summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2012-06-29 13:14:10 -0700
committerJeremy Allison <jra@samba.org>2012-06-30 02:23:39 +0200
commitb004121d9beb890054b373f96c8145bf8a830065 (patch)
treeb62dfd999a3a07140f9f11fb2c193a128e5343a8
parentd1e1aa552d3feb430b6b48c572ba2b713dfffec5 (diff)
downloadsamba-b004121d9beb890054b373f96c8145bf8a830065.tar.gz
samba-b004121d9beb890054b373f96c8145bf8a830065.tar.bz2
samba-b004121d9beb890054b373f96c8145bf8a830065.zip
Allow for async opens.
If the SMB_VFS_OPEN() function returns -1, EINTR -> NT_STATUS_RETRY, then queue the open up to be completed when the async open completes.
-rw-r--r--source3/smbd/open.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 468b9cc315..467a69f049 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -1542,6 +1542,27 @@ static void schedule_defer_open(struct share_mode_lock *lck,
}
/****************************************************************************
+ Reschedule an open call that went asynchronous.
+****************************************************************************/
+
+static void schedule_async_open(struct timeval request_time,
+ struct smb_request *req)
+{
+ struct deferred_open_record state;
+ struct timeval timeout;
+
+ timeout = timeval_set(20, 0);
+
+ ZERO_STRUCT(state);
+ state.delayed_for_oplocks = false;
+ state.async_open = true;
+
+ if (!request_timed_out(request_time, timeout)) {
+ defer_open(NULL, request_time, timeout, req, &state);
+ }
+}
+
+/****************************************************************************
Work out what access_mask to use from what the client sent us.
****************************************************************************/
@@ -1773,10 +1794,17 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
request with this mid. We'll use it later to
see if this has timed out. */
- /* Remove the deferred open entry under lock. */
- remove_deferred_open_entry(
- state->id, req->mid,
- messaging_server_id(req->sconn->msg_ctx));
+ /* If it was an async create retry, the file
+ didn't exist. */
+ if (state->async_open) {
+ SET_STAT_INVALID(smb_fname->st);
+ file_existed = false;
+ } else {
+ /* Remove the deferred open entry under lock. */
+ remove_deferred_open_entry(
+ state->id, req->mid,
+ messaging_server_id(req->sconn->msg_ctx));
+ }
/* Ensure we don't reprocess this message. */
remove_deferred_open_message_smb(req->sconn, req->mid);
@@ -2223,6 +2251,9 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
open_access_mask);
if (!NT_STATUS_IS_OK(fsp_open)) {
+ if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
+ schedule_async_open(request_time, req);
+ }
TALLOC_FREE(lck);
return fsp_open;
}