From: Rusty Russell Date: Mon, 15 Nov 2010 07:31:48 +0000 (+1030) Subject: tdb2: extra debugging checks X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=b371060fb7e2aa6a5990413cabe5fcc5ba5cc84c tdb2: extra debugging checks --- diff --git a/ccan/tdb2/free.c b/ccan/tdb2/free.c index e6d871a5..3ca4e2c3 100644 --- a/ccan/tdb2/free.c +++ b/ccan/tdb2/free.c @@ -132,7 +132,8 @@ static tdb_off_t find_free_head(struct tdb_context *tdb, tdb_off_t bucket) /* Remove from free bucket. */ static int remove_from_list(struct tdb_context *tdb, - tdb_off_t b_off, struct tdb_free_record *r) + tdb_off_t b_off, tdb_off_t r_off, + struct tdb_free_record *r) { tdb_off_t off; @@ -142,6 +143,16 @@ static int remove_from_list(struct tdb_context *tdb, } else { off = r->prev + offsetof(struct tdb_free_record, next); } + +#ifdef DEBUG + if (tdb_read_off(tdb, off) != r_off) { + tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, + "remove_from_list: %llu bad prev in list %llu\n", + (long long)r_off, (long long)b_off); + return -1; + } +#endif + /* r->prev->next = r->next */ if (tdb_write_off(tdb, off, r->next)) { return -1; @@ -150,6 +161,16 @@ static int remove_from_list(struct tdb_context *tdb, if (r->next != 0) { off = r->next + offsetof(struct tdb_free_record, prev); /* r->next->prev = r->prev */ + +#ifdef DEBUG + if (tdb_read_off(tdb, off) != r_off) { + tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, + "remove_from_list: %llu bad list %llu\n", + (long long)r_off, (long long)b_off); + return -1; + } +#endif + if (tdb_write_off(tdb, off, r->prev)) { return -1; } @@ -170,6 +191,17 @@ static int enqueue_in_free(struct tdb_context *tdb, return -1; if (new->next) { +#ifdef DEBUG + if (tdb_read_off(tdb, + new->next + + offsetof(struct tdb_free_record, prev)) + != 0) { + tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, + "enqueue_in_free: %llu bad head prev %llu\n", + (long long)new->next, (long long)b_off); + return -1; + } +#endif /* next->prev = new. */ if (tdb_write_off(tdb, new->next + offsetof(struct tdb_free_record, prev), @@ -272,7 +304,7 @@ static int coalesce(struct tdb_context *tdb, break; } - if (remove_from_list(tdb, nb_off, r) == -1) { + if (remove_from_list(tdb, nb_off, end, r) == -1) { tdb_unlock_free_bucket(tdb, nb_off); goto err; } @@ -298,7 +330,7 @@ static int coalesce(struct tdb_context *tdb, goto err; } - if (remove_from_list(tdb, b_off, r) == -1) + if (remove_from_list(tdb, b_off, off, r) == -1) goto err; /* We have to drop this to avoid deadlocks. */ @@ -388,7 +420,7 @@ again: if (best_off) { use_best: /* We're happy with this size: take it. */ - if (remove_from_list(tdb, b_off, &best) != 0) + if (remove_from_list(tdb, b_off, best_off, &best) != 0) goto unlock_err; tdb_unlock_free_bucket(tdb, b_off); diff --git a/ccan/tdb2/hash.c b/ccan/tdb2/hash.c index d3a195a7..dec7aae5 100644 --- a/ccan/tdb2/hash.c +++ b/ccan/tdb2/hash.c @@ -560,6 +560,14 @@ int next_in_hash(struct tdb_context *tdb, int ltype, ltype); return -1; } + if (rec_magic(&rec) != TDB_MAGIC) { + tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, + "next_in_hash:" + " corrupt record at %llu\n", + (long long)off); + return -1; + } + kbuf->dsize = rec_key_length(&rec); /* They want data as well? */