URI: 
       Check cache for consistency - dedup - deduplicating backup program
  HTML git clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/
   DIR Log
   DIR Files
   DIR Refs
   DIR Tags
   DIR README
   DIR LICENSE
       ---
   DIR commit e2a7f03a6b43cf093fc814dd8610e2b73c1345a3
   DIR parent 6d9bfc25ce2ba1ddc768c68522d05195d783472b
  HTML Author: sin <sin@2f30.org>
       Date:   Mon,  4 Mar 2019 14:45:41 +0000
       
       Check cache for consistency
       
       Diffstat:
         M dedup.c                             |      67 ++++++++++++++++++++++++++++---
       
       1 file changed, 61 insertions(+), 6 deletions(-)
       ---
   DIR 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;
                }