summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-08-29 20:49:09 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:30:22 -0500
commitd76e724b1029f840c947859ba5354fa171a2b383 (patch)
tree75f0a5bb65c96d044637fb508f095e9171d446e4
parent48853f0badc92b86c18ed3daad3d45f8d74c5cac (diff)
downloadsamba-d76e724b1029f840c947859ba5354fa171a2b383.tar.gz
samba-d76e724b1029f840c947859ba5354fa171a2b383.tar.bz2
samba-d76e724b1029f840c947859ba5354fa171a2b383.zip
r24791: Fix logic error in timeout of blocking lock processing found by
Ronnie. If a lock timeout expires, we must check we can get the lock before responding with failure. Volker is writing a torture test. Jeremy. (This used to be commit 45380f356b99d575645873b05af17c504b091dc8)
-rw-r--r--source3/smbd/blocking.c51
1 files changed, 29 insertions, 22 deletions
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 86cf315930..3bf6e0f99a 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -702,18 +702,14 @@ static void process_blocking_lock_queue(void)
DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
fsp->fnum, fsp->fsp_name ));
- if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
+ if(!change_to_user(conn,vuid)) {
struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
/*
- * Lock expired - throw away all previously
- * obtained locks and return lock error.
+ * Remove the entry and return an error to the client.
*/
if (br_lck) {
- DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
- fsp->fnum, fsp->fsp_name ));
-
brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
@@ -723,14 +719,16 @@ static void process_blocking_lock_queue(void)
TALLOC_FREE(br_lck);
}
- blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
+ DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
+ vuid ));
+ blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
recalc_timeout = True;
continue;
}
- if(!change_to_user(conn,vuid)) {
+ if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) {
struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
/*
@@ -747,21 +745,23 @@ static void process_blocking_lock_queue(void)
TALLOC_FREE(br_lck);
}
- DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
- vuid ));
+ DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
recalc_timeout = True;
+ change_to_root_user();
continue;
}
- if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) {
- struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
+ /*
+ * Go through the remaining locks and try and obtain them.
+ * The call returns True if all locks were obtained successfully
+ * and False if we still need to wait.
+ */
- /*
- * Remove the entry and return an error to the client.
- */
+ if(blocking_lock_record_process(blr)) {
+ struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
if (br_lck) {
brl_lock_cancel(br_lck,
@@ -773,8 +773,6 @@ static void process_blocking_lock_queue(void)
TALLOC_FREE(br_lck);
}
- DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
recalc_timeout = True;
@@ -782,16 +780,25 @@ static void process_blocking_lock_queue(void)
continue;
}
+ change_to_root_user();
+
/*
- * Go through the remaining locks and try and obtain them.
- * The call returns True if all locks were obtained successfully
- * and False if we still need to wait.
+ * We couldn't get the locks for this record on the list.
+ * If the time has expired, return a lock error.
*/
- if(blocking_lock_record_process(blr)) {
+ if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
struct byte_range_lock *br_lck = brl_get_locks(NULL, fsp);
+ /*
+ * Lock expired - throw away all previously
+ * obtained locks and return lock error.
+ */
+
if (br_lck) {
+ DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
+ fsp->fnum, fsp->fsp_name ));
+
brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
@@ -801,11 +808,11 @@ static void process_blocking_lock_queue(void)
TALLOC_FREE(br_lck);
}
+ blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
DLIST_REMOVE(blocking_lock_queue, blr);
free_blocking_lock_record(blr);
recalc_timeout = True;
}
- change_to_root_user();
}
if (recalc_timeout) {