diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-09-22 13:12:46 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:38:44 -0500 |
commit | bd310b792509f7305d7dc029eb4bec109322a4bf (patch) | |
tree | 7621c4474ccae12b9126e09c25bd6ff70fbc998e /source4/lib/tdb/common/lock.c | |
parent | 05bd880626255c6547922204d7ba012aa9bc6d50 (diff) | |
download | samba-bd310b792509f7305d7dc029eb4bec109322a4bf.tar.gz samba-bd310b792509f7305d7dc029eb4bec109322a4bf.tar.bz2 samba-bd310b792509f7305d7dc029eb4bec109322a4bf.zip |
r10421: following on discussions with simo, I have worked out a way of
allowing searches to proceed while another process is in a
transaction, then only upgrading the transaction lock to a write lock
on commit.
The solution is:
- split tdb_traverse() into two calls, called tdb_traverse() and
tdb_traverse_read(). The _read() version only gets read locks, and
will fail any write operations made in the callback from the
traverse.
- the normal tdb_traverse() call allows for read or write operations
in the callback, but gets the transaction lock, preventing
transastions from starting inside the traverse
In addition we enforce the following rule that you may not start a
transaction within a traverse callback, although you can start a
traverse within a transaction
With these rules in place I believe all the deadlock possibilities are
removed, and we can now allow for searches to happen in parallel with
transactions
(This used to be commit 7dd31288a701d772e45b1960ac4ce4cc1be782ed)
Diffstat (limited to 'source4/lib/tdb/common/lock.c')
-rw-r--r-- | source4/lib/tdb/common/lock.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/source4/lib/tdb/common/lock.c b/source4/lib/tdb/common/lock.c index 8061bab7b1..7a76bd3d9b 100644 --- a/source4/lib/tdb/common/lock.c +++ b/source4/lib/tdb/common/lock.c @@ -42,10 +42,12 @@ int tdb_brlock_len(struct tdb_context *tdb, tdb_off_t offset, struct flock fl; int ret; - if (tdb->flags & TDB_NOLOCK) + if (tdb->flags & TDB_NOLOCK) { return 0; + } + if ((rw_type == F_WRLCK) && (tdb->read_only)) { - errno = EACCES; + tdb->ecode = TDB_ERR_RDONLY; return -1; } @@ -64,8 +66,8 @@ int tdb_brlock_len(struct tdb_context *tdb, tdb_off_t offset, * EAGAIN is an expected return from non-blocking * locks. */ if (errno != EAGAIN) { - TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d: %s\n", - tdb->fd, offset, rw_type, lck_type, + TDB_LOG((tdb, 5, "tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d: %s\n", + tdb->fd, offset, rw_type, lck_type, len, strerror(errno))); } else if (!probe && lck_type != F_SETLK) { /* Ensure error code is set for log fun to examine. */ |