avoid write locks during delete checks in traversals
authorAndrew Tridgell <tridge@samba.org>
Fri, 4 Jan 2008 22:33:39 +0000 (09:33 +1100)
committerAndrew Tridgell <tridge@samba.org>
Fri, 4 Jan 2008 22:33:39 +0000 (09:33 +1100)
lib/tdb/common/tdb.c
lib/tdb/common/tdb_private.h
lib/tdb/common/traverse.c

index 4afbfdaa2ba9ae34dc7d844729158caf11c7cabf..5be6325d4952ff7f1a2a148496770754e22dd948 100644 (file)
@@ -243,7 +243,8 @@ int tdb_do_delete(struct tdb_context *tdb, tdb_off_t rec_ptr, struct list_struct
 
        if (tdb->read_only || tdb->traverse_read) return -1;
 
-       if (tdb_write_lock_record(tdb, rec_ptr) == -1) {
+       if (tdb->traverse_write != 0 || 
+           tdb_write_lock_record(tdb, rec_ptr) == -1) {
                /* Someone traversing here: mark it as dead */
                rec->magic = TDB_DEAD_MAGIC;
                return tdb_rec_write(tdb, rec_ptr, rec);
index d16dcb93afe67a26f814c2f55d31ce13ed78b1f7..920a3de8f53e71de8b0a07a377b9d9bfd4e57d7b 100644 (file)
@@ -151,6 +151,7 @@ struct tdb_context {
        tdb_len_t map_size; /* how much space has been mapped */
        int read_only; /* opened read-only */
        int traverse_read; /* read-only traversal */
+       int traverse_write; /* read-write traversal */
        struct tdb_lock_type global_lock;
        int num_lockrecs;
        struct tdb_lock_type *lockrecs; /* only real locks, all with count>0 */
index a6f9165617398367a5dd579ca4ba42c3857656a5..5f7b4c88445e225f5b99d5882cb7a56db1bd663f 100644 (file)
@@ -238,7 +238,9 @@ int tdb_traverse(struct tdb_context *tdb,
                return -1;
        }
 
+       tdb->traverse_write++;
        ret = tdb_traverse_internal(tdb, fn, private_data, &tl);
+       tdb->traverse_write--;
 
        tdb_transaction_unlock(tdb);