iRework cache code - 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 5ae463d1c2cb6c77d735d53ee7e00c3a00b70090 /scm/dedup/commit/5ae463d1c2cb6c77d735d53ee7e00c3a00b70090.gph bitreich.org 70 1parent 4a9c691eb97725f224362ee65dc088f0260bc8b6 /scm/dedup/commit/4a9c691eb97725f224362ee65dc088f0260bc8b6.gph bitreich.org 70 hAuthor: sin URL:mailto:sin@2f30.org bitreich.org 70 iDate: Wed, 21 Mar 2018 13:45:58 +0000 Err bitreich.org 70 i Err bitreich.org 70 iRework cache code Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M dedup.c | 99 ++++++++++++++++++++----------- Err bitreich.org 70 i Err bitreich.org 70 i1 file changed, 64 insertions(+), 35 deletions(-) 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@@ -35,17 +35,18 @@ struct blk { Err bitreich.org 70 i unsigned char data[BLKSIZ]; Err bitreich.org 70 i } __attribute__((packed)); Err bitreich.org 70 i Err bitreich.org 70 i-struct cent { Err bitreich.org 70 i+struct cache_data { Err bitreich.org 70 i unsigned char md[SHA256_DIGEST_LENGTH]; Err bitreich.org 70 i uint64_t blkidx; Err bitreich.org 70 i-} __attribute__((packed)); Err bitreich.org 70 i+}; Err bitreich.org 70 i Err bitreich.org 70 i-struct hash_ent { Err bitreich.org 70 i- struct cent cent; Err bitreich.org 70 i- RB_ENTRY(hash_ent) e; Err bitreich.org 70 i+struct cache_ent { Err bitreich.org 70 i+ struct cache_data data; Err bitreich.org 70 i+ int dirty; Err bitreich.org 70 i+ RB_ENTRY(cache_ent) e; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i-RB_HEAD(hash_tree, hash_ent) hash_tree_head; Err bitreich.org 70 i+RB_HEAD(cache, cache_ent) cache_head; Err bitreich.org 70 i struct enthdr enthdr; Err bitreich.org 70 i int ifd; Err bitreich.org 70 i int sfd; Err bitreich.org 70 i@@ -122,33 +123,53 @@ xwrite(int fd, const void *buf, size_t nbytes) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i-hash_ent_cmp(struct hash_ent *e1, struct hash_ent *e2) Err bitreich.org 70 i+cache_ent_cmp(struct cache_ent *e1, struct cache_ent *e2) Err bitreich.org 70 i { Err bitreich.org 70 i int r; Err bitreich.org 70 i Err bitreich.org 70 i- r = memcmp(e1->cent.md, e2->cent.md, sizeof(e1->cent.md)); Err bitreich.org 70 i+ r = memcmp(e1->data.md, e2->data.md, sizeof(e1->data.md)); Err bitreich.org 70 i if (r > 0) Err bitreich.org 70 i return 1; Err bitreich.org 70 i else if (r < 0) Err bitreich.org 70 i return -1; Err bitreich.org 70 i return 0; Err bitreich.org 70 i } Err bitreich.org 70 i-RB_PROTOTYPE(hash_tree, hash_ent, e, hash_ent_cmp); Err bitreich.org 70 i-RB_GENERATE(hash_tree, hash_ent, e, hash_ent_cmp); Err bitreich.org 70 i+RB_PROTOTYPE(cache, cache_ent, e, cache_ent_cmp); Err bitreich.org 70 i+RB_GENERATE(cache, cache_ent, e, cache_ent_cmp); Err bitreich.org 70 i Err bitreich.org 70 i-struct hash_ent * Err bitreich.org 70 i-hash_ent_add(unsigned char *md, uint64_t blkidx) Err bitreich.org 70 i+struct cache_ent * Err bitreich.org 70 i+alloc_cache_ent(unsigned char *md, uint64_t blkidx) Err bitreich.org 70 i { Err bitreich.org 70 i- struct hash_ent *hash_ent; Err bitreich.org 70 i+ struct cache_ent *ent; Err bitreich.org 70 i Err bitreich.org 70 i- hash_ent = malloc(sizeof(*hash_ent)); Err bitreich.org 70 i- if (hash_ent == NULL) Err bitreich.org 70 i+ ent = calloc(1, sizeof(*ent)); Err bitreich.org 70 i+ if (ent == NULL) Err bitreich.org 70 i err(1, "malloc"); Err bitreich.org 70 i+ memcpy(&ent->data.md, md, sizeof(ent->data.md)); Err bitreich.org 70 i+ ent->data.blkidx = blkidx; Err bitreich.org 70 i+ return ent; Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+void Err bitreich.org 70 i+add_cache_ent(struct cache_ent *ent) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ RB_INSERT(cache, &cache_head, ent); Err bitreich.org 70 i+} Err bitreich.org 70 i Err bitreich.org 70 i- memcpy(&hash_ent->cent.md, md, sizeof(hash_ent->cent.md)); Err bitreich.org 70 i- hash_ent->cent.blkidx = blkidx; Err bitreich.org 70 i- RB_INSERT(hash_tree, &hash_tree_head, hash_ent); Err bitreich.org 70 i- return hash_ent; Err bitreich.org 70 i+void Err bitreich.org 70 i+flush_cache(void) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct cache_ent *ent; Err bitreich.org 70 i+ Err bitreich.org 70 i+ if (verbose) Err bitreich.org 70 i+ fprintf(stderr, "flushing cache...\n"); Err bitreich.org 70 i+ RB_FOREACH(ent, cache, &cache_head) { Err bitreich.org 70 i+ if (!ent->dirty) Err bitreich.org 70 i+ continue; Err bitreich.org 70 i+ lseek(cfd, ent->data.blkidx * sizeof(ent->data), SEEK_SET); Err bitreich.org 70 i+ xwrite(cfd, &ent->data, sizeof(ent->data)); Err bitreich.org 70 i+ ent->dirty = 0; Err bitreich.org 70 i+ } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i@@ -200,7 +221,7 @@ storefile_nblks(void) Err bitreich.org 70 i uint64_t Err bitreich.org 70 i cachefile_nblks(void) Err bitreich.org 70 i { Err bitreich.org 70 i- return lseek(cfd, 0, SEEK_END) / sizeof(struct cent); Err bitreich.org 70 i+ return lseek(cfd, 0, SEEK_END) / sizeof(struct cache_data); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i@@ -231,12 +252,12 @@ append_blk(struct blk *blk) Err bitreich.org 70 i int Err bitreich.org 70 i lookup_blk(struct blk *blk, uint64_t *blkidx) Err bitreich.org 70 i { Err bitreich.org 70 i- struct hash_ent *hash_ent, key; Err bitreich.org 70 i+ struct cache_ent *ent, key; Err bitreich.org 70 i Err bitreich.org 70 i- memcpy(key.cent.md, blk->md, sizeof(key.cent.md)); Err bitreich.org 70 i- hash_ent = RB_FIND(hash_tree, &hash_tree_head, &key); Err bitreich.org 70 i- if (hash_ent != NULL) { Err bitreich.org 70 i- *blkidx = hash_ent->cent.blkidx; Err bitreich.org 70 i+ memcpy(key.data.md, blk->md, sizeof(key.data.md)); Err bitreich.org 70 i+ ent = RB_FIND(cache, &cache_head, &key); Err bitreich.org 70 i+ if (ent != NULL) { Err bitreich.org 70 i+ *blkidx = ent->data.blkidx; Err bitreich.org 70 i return 0; Err bitreich.org 70 i } Err bitreich.org 70 i return -1; Err bitreich.org 70 i@@ -264,13 +285,15 @@ dedup(int fd) Err bitreich.org 70 i ent = grow_ent(ent, ent->nblks + 1); Err bitreich.org 70 i Err bitreich.org 70 i if (lookup_blk(&blk, &blkidx) == -1) { Err bitreich.org 70 i- struct hash_ent *hash_ent; Err bitreich.org 70 i+ struct cache_ent *cache_ent; Err bitreich.org 70 i uint64_t nblks = storefile_nblks(); Err bitreich.org 70 i Err bitreich.org 70 i+ /* Create a cache entry for this block */ Err bitreich.org 70 i+ cache_ent = alloc_cache_ent(blk.md, nblks); Err bitreich.org 70 i+ add_cache_ent(cache_ent); Err bitreich.org 70 i+ cache_ent->dirty = 1; Err bitreich.org 70 i+ Err bitreich.org 70 i ent->blks[ent->nblks++] = nblks; Err bitreich.org 70 i- hash_ent = hash_ent_add(blk.md, nblks); Err bitreich.org 70 i- lseek(cfd, 0, SEEK_END); Err bitreich.org 70 i- xwrite(cfd, &hash_ent->cent, sizeof(hash_ent->cent)); Err bitreich.org 70 i append_blk(&blk); Err bitreich.org 70 i } else { Err bitreich.org 70 i ent->blks[ent->nblks++] = blkidx; Err bitreich.org 70 i@@ -281,6 +304,7 @@ dedup(int fd) Err bitreich.org 70 i SHA256_Final(ent->md, &ctx); Err bitreich.org 70 i append_ent(ent); Err bitreich.org 70 i free(ent); Err bitreich.org 70 i+ flush_cache(); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i@@ -339,13 +363,15 @@ rebuild_cache(void) Err bitreich.org 70 i nblks = storefile_nblks(); Err bitreich.org 70 i lseek(cfd, 0, SEEK_SET); Err bitreich.org 70 i for (i = 0; i < nblks; i++) { Err bitreich.org 70 i- struct hash_ent *hash_ent; Err bitreich.org 70 i+ struct cache_ent *ent; Err bitreich.org 70 i struct blk blk; Err bitreich.org 70 i Err bitreich.org 70 i read_blk(&blk, i); Err bitreich.org 70 i- hash_ent = hash_ent_add(blk.md, i); Err bitreich.org 70 i- xwrite(cfd, &hash_ent->cent, sizeof(hash_ent->cent)); Err bitreich.org 70 i+ ent = alloc_cache_ent(blk.md, i); Err bitreich.org 70 i+ add_cache_ent(ent); Err bitreich.org 70 i+ ent->dirty = 1; Err bitreich.org 70 i } Err bitreich.org 70 i+ flush_cache(); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i@@ -359,11 +385,13 @@ init_cache(void) Err bitreich.org 70 i nblks = cachefile_nblks(); Err bitreich.org 70 i lseek(cfd, 0, SEEK_SET); Err bitreich.org 70 i for (i = 0; i < nblks; i++) { Err bitreich.org 70 i- struct cent cent; Err bitreich.org 70 i+ struct blk blk; Err bitreich.org 70 i+ struct cache_ent *ent; Err bitreich.org 70 i Err bitreich.org 70 i- if (xread(cfd, ¢, sizeof(cent)) == 0) Err bitreich.org 70 i+ ent = alloc_cache_ent(blk.md, i); Err bitreich.org 70 i+ if (xread(cfd, &ent->data, sizeof(ent->data)) == 0) Err bitreich.org 70 i errx(1, "unexpected EOF"); Err bitreich.org 70 i- hash_ent_add(cent.md, cent.blkidx); Err bitreich.org 70 i+ add_cache_ent(ent); Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -401,6 +429,7 @@ term(void) Err bitreich.org 70 i fsync(ifd); Err bitreich.org 70 i fsync(sfd); Err bitreich.org 70 i fsync(cfd); Err bitreich.org 70 i+ Err bitreich.org 70 i close(ifd); Err bitreich.org 70 i close(sfd); Err bitreich.org 70 i close(cfd); Err bitreich.org 70 .