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) {
