- /* Someone else enlarged for us? Nothing to do. */
- if ((1ULL << tdb->header.v.hash_bits) != num)
- goto unlock;
-
- /* Allocate our new array. */
- hlen = num * sizeof(tdb_off_t) * 2;
- newoff = alloc(tdb, 0, hlen, 0, false);
- if (unlikely(newoff == TDB_OFF_ERR))
- goto unlock;
- if (unlikely(newoff == 0)) {
- if (tdb_expand(tdb, 0, hlen, false) == -1)
- goto unlock;
- newoff = alloc(tdb, 0, hlen, 0, false);
- if (newoff == TDB_OFF_ERR || newoff == 0)
- goto unlock;
- }
- /* Step over record header! */
- newoff += sizeof(struct tdb_used_record);
-
- /* Starts all zero. */
- if (zero_out(tdb, newoff, hlen) == -1)
- goto unlock;
-
- /* FIXME: If the space before is empty, we know this is in its ideal
- * location. Or steal a bit from the pointer to avoid rehash. */
- for (i = tdb_find_nonzero_off(tdb, hash_off(tdb, 0), num);
- i < num;
- i += tdb_find_nonzero_off(tdb, hash_off(tdb, i), num - i)) {
- tdb_off_t off;
- off = tdb_read_off(tdb, hash_off(tdb, i));
- if (unlikely(off == TDB_OFF_ERR))
- goto unlock;
- if (unlikely(!off)) {
- tdb->ecode = TDB_ERR_CORRUPT;
- tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv,
- "enlarge_hash: zero hash bucket!\n");
- goto unlock;
- }
-
- /* Find next empty hash slot. */
- for (h = hash_record(tdb, off);
- tdb_read_off(tdb, newoff + (h & ((num * 2)-1))
- * sizeof(tdb_off_t)) != 0;
- h++);
-
- /* FIXME: Encode extra hash bits! */
- if (tdb_write_off(tdb, newoff + (h & ((num * 2)-1))
- * sizeof(tdb_off_t), off) == -1)
- goto unlock;
- i++;
+ ecode = tdb->methods->twrite(tdb, off, dbuf.dptr, dbuf.dsize);
+ if (ecode == TDB_SUCCESS && extra) {
+ /* Put a zero in; future versions may append other data. */
+ ecode = tdb->methods->twrite(tdb, off + dbuf.dsize, "", 1);