]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3/smbd: add and use retry_open() instead of defer_open() in two places
authorRalph Boehme <slow@samba.org>
Tue, 7 Mar 2017 14:03:12 +0000 (15:03 +0100)
committerKarolin Seeger <kseeger@samba.org>
Tue, 14 Mar 2017 11:49:24 +0000 (12:49 +0100)
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit beaba6222848fb4ff4392b2247c5be1094b1d65b)

source3/smbd/open.c

index 070e2286d3ef0475b88c103c4d68b88b792ff2bc..9ffae48963d47d74dc0a9b7da417cc8aec35751a 100644 (file)
@@ -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. "