X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Fcheck.c;h=ab6621ea85b4596aa192c3b53a9dc1aab73de366;hb=63e80faf9b42fbe73e25c804dd734b6179e42c24;hp=577086689f373f75c1774d9be2fd1175180af950;hpb=f367a1dc8573db0a1f6f49fcda474eb51c192241;p=ccan diff --git a/ccan/tdb2/check.c b/ccan/tdb2/check.c index 57708668..ab6621ea 100644 --- a/ccan/tdb2/check.c +++ b/ccan/tdb2/check.c @@ -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;