summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/brlock.c13
-rw-r--r--source3/locking/locking.c36
2 files changed, 40 insertions, 9 deletions
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index 4cd885f1a6..20d76c9c79 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -414,7 +414,9 @@ static BOOL brl_pending_overlap(struct lock_struct *lock, struct lock_struct *pe
BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
uint16 smbpid, pid_t pid, uint16 tid,
br_off start, br_off size,
- BOOL remove_pending_locks_only)
+ BOOL remove_pending_locks_only,
+ void (*pre_unlock_fn)(void *),
+ void *pre_unlock_data)
{
TDB_DATA kbuf, dbuf;
int count, i, j;
@@ -450,6 +452,10 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
lock->fnum == fnum &&
lock->start == start &&
lock->size == size) {
+
+ if (pre_unlock_fn)
+ (*pre_unlock_fn)(pre_unlock_data);
+
/* found it - delete it */
if (count == 1) {
tdb_delete(tdb, kbuf);
@@ -483,6 +489,11 @@ BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
continue;
if (lock->lock_type != PENDING_LOCK) {
+
+ /* Do any POSIX unlocks needed. */
+ if (pre_unlock_fn)
+ (*pre_unlock_fn)(pre_unlock_data);
+
/* Send unlock messages to any pending waiters that overlap. */
for (j=0; j<count; j++) {
struct lock_struct *pend_lock = &locks[j];
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 651f905e15..1b40187ac4 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -132,7 +132,8 @@ static NTSTATUS do_lock(files_struct *fsp,connection_struct *conn, uint16 lock_p
*/
(void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
lock_pid, sys_getpid(), conn->cnum,
- offset, count, False);
+ offset, count, False,
+ NULL, NULL);
}
}
}
@@ -175,6 +176,25 @@ NTSTATUS do_lock_spin(files_struct *fsp,connection_struct *conn, uint16 lock_pid
return ret;
}
+/* Struct passed to brl_unlock. */
+struct posix_unlock_data_struct {
+ files_struct *fsp;
+ SMB_BIG_UINT offset;
+ SMB_BIG_UINT count;
+};
+
+/****************************************************************************
+ Function passed to brl_unlock to allow POSIX unlock to be done first.
+****************************************************************************/
+
+static void posix_unlock(void *pre_data)
+{
+ struct posix_unlock_data_struct *pdata = (struct posix_unlock_data_struct *)pre_data;
+
+ if (lp_posix_locking(SNUM(pdata->fsp->conn)))
+ release_posix_lock(pdata->fsp, pdata->offset, pdata->count);
+}
+
/****************************************************************************
Utility function called by unlocking requests.
****************************************************************************/
@@ -183,6 +203,7 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
SMB_BIG_UINT count,SMB_BIG_UINT offset)
{
BOOL ok = False;
+ struct posix_unlock_data_struct posix_data;
if (!lp_locking(SNUM(conn)))
return NT_STATUS_OK;
@@ -200,19 +221,18 @@ NTSTATUS do_unlock(files_struct *fsp,connection_struct *conn, uint16 lock_pid,
* match then don't bother looking to remove POSIX locks.
*/
+ posix_data.fsp = fsp;
+ posix_data.offset = offset;
+ posix_data.count = count;
+
ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
- lock_pid, sys_getpid(), conn->cnum, offset, count, False);
+ lock_pid, sys_getpid(), conn->cnum, offset, count,
+ False, posix_unlock, (void *)&posix_data);
if (!ok) {
DEBUG(10,("do_unlock: returning ERRlock.\n" ));
return NT_STATUS_RANGE_NOT_LOCKED;
}
-
- if (!lp_posix_locking(SNUM(conn)))
- return NT_STATUS_OK;
-
- (void)release_posix_lock(fsp, offset, count);
-
return NT_STATUS_OK;
}