]> git.ozlabs.org Git - ccan/blobdiff - ccan/tdb2/check.c
tdb2: fix tdb_summary reports
[ccan] / ccan / tdb2 / check.c
index 577086689f373f75c1774d9be2fd1175180af950..ab6621ea85b4596aa192c3b53a9dc1aab73de366 100644 (file)
@@ -492,7 +492,7 @@ static enum TDB_ERROR check_free(struct tdb_context *tdb,
                                  (long long)off,
                                  bucket, size_to_bucket(frec_len(frec)));
        }
-       if (prev != frec_prev(frec)) {
+       if (prev && prev != frec_prev(frec)) {
                return tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
                                  "tdb_check: offset %llu bad prev"
                                  " (%llu vs %llu)",
@@ -528,11 +528,13 @@ static enum TDB_ERROR check_free_table(struct tdb_context *tdb,
        }
 
        for (i = 0; i < TDB_FREE_BUCKETS; i++) {
-               tdb_off_t off, prev = 0, *p;
+               tdb_off_t off, prev = 0, *p, first = 0;
                struct tdb_free_record f;
 
                h = bucket_off(ftable_off, i);
                for (off = tdb_read_off(tdb, h); off; off = f.next) {
+                       if (!first)
+                               first = off;
                        if (TDB_OFF_IS_ERR(off)) {
                                return off;
                        }
@@ -559,6 +561,18 @@ static enum TDB_ERROR check_free_table(struct tdb_context *tdb,
                        (*num_found)++;
                        prev = off;
                }
+
+               if (first) {
+                       /* Now we can check first back pointer. */
+                       ecode = tdb_read_convert(tdb, first, &f, sizeof(f));
+                       if (ecode != TDB_SUCCESS) {
+                               return ecode;
+                       }
+                       ecode = check_free(tdb, first, &f, prev, ftable_num, i);
+                       if (ecode != TDB_SUCCESS) {
+                               return ecode;
+                       }
+               }
        }
        return TDB_SUCCESS;
 }
@@ -759,8 +773,8 @@ static enum TDB_ERROR check_linear(struct tdb_context *tdb,
 
 enum TDB_ERROR tdb_check_(struct tdb_context *tdb,
                          enum TDB_ERROR (*check)(TDB_DATA key, TDB_DATA data,
-                                                 void *private),
-                         void *private)
+                                                 void *private_data),
+                         void *private_data)
 {
        tdb_off_t *fr = NULL, *used = NULL, ft, recovery;
        size_t num_free = 0, num_used = 0, num_found = 0, num_ftables = 0;
@@ -801,7 +815,8 @@ enum TDB_ERROR tdb_check_(struct tdb_context *tdb,
        }
 
        /* FIXME: Check key uniqueness? */
-       ecode = check_hash(tdb, used, num_used, num_ftables, check, private);
+       ecode = check_hash(tdb, used, num_used, num_ftables, check,
+                          private_data);
        if (ecode != TDB_SUCCESS)
                goto out;