From: Volker Lendecke Date: Tue, 30 Jul 2019 10:24:53 +0000 (+0200) Subject: smbd: Fix retry for kernel-oplocked files X-Git-Tag: tdb-1.4.2~394 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b590e16bcb4f4e1f1f0bf049a863db38e634beb;p=thirdparty%2Fsamba.git smbd: Fix retry for kernel-oplocked files This now removed comment describes the bug correctly: /* * As this timer event is owned by req, it will * disappear if req it talloc_freed. */ In smb1, "req" disappears once the reply_whatever routine is done. Thus the timer goes away and we never look at "req" again. This change moves the valid data (xconn and mid) to deferred_open_record, and changes the talloc hierarchy such that the timer is now a child of open_rec, which is a child of the deferred message. Bug: https://bugzilla.samba.org/show_bug.cgi?id=14060 Signed-off-by: Volker Lendecke Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Wed Jul 31 00:12:34 UTC 2019 on sn-devel-184 --- diff --git a/selftest/knownfail b/selftest/knownfail index 99772b45c4d..ded80b12259 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -15,7 +15,6 @@ ^samba3.smbtorture_s3.crypt_server # expected to give ACCESS_DENIED as SMB1 encryption isn't used ^samba3.smbtorture_s3.*.LOCK12.*\(fileserver\) ^samba3.smbtorture_s3.*.LOCK12.*\(nt4_dc\) -^samba3.smbtorture_s3.*.OPLOCK5.*\(fileserver\) ^samba3.nbt.dgram.*netlogon2\(nt4_dc\) ^samba3.*rap.sam.*.useradd # Not provided by Samba 3 ^samba3.*rap.sam.*.userdelete # Not provided by Samba 3 diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 6838354a7d4..8fcd7b3b580 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -44,6 +44,9 @@ extern const struct generic_mapping file_generic_mapping; struct deferred_open_record { + struct smbXsrv_connection *xconn; + uint64_t mid; + bool delayed_for_oplocks; bool async_open; struct file_id id; @@ -2504,10 +2507,12 @@ static void kernel_oplock_poll_open_timer(struct tevent_context *ev, struct timeval current_time, void *private_data) { + struct deferred_open_record *open_rec = talloc_get_type_abort( + private_data, struct deferred_open_record); bool ok; - struct smb_request *req = (struct smb_request *)private_data; - ok = schedule_deferred_open_message_smb(req->xconn, req->mid); + ok = schedule_deferred_open_message_smb( + open_rec->xconn, open_rec->mid); if (!ok) { exit_server("schedule_deferred_open_message_smb failed"); } @@ -2535,6 +2540,8 @@ static void setup_kernel_oplock_poll_open(struct timeval request_time, if (open_rec == NULL) { exit_server("talloc failed"); } + open_rec->xconn = req->xconn; + open_rec->mid = req->mid; ok = push_deferred_open_message_smb(req, request_time, @@ -2545,15 +2552,11 @@ static void setup_kernel_oplock_poll_open(struct timeval request_time, exit_server("push_deferred_open_message_smb failed"); } - /* - * As this timer event is owned by req, it will - * disappear if req it talloc_freed. - */ open_rec->te = tevent_add_timer(req->sconn->ev_ctx, - req, + open_rec, timeval_current_ofs(1, 0), kernel_oplock_poll_open_timer, - req); + open_rec); if (open_rec->te == NULL) { exit_server("tevent_add_timer failed"); }