-
- /* Slow path, need to grab more locks and search. */
-
- /* Warning: this may drop the lock on *bucket! */
- *num_locks = relock_hash_to_zero(tdb, *start_lock, ltype);
- if (*num_locks == TDB_OFF_ERR)
- return TDB_OFF_ERR;
-
- for (*bucket = *start_lock;
- *bucket < *start_lock + *num_locks;
- (*bucket)++) {
- off = entry_matches(tdb, *bucket, h, &key, rec);
- /* Empty entry or we found it? */
- if (off == 0 || off != TDB_OFF_ERR)
- return off;
- }
-
- /* We didn't find a zero entry? Something went badly wrong... */
- unlock_lists(tdb, *start_lock, *start_lock + *num_locks, ltype);
- tdb->ecode = TDB_ERR_CORRUPT;
- tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv,
- "find_and_lock: expected to find an empty hash bucket!\n");
- return TDB_OFF_ERR;
-}
-
-/* Returns -1 on error, 0 on OK, 1 on "expand and retry." */
-static int replace_data(struct tdb_context *tdb,
- uint64_t h, struct tdb_data key, struct tdb_data dbuf,
- tdb_off_t bucket,
- tdb_off_t old_off, tdb_len_t old_room,
- bool growing)
-{
- tdb_off_t new_off;
-
- /* Allocate a new record. */
- new_off = alloc(tdb, key.dsize, dbuf.dsize, h, growing);
- if (new_off == 0)
- return 1;
-
- /* We didn't like the existing one: remove it. */
- if (old_off)
- add_free_record(tdb, old_off,
- sizeof(struct tdb_used_record)
- + key.dsize + old_room);
-
- /* FIXME: Encode extra hash bits! */
- if (tdb_write_off(tdb, hash_off(tdb, bucket), new_off) == -1)
- return -1;
-
- new_off += sizeof(struct tdb_used_record);
- if (tdb->methods->write(tdb, new_off, key.dptr, key.dsize) == -1)
- return -1;
-
- new_off += key.dsize;
- if (tdb->methods->write(tdb, new_off, dbuf.dptr, dbuf.dsize) == -1)
- return -1;
-
- /* FIXME: tdb_increment_seqnum(tdb); */
- return 0;