- /* Allocate a new record. */
- new_off = alloc(tdb, key.dsize, dbuf.dsize, h, growing);
- if (new_off == 0) {
- unlock_lists(tdb, start, end, F_WRLCK);
- /* Expand, then try again... */
- if (tdb_expand(tdb, key.dsize, dbuf.dsize, growing) == -1)
- return -1;
- return tdb_store(tdb, key, dbuf, flag);
- }
-
- /* We didn't like the existing one: remove it. */
- if (off) {
- add_free_record(tdb, off, sizeof(struct tdb_used_record)
- + key.dsize + room);
- }
-
-write:
- off = tdb->header.v.hash_off + end * sizeof(tdb_off_t);
- /* FIXME: Encode extra hash bits! */
- if (tdb_write_off(tdb, off, new_off) == -1)
- goto fail;
-
- off = new_off + sizeof(struct tdb_used_record);
- if (tdb->methods->write(tdb, off, key.dptr, key.dsize) == -1)
- goto fail;
- off += key.dsize;
- if (tdb->methods->write(tdb, off, dbuf.dptr, dbuf.dsize) == -1)
- goto fail;
-
- /* FIXME: tdb_increment_seqnum(tdb); */
- unlock_lists(tdb, start, end, F_WRLCK);
-
- /* By simple trial and error, this roughly approximates a 60%
- * full measure. */
- if (unlikely(end - start > 4 * tdb->header.v.hash_bits - 32))
- enlarge_hash(tdb);
-
- return 0;
-
-fail:
- unlock_lists(tdb, start, end, F_WRLCK);
- return -1;
+ /* If we didn't use the old record, this implies we're growing. */
+ ecode = replace_data(tdb, &h, key, dbuf, off, old_room, off);
+out:
+ tdb_unlock_hashes(tdb, h.hlock_start, h.hlock_range, F_WRLCK);
+ return ecode;