URI: 
       Always check and rebuild the cache - 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 12641354d5c6d5d5a06b889df69ec71cbbeca176
   DIR parent cc98da662594f5538942073561082e92be19d9fb
  HTML Author: sin <sin@2f30.org>
       Date:   Mon,  4 Mar 2019 16:12:01 +0000
       
       Always check and rebuild the cache
       
       It might be dangerous to proceed with a corrupt cache.
       
       Diffstat:
         M dedup.c                             |      97 +++++++++++++++----------------
       
       1 file changed, 46 insertions(+), 51 deletions(-)
       ---
   DIR diff --git a/dedup.c b/dedup.c
       @@ -403,7 +403,7 @@ check_snap(struct snapshot *snap, void *arg)
         * that case.
         */
        static int
       -check_cache(struct snapshot *snap, void *arg)
       +check_cache_entry(struct snapshot *snap, void *arg)
        {
                int *ret = arg;
                uint64_t i;
       @@ -429,18 +429,7 @@ check_cache(struct snapshot *snap, void *arg)
        }
        
        static int
       -list(struct snapshot *snap, void *arg)
       -{
       -        print_md(stdout, snap->md, sizeof(snap->md));
       -        if (snap->msg[0] != '\0')
       -                printf("\t%s\n", snap->msg);
       -        else
       -                putchar('\n');
       -        return WALK_CONTINUE;
       -}
       -
       -static int
       -rebuild_cache(struct snapshot *snap, void *arg)
       +reload_cache(struct snapshot *snap, void *arg)
        {
                uint8_t md[MDSIZE];
                uint8_t *buf;
       @@ -469,6 +458,17 @@ rebuild_cache(struct snapshot *snap, void *arg)
                return WALK_CONTINUE;
        }
        
       +static int
       +list(struct snapshot *snap, void *arg)
       +{
       +        print_md(stdout, snap->md, sizeof(snap->md));
       +        if (snap->msg[0] != '\0')
       +                printf("\t%s\n", snap->msg);
       +        else
       +                putchar('\n');
       +        return WALK_CONTINUE;
       +}
       +
        /* Walk through all snapshots and call fn() on each one */
        static void
        walk_snap(int (*fn)(struct snapshot *, void *), void *arg)
       @@ -514,11 +514,30 @@ cache_nr_entries(void)
                return sb.st_size / CACHE_ENTRY_SIZE;
        }
        
       -static int
       -flush_cache(struct cache_entry *cache_entry)
       +static void
       +check_cache(void)
        {
       -        write_cache_entry(cfd, cache_entry);
       -        return 0;
       +        int ret;
       +
       +        if (cache_nr_entries() != snap_hdr.st.nr_blks) {
       +                ret = -1;
       +        } else {
       +                xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
       +                ret = 0;
       +                walk_snap(check_cache_entry, &ret);
       +        }
       +
       +        if (ret != 0) {
       +                free_cache(cache);
       +                cache = alloc_cache();
       +
       +                if (ftruncate(cfd, 0) < 0)
       +                        err(1, "ftruncate");
       +
       +                xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
       +                xlseek(cfd, 0, SEEK_SET);
       +                walk_snap(reload_cache, NULL);
       +        }
        }
        
        static void
       @@ -527,19 +546,10 @@ load_cache(void)
                uint64_t nr_entries;
                uint64_t i;
        
       -        xlseek(cfd, 0, SEEK_SET);
       +        check_cache();
        
       +        xlseek(cfd, 0, SEEK_SET);
                nr_entries = cache_nr_entries();
       -        if (nr_entries == 0) {
       -                xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
       -                if (verbose > 0)
       -                        fprintf(stderr, "Rebuilding cache...");
       -                walk_snap(rebuild_cache, NULL);
       -                if (verbose > 0)
       -                        fprintf(stderr, "done\n");
       -                return;
       -        }
       -
                for (i = 0; i < nr_entries; i++) {
                        struct cache_entry cache_entry;
        
       @@ -548,6 +558,13 @@ load_cache(void)
                }
        }
        
       +static int
       +flush_cache(struct cache_entry *cache_entry)
       +{
       +        write_cache_entry(cfd, cache_entry);
       +        return 0;
       +}
       +
        static void
        save_cache(void)
        {
       @@ -757,29 +774,7 @@ main(int argc, char *argv[])
                        if (ret != 0)
                                errx(1, "%s or %s is corrupted", SNAPSF, STOREF);
        
       -                if (cache_nr_entries() != snap_hdr.st.nr_blks) {
       -                        ret = -1;
       -                } else {
       -                        xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
       -                        ret = 0;
       -                        walk_snap(check_cache, &ret);
       -                }
       -
       -                if (ret != 0) {
       -                        free_cache(cache);
       -                        cache = alloc_cache();
       -
       -                        if (ftruncate(cfd, 0) < 0)
       -                                err(1, "ftruncate");
       -
       -                        if (verbose > 0)
       -                                fprintf(stderr, "Cache is corrupted, rebuilding...");
       -                        xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
       -                        xlseek(cfd, 0, SEEK_SET);
       -                        walk_snap(rebuild_cache, NULL);
       -                        if (verbose > 0)
       -                                fprintf(stderr, "done\n");
       -                }
       +                check_cache();
        
                        term();
                        return 0;