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 */

Reply via email to