diff options
Diffstat (limited to 'source3/locking')
-rw-r--r-- | source3/locking/brlock.c | 33 | ||||
-rw-r--r-- | source3/locking/locking.c | 18 |
2 files changed, 45 insertions, 6 deletions
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c index 8f73327830..7f3ec6757e 100644 --- a/source3/locking/brlock.c +++ b/source3/locking/brlock.c @@ -341,13 +341,33 @@ smbpid = %u, pid = %u, tid = %u\n", } /**************************************************************************** + Check to see if this lock conflicts, but ignore our own locks on the + same fnum only. +****************************************************************************/ + +static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) +{ + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) + return False; + + if (brl_same_context(&lck1->context, &lck2->context) && + lck1->fnum == lck2->fnum) + return False; + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) return False; + + return True; +} + +/**************************************************************************** Test if we could add a lock if we wanted to. ****************************************************************************/ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, uint16 smbpid, pid_t pid, uint16 tid, br_off start, br_off size, - enum brl_type lock_type) + enum brl_type lock_type, int check_self) { TDB_DATA kbuf, dbuf; int count, i; @@ -373,8 +393,15 @@ BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino, int fnum, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); for (i=0; i<count; i++) { - if (brl_conflict(&locks[i], &lock)) { - goto fail; + if (check_self) { + if (brl_conflict(&locks[i], &lock)) + goto fail; + } else { + /* + * Our own locks don't conflict. + */ + if (brl_conflict_other(&locks[i], &lock)) + goto fail; } } } diff --git a/source3/locking/locking.c b/source3/locking/locking.c index c77a86cbf4..68c3c5b653 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -53,11 +53,14 @@ static const char *lock_type_name(enum brl_type lock_type) /**************************************************************************** Utility function called to see if a file region is locked. + If check_self is True, then checks on our own fd with the same locking context + are still made. If check_self is False, then checks are not made on our own fd + with the same locking context are not made. ****************************************************************************/ BOOL is_locked(files_struct *fsp,connection_struct *conn, SMB_BIG_UINT count,SMB_BIG_UINT offset, - enum brl_type lock_type) + enum brl_type lock_type, BOOL check_self) { int snum = SNUM(conn); BOOL ret; @@ -70,16 +73,25 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn, ret = !brl_locktest(fsp->dev, fsp->inode, fsp->fnum, global_smbpid, sys_getpid(), conn->cnum, - offset, count, lock_type); + offset, count, lock_type, check_self); + + DEBUG(10,("is_locked: brl start=%.0f len=%.0f %s for file %s\n", + (double)offset, (double)count, ret ? "locked" : "unlocked", + fsp->fsp_name )); /* * There is no lock held by an SMB daemon, check to * see if there is a POSIX lock from a UNIX or NFS process. */ - if(!ret && lp_posix_locking(snum)) + if(!ret && lp_posix_locking(snum)) { ret = is_posix_locked(fsp, offset, count, lock_type); + DEBUG(10,("is_locked: posix start=%.0f len=%.0f %s for file %s\n", + (double)offset, (double)count, ret ? "locked" : "unlocked", + fsp->fsp_name )); + } + return ret; } |