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:
M | dedup.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;