X-Git-Url: http://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Fcheck.c;h=5a16dbf42798e0d351b6fe0f5c424e00703936a9;hb=d1383862ad9a74e713dc915d351b74da4db35078;hp=f3fff5f6b8e25a99b0d34682b92788a28ea48c6a;hpb=56ea2c52a18a41a88ceaed72aef56c10de85ce93;p=ccan diff --git a/ccan/tdb2/check.c b/ccan/tdb2/check.c index f3fff5f6..5a16dbf4 100644 --- a/ccan/tdb2/check.c +++ b/ccan/tdb2/check.c @@ -368,7 +368,7 @@ static tdb_off_t check_zone(struct tdb_context *tdb, tdb_off_t zone_off, unsigned int *max_zone_bits) { struct free_zone_header zhdr; - tdb_off_t off, hdrlen; + tdb_off_t off, hdrlen, end; tdb_len_t len; if (tdb_read_convert(tdb, zone_off, &zhdr, sizeof(zhdr)) == -1) @@ -391,15 +391,18 @@ static tdb_off_t check_zone(struct tdb_context *tdb, tdb_off_t zone_off, return TDB_OFF_ERR; } - /* Zone must be within file! */ - if (tdb->methods->oob(tdb, zone_off + (1ULL << zhdr.zone_bits), false)) - return TDB_OFF_ERR; - + /* Zone header must be within file! */ hdrlen = sizeof(zhdr) + (BUCKETS_FOR_ZONE(zhdr.zone_bits) + 1) * sizeof(tdb_off_t); - for (off = zone_off + hdrlen; - off < zone_off + (1ULL << zhdr.zone_bits); - off += len) { + + if (tdb->methods->oob(tdb, zone_off + hdrlen, true)) + return TDB_OFF_ERR; + + end = zone_off + (1ULL << zhdr.zone_bits); + if (end > tdb->map_size) + end = tdb->map_size; + + for (off = zone_off + hdrlen; off < end; off += len) { union { struct tdb_used_record u; struct tdb_free_record f; @@ -476,7 +479,7 @@ static tdb_off_t check_zone(struct tdb_context *tdb, tdb_off_t zone_off, } } } - return 1ULL << zhdr.zone_bits; + return off - zone_off; } /* FIXME: call check() function. */ @@ -488,7 +491,6 @@ int tdb_check(struct tdb_context *tdb, tdb_len_t len; size_t num_free = 0, num_used = 0, num_found = 0; unsigned max_zone_bits = INITIAL_ZONE_BITS; - uint8_t tailer; if (tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false) != 0) return -1; @@ -503,7 +505,7 @@ int tdb_check(struct tdb_context *tdb, /* First we do a linear scan, checking all records. */ for (off = sizeof(struct tdb_header); - off < tdb->map_size - 1; + off < tdb->map_size; off += len) { len = check_zone(tdb, off, &used, &num_used, &free, &num_free, &max_zone_bits); @@ -511,17 +513,6 @@ int tdb_check(struct tdb_context *tdb, goto fail; } - /* Check tailer. */ - if (tdb->methods->read(tdb, tdb->map_size - 1, &tailer, 1) == -1) - goto fail; - if (tailer != max_zone_bits) { - tdb->ecode = TDB_ERR_CORRUPT; - tdb->log(tdb, TDB_DEBUG_ERROR, tdb->log_priv, - "tdb_check: Bad tailer value %u vs %u\n", tailer, - max_zone_bits); - goto fail; - } - /* FIXME: Check key uniqueness? */ if (!check_hash(tdb, used, num_used)) goto fail;