dedup

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

commit 12641354d5c6d5d5a06b889df69ec71cbbeca176
parent cc98da662594f5538942073561082e92be19d9fb
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:
Mdedup.c | 97+++++++++++++++++++++++++++++++++++++------------------------------------------
1 file changed, 46 insertions(+), 51 deletions(-)

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;