smbd: Fix retry for kernel-oplocked files
authorVolker Lendecke <vl@samba.org>
Tue, 30 Jul 2019 10:24:53 +0000 (12:24 +0200)
committerJeremy Allison <jra@samba.org>
Wed, 31 Jul 2019 00:12:34 +0000 (00:12 +0000)
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 <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Wed Jul 31 00:12:34 UTC 2019 on sn-devel-184

selftest/knownfail
source3/smbd/open.c

index 99772b45c4db23efa9291a390abd815829b3f715..ded80b12259efcaf671a7262c89a6ba592bfbe1e 100644 (file)
@@ -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
index 6838354a7d496e8c43205a784743a1355b364b9a..8fcd7b3b580006590f8d836d589f83334bdf5ea9 100644 (file)
@@ -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");
        }