tdb2: make summary command handle recovery "dead zone"
authorRusty Russell <rusty@rustcorp.com.au>
Wed, 1 Dec 2010 13:21:41 +0000 (23:51 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Wed, 1 Dec 2010 13:21:41 +0000 (23:51 +1030)
We can run summary with a recovery area, or a dead zone.

ccan/tdb2/check.c
ccan/tdb2/private.h
ccan/tdb2/summary.c

index 3f5c5bd7fd3611ead3290d69f01ef77f1f145064..54f96bb0ea8283583faf91693decd8d467970423 100644 (file)
@@ -381,7 +381,7 @@ static bool check_free_list(struct tdb_context *tdb,
 }
 
 /* Slow, but should be very rare. */
 }
 
 /* Slow, but should be very rare. */
-static size_t dead_space(struct tdb_context *tdb, tdb_off_t off)
+size_t dead_space(struct tdb_context *tdb, tdb_off_t off)
 {
        size_t len;
 
 {
        size_t len;
 
index 22014759f2b61e6534342e6496a5b2622bfc68ca..aebfa020b1db88f3aaeab574bd905bcb273a0bf6 100644 (file)
@@ -391,6 +391,9 @@ int set_header(struct tdb_context *tdb,
 unsigned int size_to_bucket(tdb_len_t data_len);
 tdb_off_t bucket_off(tdb_off_t flist_off, unsigned bucket);
 
 unsigned int size_to_bucket(tdb_len_t data_len);
 tdb_off_t bucket_off(tdb_off_t flist_off, unsigned bucket);
 
+/* Used by tdb_summary */
+size_t dead_space(struct tdb_context *tdb, tdb_off_t off);
+
 /* io.c: */
 /* Initialize tdb->methods. */
 void tdb_io_init(struct tdb_context *tdb);
 /* io.c: */
 /* Initialize tdb->methods. */
 void tdb_io_init(struct tdb_context *tdb);
index dd6fa399e7e6cc38f9419e0ea96b73ac18df420a..97052608fc866735156ab5938bf827ea8f653242 100644 (file)
@@ -53,17 +53,22 @@ static bool summarize(struct tdb_context *tdb,
                union {
                        struct tdb_used_record u;
                        struct tdb_free_record f;
                union {
                        struct tdb_used_record u;
                        struct tdb_free_record f;
+                       struct tdb_recovery_record r;
                } pad, *p;
                } pad, *p;
-               p = tdb_get(tdb, off, &pad, sizeof(pad));
+               /* We might not be able to get the whole thing. */
+               p = tdb_get(tdb, off, &pad, sizeof(p->f));
                if (!p)
                        return false;
                if (!p)
                        return false;
-               if (rec_magic(&p->u) != TDB_MAGIC) {
+               if (p->r.magic == TDB_RECOVERY_INVALID_MAGIC
+                   || p->r.magic == TDB_RECOVERY_MAGIC) {
+                       len = sizeof(p->r) + p->r.max_len;
+               } else if (rec_magic(&p->u) != TDB_MAGIC) {
                        len = p->f.data_len;
                        tally_add(free, len);
                        tally_add(buckets, size_to_bucket(len));
                        len += sizeof(p->u);
                        unc++;
                        len = p->f.data_len;
                        tally_add(free, len);
                        tally_add(buckets, size_to_bucket(len));
                        len += sizeof(p->u);
                        unc++;
-               } else {
+               } else if (frec_magic(&p->f) == TDB_FREE_MAGIC) {
                        if (unc) {
                                tally_add(uncoal, unc);
                                unc = 0;
                        if (unc) {
                                tally_add(uncoal, unc);
                                unc = 0;
@@ -91,7 +96,8 @@ static bool summarize(struct tdb_context *tdb,
                                tally_add(data, rec_data_length(&p->u));
                        }
                        tally_add(extra, rec_extra_padding(&p->u));
                                tally_add(data, rec_data_length(&p->u));
                        }
                        tally_add(extra, rec_extra_padding(&p->u));
-               }
+               } else
+                       len = dead_space(tdb, off);
        }
        if (unc)
                tally_add(uncoal, unc);
        }
        if (unc)
                tally_add(uncoal, unc);