Author: tridge Date: 2007-01-22 11:46:27 +0000 (Mon, 22 Jan 2007) New Revision: 20947
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=20947 Log: fixed a bug in the unlock logic in the brlock tdb backend I'm very surprised this didn't show up earlier! Modified: branches/SAMBA_4_0/source/ntvfs/common/brlock_tdb.c Changeset: Modified: branches/SAMBA_4_0/source/ntvfs/common/brlock_tdb.c =================================================================== --- branches/SAMBA_4_0/source/ntvfs/common/brlock_tdb.c 2007-01-22 11:45:48 UTC (rev 20946) +++ branches/SAMBA_4_0/source/ntvfs/common/brlock_tdb.c 2007-01-22 11:46:27 UTC (rev 20947) @@ -423,7 +423,7 @@ { 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 @@ 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 == WRITE_LOCK) { + break; + } + } + if (i < count) goto found; + + 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) { - /* 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--; + break; + } + } - /* 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; - } +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 */