diff options
author | Volker Lendecke <vl@samba.org> | 2019-08-18 08:55:14 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2019-08-19 23:14:38 +0000 |
commit | 706f0af2e4b5012644da742c94fc12eb756054fd (patch) | |
tree | 5e2bc9e1f7ebb3fe8307690dc7900d7aff3802d9 | |
parent | 4d6f89c9883abaf7e9152887b7fa13449579c09c (diff) | |
download | samba-706f0af2e4b5012644da742c94fc12eb756054fd.tar.gz |
smbd: Optionally wait for a share mode record in setup_poll_open()
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>
-rw-r--r-- | source3/smbd/open.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index cea3d882637..fc2df6eb0a0 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -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)); |