X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=ccan%2Ftdb2%2Ffree.c;h=6fd82c5c540d0ee2767d60385c43654606396c8b;hb=dfae76fd82d4bbd8989264dadc2c3c9cde7e5af7;hp=ac637ce1c8650caab593036c143bce5b1b65bc47;hpb=ef9dec6018e1f0c6e546245a1478be523592d02d;p=ccan-lca-2011.git diff --git a/ccan/tdb2/free.c b/ccan/tdb2/free.c index ac637ce..6fd82c5 100644 --- a/ccan/tdb2/free.c +++ b/ccan/tdb2/free.c @@ -418,9 +418,9 @@ again: assert(keylen + datalen + leftover <= best.data_len); /* We need to mark non-free before we drop lock, otherwise * coalesce() could try to merge it! */ - if (set_header(tdb, &rec, keylen, datalen, - best.data_len - leftover, - hashlow) != 0) + if (set_used_header(tdb, &rec, keylen, datalen, + best.data_len - leftover, + hashlow) != 0) goto unlock_err; if (tdb_write_convert(tdb, best_off, &rec, sizeof(rec)) != 0) @@ -493,10 +493,10 @@ static tdb_off_t get_free(struct tdb_context *tdb, return 0; } -int set_header(struct tdb_context *tdb, - struct tdb_used_record *rec, - uint64_t keylen, uint64_t datalen, - uint64_t actuallen, unsigned hashlow) +int set_used_header(struct tdb_context *tdb, + struct tdb_used_record *rec, + uint64_t keylen, uint64_t datalen, + uint64_t actuallen, unsigned hashlow) { uint64_t keybits = (fls64(keylen) + 1) / 2; @@ -530,6 +530,14 @@ static int tdb_expand(struct tdb_context *tdb, tdb_len_t size) /* We need room for the record header too. */ wanted = sizeof(struct tdb_used_record) + size; + /* Need to hold a hash lock to expand DB: transactions rely on it. */ + if (!(tdb->flags & TDB_NOLOCK) + && !tdb->allrecord_lock.count && !tdb_has_hash_locks(tdb)) { + tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, + "tdb_expand: must hold lock during expand\n"); + return -1; + } + /* Only one person can expand file at a time. */ if (tdb_lock_expand(tdb, F_WRLCK) != 0) return -1;