commit 5f1e1e970f10eb34b5392079a0b98827eb6a8af5
parent e2a7f03a6b43cf093fc814dd8610e2b73c1345a3
Author: sin <sin@2f30.org>
Date: Mon, 4 Mar 2019 14:56:10 +0000
Rebuild cache if it is larger than expected
We don't want bogus cache entries that could in theory match new
blocks.
Diffstat:
M | dedup.c | | | 27 | +++++++++++++++++++-------- |
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/dedup.c b/dedup.c
@@ -411,7 +411,7 @@ check_cache(struct snapshot *snap, void *arg)
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)
+ if (verbose > 0)
fprintf(stderr, "Cache is corrupted\n");
args->ret = -1;
return WALK_STOP;
@@ -497,6 +497,16 @@ match_ver(uint64_t v)
VER_MAJ, VER_MIN, maj, min);
}
+static uint64_t
+cache_nr_entries(void)
+{
+ struct stat sb;
+
+ if (fstat(cfd, &sb) < 0)
+ err(1, "fstat");
+ return sb.st_size / CACHE_ENTRY_SIZE;
+}
+
static int
flush_cache(struct cache_entry *cache_entry)
{
@@ -507,16 +517,12 @@ flush_cache(struct cache_entry *cache_entry)
static void
load_cache(void)
{
- struct stat sb;
uint64_t nr_entries;
uint64_t i;
xlseek(cfd, 0, SEEK_SET);
- if (fstat(cfd, &sb) < 0)
- err(1, "fstat");
-
- nr_entries = sb.st_size / CACHE_ENTRY_SIZE;
+ nr_entries = cache_nr_entries();
if (nr_entries == 0) {
xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
if (verbose > 0)
@@ -741,9 +747,14 @@ main(int argc, char *argv[])
xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
walk_snap(check_snap, NULL);
- xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
args.ret = -1;
- walk_snap(check_cache, &args);
+ if (cache_nr_entries() == snap_hdr.st.nr_blks) {
+ xlseek(ifd, SNAP_HDR_SIZE, SEEK_SET);
+ walk_snap(check_cache, &args);
+ } else {
+ if (verbose > 0)
+ fprintf(stderr, "Cache is corrupted\n");
+ }
if (args.ret != 0) {
free_cache(cache);
cache = alloc_cache();