]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Optionally wait for a share mode record in setup_poll_open()
authorVolker Lendecke <vl@samba.org>
Sun, 18 Aug 2019 06:55:14 +0000 (08:55 +0200)
committerJeremy Allison <jra@samba.org>
Mon, 19 Aug 2019 23:14:38 +0000 (23:14 +0000)
This will be used when waiting for a oplock break that has been
signalled via a kernel oplock break.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/open.c

index cea3d882637c6cf5002135e523efc2ce20c77548..fc2df6eb0a02624ad94b8e670c5ab46cd12e70f4 100644 (file)
@@ -2485,11 +2485,14 @@ static void poll_open_fn(struct tevent_context *ev,
        DBG_DEBUG("timer fired. Retrying open !\n");
 }
 
+static void poll_open_done(struct tevent_req *subreq);
+
 /**
  * Reschedule an open for 1 second from now, if not timed out.
  **/
 static bool setup_poll_open(
        struct smb_request *req,
+       struct share_mode_lock *lck,
        struct file_id id,
        struct timeval max_timeout,
        struct timeval interval)
@@ -2532,6 +2535,20 @@ static bool setup_poll_open(
                return false;
        }
 
+       if (lck != NULL) {
+               struct tevent_req *watch_req = dbwrap_watched_watch_send(
+                       open_rec,
+                       req->sconn->ev_ctx,
+                       lck->data->record,
+                       (struct server_id) {0});
+               if (watch_req == NULL) {
+                       DBG_WARNING("dbwrap_watched_watch_send failed\n");
+                       TALLOC_FREE(open_rec);
+                       return false;
+               }
+               tevent_req_set_callback(watch_req, poll_open_done, open_rec);
+       }
+
        ok = push_deferred_open_message_smb(req, max_timeout, id, open_rec);
        if (!ok) {
                DBG_WARNING("push_deferred_open_message_smb failed\n");
@@ -2547,6 +2564,25 @@ static bool setup_poll_open(
        return true;
 }
 
+static void poll_open_done(struct tevent_req *subreq)
+{
+       struct deferred_open_record *open_rec = tevent_req_callback_data(
+               subreq, struct deferred_open_record);
+       NTSTATUS status;
+       bool ok;
+
+       status = dbwrap_watched_watch_recv(subreq, NULL, NULL);
+       TALLOC_FREE(subreq);
+       DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
+                 nt_errstr(status));
+
+       ok = schedule_deferred_open_message_smb(
+               open_rec->xconn, open_rec->mid);
+       if (!ok) {
+               exit_server("schedule_deferred_open_message_smb failed");
+       }
+}
+
 bool defer_smb1_sharing_violation(struct smb_request *req)
 {
        bool ok;
@@ -2571,6 +2607,7 @@ bool defer_smb1_sharing_violation(struct smb_request *req)
 
        ok = setup_poll_open(
                req,
+               NULL,
                (struct file_id) {0},
                (struct timeval) { .tv_usec = timeout_usecs },
                (struct timeval) { .tv_usec = 200000 });
@@ -3322,6 +3359,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                         */
                        setup_poll_open(
                                req,
+                               NULL,
                                fsp->file_id,
                                timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
                                timeval_set(1, 0));
@@ -3352,6 +3390,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                 */
                setup_poll_open(
                        req,
+                       NULL,
                        fsp->file_id,
                        timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
                        timeval_set(1, 0));