+/* FIXME: call check() function. */
+int tdb_check(struct tdb_context *tdb,
+ int (*check)(TDB_DATA key, TDB_DATA data, void *private_data),
+ void *private_data)
+{
+ tdb_off_t *free = NULL, *used = NULL, off;
+ tdb_len_t len;
+ size_t num_free = 0, num_used = 0, num_found = 0;
+ bool hash_found = false;
+ unsigned max_zone_bits = INITIAL_ZONE_BITS;
+ uint8_t tailer;
+
+ /* FIXME: need more locking? against expansion? */
+ /* This always ensures the header is uptodate. */
+ if (tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, false) != 0)
+ return -1;
+
+ if (!check_header(tdb))
+ goto fail;
+
+ /* First we do a linear scan, checking all records. */
+ for (off = sizeof(struct tdb_header);
+ off < tdb->map_size - 1;
+ off += len) {
+ len = check_zone(tdb, off, &used, &num_used, &free, &num_free,
+ &hash_found, &max_zone_bits);
+ if (len == TDB_OFF_ERR)
+ 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;