Getting Samba 3.6.12 and possibly 4.0.x to properly handle an OpLock Break in a compound request

Richard Sharpe realrichardsharpe at gmail.com
Wed Mar 13 20:45:24 MDT 2013


On Wed, Mar 13, 2013 at 1:24 PM, Richard Sharpe
<realrichardsharpe at gmail.com> wrote:
> Hi folks,
>
> The following ugly patch seems to allow Samba 3.6.12 to handle an
> OpLock break in a compound request.
>
> Next up I have to see if not responding with a STATUS_PENDING response matters.
>
> -bash-4.0$ diff -up
> build/cloudcc/build_x86_64/samba-3.6.12/source3/smbd/smb2_server.c
> smb2_server.c
> --- build/cloudcc/build_x86_64/samba-3.6.12/source3/smbd/smb2_server.c
>  2013-03-13 21:18:24.839321028 -0700
> +++ smb2_server.c       2013-03-13 21:14:09.827919858 -0700
> @@ -930,6 +930,7 @@ NTSTATUS smbd_smb2_request_pending_queue
>         struct iovec *outvec = NULL;
>
>         if (!tevent_req_is_in_progress(subreq)) {
> +               DEBUG(10, ("Already in progress\n"));
>                 return NT_STATUS_OK;
>         }
>
> @@ -937,10 +938,17 @@ NTSTATUS smbd_smb2_request_pending_queue
>         subreq = NULL;
>
>         if (req->async) {
> +               DEBUG(10, ("Already async"));
>                 /* We're already async. */
>                 return NT_STATUS_OK;
>         }
>
> +       if (req->smb1req && open_was_deferred_smb2(req->smb1req->sconn,
> +                                               req->smb1req->mid)) {
> +               DEBUG(10, ("Open Request was deferred ... doing nothing\n"));
> +               return NT_STATUS_OK;
> +       }
> +
>         if (req->in.vector_count > i + 3) {
>                 /*
>                  * We're trying to go async in a compound
>

OK, this is a better fix. It doesn't break notify :-)

--- samba-3.6.12.orig/source3/smbd/smb2_create.c 2012-06-24
10:21:16.000000000 -0700
+++ samba-3.6.12/source3/smbd/smb2_create.c      2013-03-14
01:00:44.575614048 -0700
@@ -244,7 +244,18 @@ NTSTATUS smbd_smb2_request_process_creat
        }
        tevent_req_set_callback(tsubreq,
smbd_smb2_request_create_done, smb2req);

-       return smbd_smb2_request_pending_queue(smb2req, tsubreq);
+       /*
+        * If the open was deferred, then do not call request pending queue
+        * because that means an OpLock break has occurred and we want to
+        * wait.
+        */
+       if (smb2req->smb1req && open_was_deferred_smb2(smb2req->smb1req->sconn,
+                                               smb2req->smb1req->mid)) {
+               DEBUG(10, ("Deferred request (OpLock Break) ... doing
nothing\n"));
+               return NT_STATUS_OK;
+       }
+       else
+               return smbd_smb2_request_pending_queue(smb2req, tsubreq);
 }


-- 
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)


More information about the samba-technical mailing list