iAdd primitive chunk compression support - dedup - deduplicating backup program Err bitreich.org 70 hgit clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ URL:git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ bitreich.org 70 1Log /scm/dedup/log.gph bitreich.org 70 1Files /scm/dedup/files.gph bitreich.org 70 1Refs /scm/dedup/refs.gph bitreich.org 70 1Tags /scm/dedup/tag bitreich.org 70 1README /scm/dedup/file/README.gph bitreich.org 70 1LICENSE /scm/dedup/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 3ce9db0f144f9d5a39a9180ed343d9498d064778 /scm/dedup/commit/3ce9db0f144f9d5a39a9180ed343d9498d064778.gph bitreich.org 70 1parent 4ff76106cb1e2c6f99dfd163744224fc57d5fa65 /scm/dedup/commit/4ff76106cb1e2c6f99dfd163744224fc57d5fa65.gph bitreich.org 70 hAuthor: sin URL:mailto:sin@2f30.org bitreich.org 70 iDate: Sun, 17 Feb 2019 21:28:00 +0000 Err bitreich.org 70 i Err bitreich.org 70 iAdd primitive chunk compression support Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 2 +- Err bitreich.org 70 i M dedup.c | 103 +++++++++++++++++++------------ Err bitreich.org 70 i Err bitreich.org 70 i2 files changed, 66 insertions(+), 39 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/dedup/file/Makefile.gph bitreich.org 70 i@@ -8,7 +8,7 @@ DISTFILES = $(SRC) LICENSE Makefile README arg.h dedup.1 tree.h Err bitreich.org 70 i Err bitreich.org 70 i CFLAGS = -g -Wall Err bitreich.org 70 i CPPFLAGS = -I/usr/local/include -D_FILE_OFFSET_BITS=64 Err bitreich.org 70 i-LDLIBS = -lcrypto Err bitreich.org 70 i+LDLIBS = -lcrypto -llz4 Err bitreich.org 70 i Err bitreich.org 70 i all: $(BIN) Err bitreich.org 70 i Err bitreich.org 70 1diff --git a/dedup.c b/dedup.c /scm/dedup/file/dedup.c.gph bitreich.org 70 i@@ -7,6 +7,7 @@ Err bitreich.org 70 i #include Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i+#include Err bitreich.org 70 i #include Err bitreich.org 70 i Err bitreich.org 70 i #include "arg.h" Err bitreich.org 70 i@@ -16,11 +17,11 @@ Err bitreich.org 70 i #define STOREF ".store" Err bitreich.org 70 i #define CACHEF ".cache" Err bitreich.org 70 i Err bitreich.org 70 i-#define BLKSIZ (1024 * 512) Err bitreich.org 70 i-#define WINSIZ 1024 Err bitreich.org 70 i+#define BLKSIZE (1 * 1024 * 1024) Err bitreich.org 70 i+#define WINSIZE 4095 Err bitreich.org 70 i #define HASHMSK ((1ul << 21) - 1) Err bitreich.org 70 i-#define MSGSIZ 256 Err bitreich.org 70 i-#define MDSIZ SHA256_DIGEST_LENGTH Err bitreich.org 70 i+#define MSGSIZE 256 Err bitreich.org 70 i+#define MDSIZE SHA256_DIGEST_LENGTH Err bitreich.org 70 i Err bitreich.org 70 i #define ROTL(x, y) (((x) << (y)) | ((x) >> (32 - (y)))) Err bitreich.org 70 i Err bitreich.org 70 i@@ -38,7 +39,7 @@ struct enthdr { Err bitreich.org 70 i Err bitreich.org 70 i /* block descriptor */ Err bitreich.org 70 i struct bdescr { Err bitreich.org 70 i- uint8_t md[MDSIZ]; Err bitreich.org 70 i+ uint8_t md[MDSIZE]; Err bitreich.org 70 i uint64_t offset; Err bitreich.org 70 i uint64_t size; Err bitreich.org 70 i }; Err bitreich.org 70 i@@ -46,8 +47,8 @@ struct bdescr { Err bitreich.org 70 i /* index file entry */ Err bitreich.org 70 i struct ent { Err bitreich.org 70 i uint64_t size; Err bitreich.org 70 i- uint8_t msg[MSGSIZ]; Err bitreich.org 70 i- uint8_t md[MDSIZ]; /* hash of file */ Err bitreich.org 70 i+ uint8_t msg[MSGSIZE]; Err bitreich.org 70 i+ uint8_t md[MDSIZE]; /* hash of file */ Err bitreich.org 70 i uint64_t nblks; Err bitreich.org 70 i struct bdescr bdescr[]; Err bitreich.org 70 i }; Err bitreich.org 70 i@@ -140,29 +141,47 @@ chunk_blk(uint8_t *buf, size_t size) Err bitreich.org 70 i size_t i; Err bitreich.org 70 i uint32_t fp; Err bitreich.org 70 i Err bitreich.org 70 i- /* buzhash should be at least WINSIZ */ Err bitreich.org 70 i- if (size < WINSIZ) Err bitreich.org 70 i+ /* buzhash should be at least WINSIZE */ Err bitreich.org 70 i+ if (size < WINSIZE) Err bitreich.org 70 i return size; Err bitreich.org 70 i Err bitreich.org 70 i /* Err bitreich.org 70 i * To achieve better deduplication, we chunk blocks based on a Err bitreich.org 70 i * recurring pattern occuring on the data stream. A fixed window Err bitreich.org 70 i- * of WINSIZ bytes is slid over the data, and a rolling hash is Err bitreich.org 70 i+ * of WINSIZE bytes is slid over the data, and a rolling hash is Err bitreich.org 70 i * computed for this window. Err bitreich.org 70 i * When the rolling hash matches a given pattern (see HASHMSK), Err bitreich.org 70 i * the block is chunked at the end of that window, thus making Err bitreich.org 70 i- * WINSIZ the smallest possible block size. Err bitreich.org 70 i+ * WINSIZE the smallest possible block size. Err bitreich.org 70 i */ Err bitreich.org 70 i- fp = buzh_init(buf, WINSIZ); Err bitreich.org 70 i- for (i = 0; i < size - WINSIZ; i++) { Err bitreich.org 70 i+ fp = buzh_init(buf, WINSIZE); Err bitreich.org 70 i+ for (i = 0; i < size - WINSIZE; i++) { Err bitreich.org 70 i if (i > 0) Err bitreich.org 70 i- fp = buzh_update(fp, buf[i - 1], buf[WINSIZ + i - 1], WINSIZ); Err bitreich.org 70 i+ fp = buzh_update(fp, buf[i - 1], buf[WINSIZE + i - 1], WINSIZE); Err bitreich.org 70 i if ((fp & HASHMSK) == 0) Err bitreich.org 70 i- return i + WINSIZ; Err bitreich.org 70 i+ return i + WINSIZE; Err bitreich.org 70 i } Err bitreich.org 70 i return size; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i+size_t Err bitreich.org 70 i+comp_size(size_t size) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return LZ4_compressBound(size); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+size_t Err bitreich.org 70 i+comp(uint8_t *in, uint8_t *out, size_t insize, size_t outsize) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return LZ4_compress_default((char *)in, (char *)out, insize, outsize); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+size_t Err bitreich.org 70 i+decomp(uint8_t *in, uint8_t *out, size_t insize, size_t outsize) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return LZ4_decompress_safe((char *)in, (char *)out, insize, outsize); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i void Err bitreich.org 70 i print_md(const uint8_t *md, size_t size) Err bitreich.org 70 i { Err bitreich.org 70 i@@ -375,33 +394,35 @@ lookup_blk(uint8_t *md) Err bitreich.org 70 i void Err bitreich.org 70 i dedup(int fd, char *msg) Err bitreich.org 70 i { Err bitreich.org 70 i- uint8_t *buf; Err bitreich.org 70 i+ uint8_t *buf, *cbuf; Err bitreich.org 70 i struct ent *ent; Err bitreich.org 70 i SHA256_CTX ctx; Err bitreich.org 70 i ssize_t n; Err bitreich.org 70 i Err bitreich.org 70 i- buf = alloc_buf(BLKSIZ); Err bitreich.org 70 i+ buf = alloc_buf(BLKSIZE); Err bitreich.org 70 i+ cbuf = alloc_buf(comp_size(BLKSIZE)); Err bitreich.org 70 i ent = alloc_ent(); Err bitreich.org 70 i Err bitreich.org 70 i SHA256_Init(&ctx); Err bitreich.org 70 i- while ((n = xread(fd, buf, BLKSIZ)) > 0) { Err bitreich.org 70 i+ while ((n = xread(fd, buf, BLKSIZE)) > 0) { Err bitreich.org 70 i uint8_t *bp = buf; Err bitreich.org 70 i Err bitreich.org 70 i while (n > 0) { Err bitreich.org 70 i- uint8_t md[MDSIZ]; Err bitreich.org 70 i+ uint8_t md[MDSIZE]; Err bitreich.org 70 i struct bdescr bdescr; Err bitreich.org 70 i- size_t blksiz; Err bitreich.org 70 i+ size_t blksize, csize; Err bitreich.org 70 i Err bitreich.org 70 i- blksiz = chunk_blk(bp, n); Err bitreich.org 70 i+ blksize = chunk_blk(bp, n); Err bitreich.org 70 i+ csize = comp(bp, cbuf, blksize, comp_size(BLKSIZE)); Err bitreich.org 70 i Err bitreich.org 70 i memcpy(bdescr.md, md, sizeof(bdescr)); Err bitreich.org 70 i bdescr.offset = enthdr.store_size; Err bitreich.org 70 i- bdescr.size = blksiz; Err bitreich.org 70 i+ bdescr.size = csize; Err bitreich.org 70 i Err bitreich.org 70 i- hash_blk(bp, bdescr.size, bdescr.md); Err bitreich.org 70 i+ hash_blk(cbuf, bdescr.size, bdescr.md); Err bitreich.org 70 i Err bitreich.org 70 i /* Calculate file hash one block at a time */ Err bitreich.org 70 i- SHA256_Update(&ctx, bp, bdescr.size); Err bitreich.org 70 i+ SHA256_Update(&ctx, cbuf, bdescr.size); Err bitreich.org 70 i Err bitreich.org 70 i ent = grow_ent(ent, ent->nblks + 1); Err bitreich.org 70 i Err bitreich.org 70 i@@ -412,7 +433,7 @@ dedup(int fd, char *msg) Err bitreich.org 70 i ent->bdescr[ent->nblks++] = bdescr; Err bitreich.org 70 i Err bitreich.org 70 i /* Store block */ Err bitreich.org 70 i- append_blk(bp, &bdescr); Err bitreich.org 70 i+ append_blk(cbuf, &bdescr); Err bitreich.org 70 i Err bitreich.org 70 i /* Create a cache entry for this block */ Err bitreich.org 70 i cent = alloc_cent(); Err bitreich.org 70 i@@ -422,8 +443,8 @@ dedup(int fd, char *msg) Err bitreich.org 70 i ent->bdescr[ent->nblks++] = bdescr; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- bp += blksiz; Err bitreich.org 70 i- n -= blksiz; Err bitreich.org 70 i+ bp += blksize; Err bitreich.org 70 i+ n -= blksize; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -445,24 +466,30 @@ dedup(int fd, char *msg) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i free(ent); Err bitreich.org 70 i+ free(cbuf); Err bitreich.org 70 i free(buf); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i extract(struct ent *ent, void *arg) Err bitreich.org 70 i { Err bitreich.org 70 i- uint8_t *buf; Err bitreich.org 70 i+ uint8_t *buf, *cbuf; Err bitreich.org 70 i struct extract_args *args = arg; Err bitreich.org 70 i uint64_t i; Err bitreich.org 70 i Err bitreich.org 70 i if (memcmp(ent->md, args->md, sizeof(ent->md)) != 0) Err bitreich.org 70 i return WALK_CONTINUE; Err bitreich.org 70 i Err bitreich.org 70 i- buf = alloc_buf(BLKSIZ); Err bitreich.org 70 i+ buf = alloc_buf(BLKSIZE); Err bitreich.org 70 i+ cbuf = alloc_buf(comp_size(BLKSIZE)); Err bitreich.org 70 i for (i = 0; i < ent->nblks; i++) { Err bitreich.org 70 i- read_blk(buf, &ent->bdescr[i]); Err bitreich.org 70 i- xwrite(args->fd, buf, ent->bdescr[i].size); Err bitreich.org 70 i+ size_t blksize; Err bitreich.org 70 i+ Err bitreich.org 70 i+ read_blk(cbuf, &ent->bdescr[i]); Err bitreich.org 70 i+ blksize = decomp(cbuf, buf, ent->bdescr[i].size, BLKSIZE); Err bitreich.org 70 i+ xwrite(args->fd, buf, blksize); Err bitreich.org 70 i } Err bitreich.org 70 i+ free(cbuf); Err bitreich.org 70 i free(buf); Err bitreich.org 70 i return WALK_STOP; Err bitreich.org 70 i } Err bitreich.org 70 i@@ -470,12 +497,12 @@ extract(struct ent *ent, void *arg) Err bitreich.org 70 i int Err bitreich.org 70 i check(struct ent *ent, void *arg) Err bitreich.org 70 i { Err bitreich.org 70 i- uint8_t md[MDSIZ]; Err bitreich.org 70 i+ uint8_t md[MDSIZE]; Err bitreich.org 70 i uint8_t *buf; Err bitreich.org 70 i SHA256_CTX ctx; Err bitreich.org 70 i uint64_t i; Err bitreich.org 70 i Err bitreich.org 70 i- buf = alloc_buf(BLKSIZ); Err bitreich.org 70 i+ buf = alloc_buf(BLKSIZE); Err bitreich.org 70 i /* Err bitreich.org 70 i * Calculate hash for each block and compare Err bitreich.org 70 i * with index entry block descriptor Err bitreich.org 70 i@@ -521,12 +548,12 @@ list(struct ent *ent, void *arg) Err bitreich.org 70 i int Err bitreich.org 70 i rebuild_cache(struct ent *ent, void *arg) Err bitreich.org 70 i { Err bitreich.org 70 i- uint8_t md[MDSIZ]; Err bitreich.org 70 i+ uint8_t md[MDSIZE]; Err bitreich.org 70 i uint8_t *buf; Err bitreich.org 70 i SHA256_CTX ctx; Err bitreich.org 70 i uint64_t i; Err bitreich.org 70 i Err bitreich.org 70 i- buf = alloc_buf(BLKSIZ); Err bitreich.org 70 i+ buf = alloc_buf(BLKSIZE); Err bitreich.org 70 i for (i = 0; i < ent->nblks; i++) { Err bitreich.org 70 i struct cent *cent; Err bitreich.org 70 i Err bitreich.org 70 i@@ -575,7 +602,7 @@ init_cache(void) Err bitreich.org 70 i uint64_t nents, i; Err bitreich.org 70 i uint64_t min, max, avg; Err bitreich.org 70 i Err bitreich.org 70 i- min = BLKSIZ; Err bitreich.org 70 i+ min = BLKSIZE; Err bitreich.org 70 i max = 0; Err bitreich.org 70 i avg = 0; Err bitreich.org 70 i Err bitreich.org 70 i@@ -598,7 +625,7 @@ init_cache(void) Err bitreich.org 70 i avg /= nents; Err bitreich.org 70 i Err bitreich.org 70 i if (verbose) { Err bitreich.org 70 i- fprintf(stderr, "min/avg/max blksize: %llu/%llu/%llu\n", Err bitreich.org 70 i+ fprintf(stderr, "min/avg/max block size: %llu/%llu/%llu\n", Err bitreich.org 70 i (unsigned long long)min, Err bitreich.org 70 i (unsigned long long)avg, Err bitreich.org 70 i (unsigned long long)max); Err bitreich.org 70 i@@ -661,7 +688,7 @@ usage(void) Err bitreich.org 70 i int Err bitreich.org 70 i main(int argc, char *argv[]) Err bitreich.org 70 i { Err bitreich.org 70 i- uint8_t md[MDSIZ]; Err bitreich.org 70 i+ uint8_t md[MDSIZE]; Err bitreich.org 70 i char *id = NULL, *root = NULL, *msg = NULL; Err bitreich.org 70 i int fd = -1, lflag = 0, cflag = 0; Err bitreich.org 70 i Err bitreich.org 70 .