From: Ralph Boehme Date: Tue, 7 Mar 2017 14:03:12 +0000 (+0100) Subject: s3/smbd: add and use retry_open() instead of defer_open() in two places X-Git-Tag: samba-4.4.11~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=621abab71fd9457bc6586b7e7111e465cdbbe369;p=thirdparty%2Fsamba.git s3/smbd: add and use retry_open() instead of defer_open() in two places Add a new function that does an immediate open rescheduling. The first deferred open this commit changes was never scheduled, as the scheduling relies on a timeout of the watch on the sharemode lock. This has been broken since the commits in $ git log --reverse -p -10 8283fd0e0090ed12b0b12d5acb550642d621b026 That patchset added the dbwrap watch record logic to defer_open() and removed the timers. I'm doing this mainly to untangle the defer_open() logic which is complicated by the lck arg. Bug: https://bugzilla.samba.org/show_bug.cgi?id=7537 Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison (cherry picked from commit beaba6222848fb4ff4392b2247c5be1094b1d65b) --- diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 070e2286d3e..9ffae48963d 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2037,6 +2037,40 @@ static void defer_open_done(struct tevent_req *req) TALLOC_FREE(state); } +/** + * Reschedule an open for immediate execution + **/ +static void retry_open(struct timeval request_time, + struct smb_request *req, + struct file_id id) +{ + struct deferred_open_record *open_rec = NULL; + bool ok; + + DBG_DEBUG("request time [%s] mid [%" PRIu64 "] file_id [%s]\n", + timeval_string(talloc_tos(), &request_time, false), + req->mid, + file_id_string_tos(&id)); + + open_rec = deferred_open_record_create(false, false, id); + if (open_rec == NULL) { + exit_server("talloc failed"); + } + + ok = push_deferred_open_message_smb(req, + request_time, + timeval_set(0, 0), + id, + open_rec); + if (!ok) { + exit_server("push_deferred_open_message_smb failed"); + } + + ok = schedule_deferred_open_message_smb(req->xconn, req->mid); + if (!ok) { + exit_server("schedule_deferred_open_message_smb failed"); + } +} /**************************************************************************** On overwrite open ensure that the attributes match. @@ -2822,8 +2856,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id); if (lck == NULL) { - defer_open(NULL, request_time, timeval_set(0, 0), - req, false, false, fsp->file_id); + retry_open(request_time, req, fsp->file_id); DEBUG(10, ("No share mode lock found after " "EWOULDBLOCK, retrying sync\n")); return NT_STATUS_SHARING_VIOLATION; @@ -2849,8 +2882,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, * No oplock from Samba around. Immediately retry with * a blocking open. */ - defer_open(lck, request_time, timeval_set(0, 0), req, - false, false, fsp->file_id); + retry_open(request_time, req, fsp->file_id); TALLOC_FREE(lck); DEBUG(10, ("No Samba oplock around after EWOULDBLOCK. "