Author: jra
Date: 2006-03-28 17:10:20 +0000 (Tue, 28 Mar 2006)
New Revision: 14752

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=14752

Log:
POSIX locks don't care about the fnum - only the dev/ino
pair. Ensure this is reflected in the lock split/merge 
and lock delete code.
Jeremy.

Modified:
   trunk/source/locking/brlock.c


Changeset:
Modified: trunk/source/locking/brlock.c
===================================================================
--- trunk/source/locking/brlock.c       2006-03-28 15:50:13 UTC (rev 14751)
+++ trunk/source/locking/brlock.c       2006-03-28 17:10:20 UTC (rev 14752)
@@ -163,7 +163,8 @@
 
 /****************************************************************************
  See if lock2 can be added when lock1 is in place - when both locks are POSIX
- flavour.
+ flavour. POSIX locks ignore fnum - they only care about dev/ino which we
+ know already match.
 ****************************************************************************/
 
 static BOOL brl_conflict_posix(const struct lock_struct *lck1, 
@@ -183,9 +184,8 @@
                return False;
        }
 
-       /* Locks on the same context on the same fnum con't conflict. */
-       if (brl_same_context(&lck1->context, &lck2->context) &&
-                       (lck1->fnum == lck2->fnum)) {
+       /* Locks on the same context con't conflict. Ignore fnum. */
+       if (brl_same_context(&lck1->context, &lck2->context)) {
                return False;
        }
 
@@ -226,6 +226,7 @@
 /****************************************************************************
  Check to see if this lock conflicts, but ignore our own locks on the
  same fnum only. This is the read/write lock check code path.
+ This is never used in the POSIX lock case.
 ****************************************************************************/
 
 static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct 
lock_struct *lck2)
@@ -403,16 +404,15 @@
 {
        BOOL lock_types_differ = (ex->lock_type != plock->lock_type);
 
-       /* We can't merge non-conflicting locks on different context
-               or not on the same fnum */
+       /* We can't merge non-conflicting locks on different context - ignore 
fnum. */
 
-       if (!brl_same_context(&ex->context, &plock->context) || (ex->fnum != 
plock->fnum)) {
+       if (!brl_same_context(&ex->context, &plock->context)) {
                /* Just copy. */
                memcpy(&lck_arr[0], ex, sizeof(struct lock_struct));
                return 1;
        }
 
-       /* We now know we have the same context and fnum. */
+       /* We now know we have the same context. */
 
        /* Did we overlap ? */
 
@@ -583,7 +583,8 @@
 
        /* Never get here. */
        smb_panic("brlock_posix_split_merge\n");
-       return 0;
+       /* Notreached. */
+       abort();
 }
 
 /****************************************************************************
@@ -766,12 +767,6 @@
                    lock->start == plock->start &&
                    lock->size == plock->size) {
 
-#if 0
-                       if (pre_unlock_fn) {
-                               (*pre_unlock_fn)(pre_unlock_data);
-                       }
-#endif
-
                        /* found it - delete it */
                        if (i < br_lck->num_locks - 1) {
                                memmove(&locks[i], &locks[i+1], 
@@ -803,13 +798,6 @@
                return False;
        }
 
-#if 0
-       /* Do any POSIX unlocks needed. */
-       if (pre_unlock_fn) {
-               (*pre_unlock_fn)(pre_unlock_data);
-       }
-#endif
-
        /* Send unlock messages to any pending waiters that overlap. */
        for (j=0; j < br_lck->num_locks; j++) {
                struct lock_struct *pend_lock = &locks[j];
@@ -885,10 +873,9 @@
 
                lock = &locks[i];
 
-               /* Only remove our own locks */
+               /* Only remove our own locks - ignore fnum. */
                if (!brl_same_context(&lock->context, &plock->context) ||
-                                       lock->lock_type == PENDING_LOCK ||
-                                       lock->fnum != plock->fnum ) {
+                                       lock->lock_type == PENDING_LOCK) {
                        memcpy(&tp[count], lock, sizeof(struct lock_struct));
                        count++;
                        continue;
@@ -956,13 +943,6 @@
                return True;
        }
 
-#if 0
-       /* Do any POSIX unlocks needed. */
-       if (pre_unlock_fn) {
-               (*pre_unlock_fn)(pre_unlock_data);
-       }
-#endif
-
        /* Realloc so we don't leak entries per unlock call. */
        if (count) {
                tp = (struct lock_struct *)SMB_REALLOC(tp, count * 
sizeof(*locks));
@@ -1186,6 +1166,7 @@
        for (i = 0; i < br_lck->num_locks; i++) {
                struct lock_struct *lock = &locks[i];
 
+               /* For pending locks we *always* care about the fnum. */
                if (brl_same_context(&lock->context, &context) &&
                                lock->fnum == br_lck->fsp->fnum &&
                                lock->lock_type == PENDING_LOCK &&
@@ -1225,15 +1206,21 @@
        unsigned int i, j, dcount=0;
        struct lock_struct *locks = (struct lock_struct *)br_lck->lock_data;
 
-       /* Remove any existing locks for this fnum */
+       /* Remove any existing locks for this fnum (or any fnum if they're 
POSIX). */
 
        for (i=0; i < br_lck->num_locks; i++) {
                struct lock_struct *lock = &locks[i];
+               BOOL del_this_lock = False;
 
-               if (lock->context.tid == tid &&
-                   procid_equal(&lock->context.pid, &pid) &&
-                   lock->fnum == fnum) {
+               if (lock->context.tid == tid && 
procid_equal(&lock->context.pid, &pid)) {
+                       if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == 
fnum)) {
+                               del_this_lock = True;
+                       } else if (lock->lock_flav == POSIX_LOCK) {
+                               del_this_lock = True;
+                       }
+               }
 
+               if (del_this_lock) {
                        /* Send unlock messages to any pending waiters that 
overlap. */
                        for (j=0; j < br_lck->num_locks; j++) {
                                struct lock_struct *pend_lock = &locks[j];
@@ -1243,6 +1230,8 @@
                                        continue;
                                }
 
+                               /* Optimisation - don't send to this fnum as 
we're
+                                  closing it. */
                                if (pend_lock->context.tid == tid &&
                                    procid_equal(&pend_lock->context.pid, &pid) 
&&
                                    pend_lock->fnum == fnum) {

Reply via email to