Browse Source

tdb2: add TDB_COALESCING_MAGIC to solve coalescing race.

A new special record marker to indicate coalescing is in progress.
Rusty Russell 15 years ago
parent
commit
56ea2c52a1
3 changed files with 8 additions and 5 deletions
  1. 6 4
      ccan/tdb2/check.c
  2. 1 0
      ccan/tdb2/private.h
  3. 1 1
      ccan/tdb2/summary.c

+ 6 - 4
ccan/tdb2/check.c

@@ -407,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));
 		p = tdb_get(tdb, off, &pad, sizeof(pad));
 		if (!p)
 		if (!p)
 			return TDB_OFF_ERR;
 			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) {
 			if (frec_zone_bits(&p->f) != zhdr.zone_bits) {
 				tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
 				tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
 					 "tdb_check: Bad free zone bits %u"
 					 "tdb_check: Bad free zone bits %u"
@@ -416,9 +417,6 @@ static tdb_off_t check_zone(struct tdb_context *tdb, tdb_off_t zone_off,
 					 (long long)off);
 					 (long long)off);
 				return TDB_OFF_ERR;
 				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;
 			len = sizeof(p->u) + p->f.data_len;
 			if (off + len > zone_off + (1ULL << zhdr.zone_bits)) {
 			if (off + len > zone_off + (1ULL << zhdr.zone_bits)) {
 				tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
 				tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv,
@@ -427,6 +425,10 @@ static tdb_off_t check_zone(struct tdb_context *tdb, tdb_off_t zone_off,
 					 (long long)len, (long long)off);
 					 (long long)len, (long long)off);
 				return TDB_OFF_ERR;
 				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 {
 		} else {
 			uint64_t klen, dlen, extra;
 			uint64_t klen, dlen, extra;
 
 

+ 1 - 0
ccan/tdb2/private.h

@@ -65,6 +65,7 @@ typedef uint64_t tdb_off_t;
 #define TDB_VERSION ((uint64_t)(0x26011967 + 7))
 #define TDB_VERSION ((uint64_t)(0x26011967 + 7))
 #define TDB_MAGIC ((uint64_t)0x1999)
 #define TDB_MAGIC ((uint64_t)0x1999)
 #define TDB_FREE_MAGIC ((~(uint64_t)TDB_MAGIC) << 6)
 #define TDB_FREE_MAGIC ((~(uint64_t)TDB_MAGIC) << 6)
+#define TDB_COALESCING_MAGIC (0xBAD1DEA2FEEDULL << 6)
 #define TDB_HASH_MAGIC (0xA1ABE11A01092008ULL)
 #define TDB_HASH_MAGIC (0xA1ABE11A01092008ULL)
 #define TDB_RECOVERY_MAGIC (0xf53bc0e7U)
 #define TDB_RECOVERY_MAGIC (0xf53bc0e7U)
 #define TDB_RECOVERY_INVALID_MAGIC (0x0)
 #define TDB_RECOVERY_INVALID_MAGIC (0x0)

+ 1 - 1
ccan/tdb2/summary.c

@@ -89,7 +89,7 @@ static tdb_len_t summarize_zone(struct tdb_context *tdb, tdb_off_t zone_off,
 		p = tdb_get(tdb, off, &pad, sizeof(pad));
 		p = tdb_get(tdb, off, &pad, sizeof(pad));
 		if (!p)
 		if (!p)
 			return TDB_OFF_ERR;
 			return TDB_OFF_ERR;
-		if (frec_magic(&p->f) == TDB_FREE_MAGIC) {
+		if (rec_magic(&p->u) != TDB_MAGIC) {
 			len = p->f.data_len;
 			len = p->f.data_len;
 			tally_add(free, len);
 			tally_add(free, len);
 			bucketlen[size_to_bucket(frec_zone_bits(&p->f), len)]++;
 			bucketlen[size_to_bucket(frec_zone_bits(&p->f), len)]++;