dedup

data deduplication program
git clone git://git.2f30.org/dedup.git
Log | Files | Refs | README | LICENSE

commit e2a7f03a6b43cf093fc814dd8610e2b73c1345a3
parent 6d9bfc25ce2ba1ddc768c68522d05195d783472b
Author: sin <sin@2f30.org>
Date:   Mon,  4 Mar 2019 14:45:41 +0000

Check cache for consistency

Diffstat:
Mdedup.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 61 insertions(+), 6 deletions(-)

diff --git a/dedup.c b/dedup.c @@ -25,6 +25,10 @@ enum { WALK_STOP }; +struct check_cache_args { + int ret; +}; + struct extract_args { uint8_t *md; int fd; @@ -346,8 +350,12 @@ extract(struct snapshot *snap, void *arg) return WALK_STOP; } +/* + * For each snapshot, hash every block and check if the hash + * matches the one in the corresponding block descriptor. + */ static int -check(struct snapshot *snap, void *arg) +check_snap(struct snapshot *snap, void *arg) { uint8_t md[MDSIZE]; uint8_t *buf; @@ -355,10 +363,6 @@ check(struct snapshot *snap, void *arg) uint64_t i; buf = alloc_buf(compr_size(BLKSIZE_MAX)); - /* - * Calculate hash for each block and compare - * against snapshot entry block descriptor - */ for (i = 0; i < snap->nr_blk_descs; i++) { struct blk_desc *blk_desc; @@ -388,6 +392,35 @@ check(struct snapshot *snap, void *arg) return WALK_CONTINUE; } +/* + * For each block descriptor within each snapshot, do a lookup + * of the block descriptor hash in the cache. If the lookup fails + * the cache is corrupted. The caller will rebuild the cache in + * that case. + */ +static int +check_cache(struct snapshot *snap, void *arg) +{ + struct check_cache_args *args = arg; + uint64_t i; + + for (i = 0; i < snap->nr_blk_descs; i++) { + struct blk_desc *blk_desc; + struct cache_entry cache_entry; + + blk_desc = &snap->blk_desc[i]; + memcpy(&cache_entry.md, blk_desc->md, sizeof(cache_entry.md)); + if (lookup_cache_entry(cache, &cache_entry) < 0) { + if (verbose) + fprintf(stderr, "Cache is corrupted\n"); + args->ret = -1; + return WALK_STOP; + } + } + args->ret = 0; + return WALK_CONTINUE; +} + static int list(struct snapshot *snap, void *arg) { @@ -703,8 +736,30 @@ main(int argc, char *argv[]) } if (cflag) { + struct check_cache_args args; + + xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET); + walk_snap(check_snap, NULL); + xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET); - walk_snap(check, NULL); + args.ret = -1; + walk_snap(check_cache, &args); + if (args.ret != 0) { + free_cache(cache); + cache = alloc_cache(); + + if (ftruncate(cfd, 0) < 0) + err(1, "ftruncate"); + + if (verbose > 0) + fprintf(stderr, "Rebuilding cache..."); + xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET); + xlseek(cfd, 0, SEEK_SET); + walk_snap(rebuild_cache, NULL); + if (verbose > 0) + fprintf(stderr, "done\n"); + } + term(); return 0; }