From 87df5a631200a5725618fbe2779ade7066ad084c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 Jan 2007 11:46:27 +0000 Subject: 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) --- source4/ntvfs/common/brlock_tdb.c | 72 ++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 28 deletions(-) (limited to 'source4') 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; icontext, &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; icontext, &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 */ -- cgit