diff options
author | Andrew Tridgell <tridge@samba.org> | 2007-01-22 11:46:27 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:43:59 -0500 |
commit | 87df5a631200a5725618fbe2779ade7066ad084c (patch) | |
tree | 33cb258caf3d4095a10da9a7840cf12f2197cf6a | |
parent | 44b6652e6ce252cedccdcbba2301261257094203 (diff) | |
download | samba-87df5a631200a5725618fbe2779ade7066ad084c.tar.gz samba-87df5a631200a5725618fbe2779ade7066ad084c.tar.bz2 samba-87df5a631200a5725618fbe2779ade7066ad084c.zip |
r20947: fixed a bug in the unlock logic in the brlock tdb backend
I'm very surprised this didn't show up earlier!
(This used to be commit 5d9b1acf4f35d11c4730cbc9cadedb33c6ec08e8)
-rw-r--r-- | source4/ntvfs/common/brlock_tdb.c | 72 |
1 files changed, 44 insertions, 28 deletions
diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index ee83008ce2..6fe8cefd34 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -423,7 +423,7 @@ static NTSTATUS brl_tdb_unlock(struct brl_context *brl, { TDB_DATA kbuf, dbuf; int count, i; - struct lock_struct *locks; + struct lock_struct *locks, *lock; struct lock_context context; NTSTATUS status; @@ -449,42 +449,58 @@ static NTSTATUS brl_tdb_unlock(struct brl_context *brl, count = dbuf.dsize / sizeof(*locks); for (i=0; i<count; i++) { - struct lock_struct *lock = &locks[i]; - + lock = &locks[i]; if (brl_tdb_same_context(&lock->context, &context) && lock->ntvfs == brlh->ntvfs && lock->start == start && lock->size == size && - lock->lock_type < PENDING_READ_LOCK) { - /* found it - delete it */ - if (count == 1) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } else { - struct lock_struct removed_lock = *lock; - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - - /* send notifications for any relevant pending locks */ - brl_tdb_notify_unlock(brl, locks, count, &removed_lock); + lock->lock_type == WRITE_LOCK) { + break; + } + } + if (i < count) goto found; - dbuf.dsize = count * sizeof(*locks); + for (i=0; i<count; i++) { + lock = &locks[i]; + if (brl_tdb_same_context(&lock->context, &context) && + lock->ntvfs == brlh->ntvfs && + lock->start == start && + lock->size == size && + lock->lock_type < PENDING_READ_LOCK) { + break; + } + } - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } +found: + if (i < count) { + /* found it - delete it */ + if (count == 1) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } else { + struct lock_struct removed_lock = *lock; + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); } + count--; - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; + /* send notifications for any relevant pending locks */ + brl_tdb_notify_unlock(brl, locks, count, &removed_lock); + + dbuf.dsize = count * sizeof(*locks); + + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; } /* we didn't find it */ |