]> git.ozlabs.org Git - ccan/blobdiff - ccan/tdb2/check.c
tdb2: fix coalesce race #3
[ccan] / ccan / tdb2 / check.c
index c2ca95d08bcddfa98444d3d1354987c8168ce19a..f3fff5f6b8e25a99b0d34682b92788a28ea48c6a 100644 (file)
@@ -45,14 +45,15 @@ static bool check_header(struct tdb_context *tdb)
        if (hdr.hash_test != hash_test) {
                tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
                         "check: hash test %llu should be %llu\n",
-                        hdr.hash_test, hash_test);
+                        (long long)hdr.hash_test,
+                        (long long)hash_test);
                return false;
        }
 
        if (strcmp(hdr.magic_food, TDB_MAGIC_FOOD) != 0) {
                tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
                         "check: bad magic '%.*s'\n",
-                        sizeof(hdr.magic_food), hdr.magic_food);
+                        (unsigned)sizeof(hdr.magic_food), hdr.magic_food);
                return false;
        }
 
@@ -263,7 +264,7 @@ static bool check_hash(struct tdb_context *tdb,
 
        if (!check_hash_tree(tdb, offsetof(struct tdb_header, hashtable),
                             TDB_TOPLEVEL_HASH_BITS-TDB_HASH_GROUP_BITS,
-                            0, 0,  used, num_used, &num_found))
+                            0, 0, used, num_used, &num_found))
                return false;
 
        if (num_found != num_used) {
@@ -406,7 +407,8 @@ static tdb_off_t check_zone(struct tdb_context *tdb, tdb_off_t zone_off,
                p = tdb_get(tdb, off, &pad, sizeof(pad));
                if (!p)
                        return TDB_OFF_ERR;
-               if (frec_magic(&p->f) == TDB_FREE_MAGIC) {
+               if (frec_magic(&p->f) == TDB_FREE_MAGIC
+                   || frec_magic(&p->f) == TDB_COALESCING_MAGIC) {
                        if (frec_zone_bits(&p->f) != zhdr.zone_bits) {
                                tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
                                         "tdb_check: Bad free zone bits %u"
@@ -415,9 +417,6 @@ static tdb_off_t check_zone(struct tdb_context *tdb, tdb_off_t zone_off,
                                         (long long)off);
                                return TDB_OFF_ERR;
                        }
-                       /* This record is free! */
-                       if (!append(free, num_free, off))
-                               return TDB_OFF_ERR;
                        len = sizeof(p->u) + p->f.data_len;
                        if (off + len > zone_off + (1ULL << zhdr.zone_bits)) {
                                tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
@@ -426,6 +425,10 @@ static tdb_off_t check_zone(struct tdb_context *tdb, tdb_off_t zone_off,
                                         (long long)len, (long long)off);
                                return TDB_OFF_ERR;
                        }
+                       /* This record is free! */
+                       if (frec_magic(&p->f) == TDB_FREE_MAGIC
+                           && !append(free, num_free, off))
+                               return TDB_OFF_ERR;
                } else {
                        uint64_t klen, dlen, extra;