summaryrefslogtreecommitdiff
path: root/source3/locking/locking.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-07-17 21:09:02 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:38:11 -0500
commite1da1fcf12164f50f3462c90f0bb785d18c59b0b (patch)
tree8df81a6c947a609249d67188c3a5dbebbdee0984 /source3/locking/locking.c
parent4c713703d046f756989e7eb901e884829825593c (diff)
downloadsamba-e1da1fcf12164f50f3462c90f0bb785d18c59b0b.tar.gz
samba-e1da1fcf12164f50f3462c90f0bb785d18c59b0b.tar.bz2
samba-e1da1fcf12164f50f3462c90f0bb785d18c59b0b.zip
r17098: Samba3 now cleanly passes Samba4 RAW-LOCK torture
test. Phew - that was painful :-). But what it means is that we now implement lock cancels and I can add lock cancels into POSIX lock handling which will fix the fast/slow system call issue with cifsfs ! Jeremy. (This used to be commit f1a9cf075b87c76c032d19da0168424c90f6cb3c)
Diffstat (limited to 'source3/locking/locking.c')
-rw-r--r--source3/locking/locking.c102
1 files changed, 46 insertions, 56 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index ac50c9b648..cd1d9547f3 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -185,7 +185,7 @@ NTSTATUS do_lock(files_struct *fsp,
SMB_BIG_UINT offset,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- BOOL *my_lock_ctx)
+ int32 lock_timeout)
{
struct byte_range_lock *br_lck = NULL;
NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
@@ -216,76 +216,63 @@ NTSTATUS do_lock(files_struct *fsp,
count,
lock_type,
lock_flav,
- my_lock_ctx);
+ lock_timeout);
TALLOC_FREE(br_lck);
return status;
}
/****************************************************************************
- Utility function called by locking requests. This is *DISGUSTING*. It also
- appears to be "What Windows Does" (tm). Andrew, ever wonder why Windows 2000
- is so slow on the locking tests...... ? This is the reason. Much though I hate
- it, we need this. JRA.
+ Utility function called by unlocking requests.
****************************************************************************/
-NTSTATUS do_lock_spin(files_struct *fsp,
+NTSTATUS do_unlock(files_struct *fsp,
uint32 lock_pid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
- enum brl_type lock_type,
- enum brl_flavour lock_flav,
- BOOL *my_lock_ctx)
+ enum brl_flavour lock_flav)
{
- int j, maxj = lp_lock_spin_count();
- int sleeptime = lp_lock_sleep_time();
- NTSTATUS status, ret;
-
- if (maxj <= 0) {
- maxj = 1;
+ BOOL ok = False;
+ struct byte_range_lock *br_lck = NULL;
+
+ if (!fsp->can_lock) {
+ return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
}
+
+ if (!lp_locking(SNUM(fsp->conn))) {
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
+ (double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
- ret = NT_STATUS_OK; /* to keep dumb compilers happy */
-
- for (j = 0; j < maxj; j++) {
- status = do_lock(fsp,
- lock_pid,
- count,
- offset,
- lock_type,
- lock_flav,
- my_lock_ctx);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
- return status;
- }
- /* if we do fail then return the first error code we got */
- if (j == 0) {
- ret = status;
- /* Don't spin if we blocked ourselves. */
- if (*my_lock_ctx) {
- return ret;
- }
+ br_lck = brl_get_locks(NULL, fsp);
+ if (!br_lck) {
+ return NT_STATUS_NO_MEMORY;
+ }
- /* Only spin for Windows locks. */
- if (lock_flav == POSIX_LOCK) {
- return ret;
- }
- }
+ ok = brl_unlock(br_lck,
+ lock_pid,
+ procid_self(),
+ offset,
+ count,
+ lock_flav);
+
+ TALLOC_FREE(br_lck);
- if (sleeptime) {
- sys_usleep(sleeptime);
- }
+ if (!ok) {
+ DEBUG(10,("do_unlock: returning ERRlock.\n" ));
+ return NT_STATUS_RANGE_NOT_LOCKED;
}
- return ret;
+
+ return NT_STATUS_OK;
}
/****************************************************************************
- Utility function called by unlocking requests.
+ Cancel any pending blocked locks.
****************************************************************************/
-NTSTATUS do_unlock(files_struct *fsp,
+NTSTATUS do_lock_cancel(files_struct *fsp,
uint32 lock_pid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
@@ -295,14 +282,15 @@ NTSTATUS do_unlock(files_struct *fsp,
struct byte_range_lock *br_lck = NULL;
if (!fsp->can_lock) {
- return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
+ return fsp->is_directory ?
+ NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
}
if (!lp_locking(SNUM(fsp->conn))) {
- return NT_STATUS_OK;
+ return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
}
-
- DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
+
+ DEBUG(10,("do_lock_cancel: cancel start=%.0f len=%.0f requested for fnum %d file %s\n",
(double)offset, (double)count, fsp->fnum, fsp->fsp_name ));
br_lck = brl_get_locks(NULL, fsp);
@@ -310,7 +298,7 @@ NTSTATUS do_unlock(files_struct *fsp,
return NT_STATUS_NO_MEMORY;
}
- ok = brl_unlock(br_lck,
+ ok = brl_lock_cancel(br_lck,
lock_pid,
procid_self(),
offset,
@@ -320,8 +308,8 @@ NTSTATUS do_unlock(files_struct *fsp,
TALLOC_FREE(br_lck);
if (!ok) {
- DEBUG(10,("do_unlock: returning ERRlock.\n" ));
- return NT_STATUS_RANGE_NOT_LOCKED;
+ DEBUG(10,("do_lock_cancel: returning ERRcancelviolation.\n" ));
+ return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
}
return NT_STATUS_OK;
@@ -340,7 +328,9 @@ void locking_close_file(files_struct *fsp)
}
br_lck = brl_get_locks(NULL,fsp);
+
if (br_lck) {
+ cancel_pending_lock_requests_by_fid(fsp, br_lck);
brl_close_fnum(br_lck);
TALLOC_FREE(br_lck);
}