- /* Only one person can expand file at a time. */
- if (tdb_lock_expand(tdb, F_WRLCK) != 0)
- return -1;
-
- /* Someone else may have expanded the file, so retry. */
- old_size = tdb->map_size;
- tdb->methods->oob(tdb, tdb->map_size + 1, true);
- if (tdb->map_size != old_size)
- goto success;
-
- /* FIXME: Tailer is a bogus optimization, remove it. */
- /* zone bits tailer char is protected by EXPAND lock. */
- if (tdb->methods->read(tdb, old_size - 1, &zone_bits, 1) == -1)
- goto fail;
-
- /* If zones aren't working well, add larger zone if possible. */
- enlarge_zone = !zones_happy(tdb);
-
- /* New zone can be between zone_bits or larger if we're on the right
- * boundary. */
- for (;;) {
- /* Does this fit the allocation comfortably? */
- if ((1ULL << zone_bits) >= overhead(zone_bits) + wanted) {
- /* Only let enlarge_zone enlarge us once. */
- if (!enlarge_zone)
- break;
- enlarge_zone = false;
- }
- if ((old_size - 1 - sizeof(struct tdb_header))
- & (1 << zone_bits))
- break;
- zone_bits++;
+ /* Need to hold a hash lock to expand DB: transactions rely on it. */
+ if (!(tdb->flags & TDB_NOLOCK)
+ && !tdb->file->allrecord_lock.count && !tdb_has_hash_locks(tdb)) {
+ return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR,
+ "tdb_expand: must hold lock during expand");