Bug 12783 - If "kernel oplocks" == yes, smbd tries to release not taken oplock when closing file
Summary: If "kernel oplocks" == yes, smbd tries to release not taken oplock when closi...
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: File services (show other bugs)
Version: 4.5.8
Hardware: All Linux
: P5 normal (vote)
Target Milestone: ---
Assignee: Samba QA Contact
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-10 13:08 UTC by Lev
Modified: 2023-01-25 17:51 UTC (History)
3 users (show)

See Also:


Attachments
Log file (831.43 KB, text/plain)
2017-05-10 13:08 UTC, Lev
no flags Details
testparm -sv (10.63 KB, text/plain)
2017-05-10 13:09 UTC, Lev
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Lev 2017-05-10 13:08:28 UTC
Created attachment 13203 [details]
Log file

Client sends create file message with oplock_request = 0x100 (LEASE_OPLOCK):

[2017/05/10 14:16:49.138101, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0)] ../source3/smbd/open.c:5336(create_file_default)
  create_file: access_mask = 0x16019f file_attributes = 0x80, share_access = 0x0, create_disposition = 0x2 create_options = 0x44 oplock_request = 0x100 private_flags = 0x0 root_dir_fid = 0x0, ea_list = 0x(nil), sd = 0x(nil), fname = New Text Document.txt
[2017/05/10 14:16:49.138125, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0)] ../source3/smbd/open.c:4809(create_file_unixpath)
  create_file_unixpath: access_mask = 0x16019f file_attributes = 0x80, share_access = 0x0, create_disposition = 0x2 create_options = 0x44 oplock_request = 0x100 private_flags = 0x0 ea_list = 0x(nil), sd = 0x(nil), fname = New Text Document.txt
[2017/05/10 14:16:49.147145, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0)] ../source3/smbd/open.c:2795(open_file_ntcreate)
  open_file_ntcreate: fname=New Text Document.txt, dos_attrs=0x80 access_mask=0x16019f share_access=0x0 create_disposition = 0x2 create_options=0x44 unix mode=0744 oplock_request=256 private_flags = 0x0
  
grant_fsp_oplock_type() sets fsp->oplock_type = LEASE_OPLOCK and granted = SMB2_LEASE_NONE:

[2017/05/10 14:16:49.152565, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0)] ../source3/smbd/open.c:2062(grant_fsp_oplock_type)
  No lease granted because kernel oplocks are enabled
[2017/05/10 14:16:49.152583, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0)] ../source3/smbd/open.c:2066(grant_fsp_oplock_type)
  No read or write lease requested
[2017/05/10 14:16:49.157844, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0)] ../source3/smbd/open.c:2138(grant_fsp_oplock_type)
  lease_state=0
[2017/05/10 14:16:49.157881, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0)] ../source3/smbd/open.c:2184(grant_fsp_oplock_type)
  grant_fsp_oplock_type: oplock type 0x100 on file New Text Document.txt
  

When the file is closed, release_file_oplock() checks that fsp->oplock_type != NO_OPLOCK, and tries to issue release_oplock:
  
[2017/05/10 14:16:49.376247, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0)] ../source3/smbd/smb2_close.c:227(smbd_smb2_close)
  smbd_smb2_close: New Text Document.txt - fnum 3013970518
[2017/05/10 14:16:49.385784, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0), class=locking] ../source3/smbd/oplock_linux.c:167(linux_release_kernel_oplock)
  linux_release_kernel_oplock: file New Text Document.txt, file_id = fd1c:83:0 gen_id = 394143052 has kernel oplock state of 2.
[2017/05/10 14:16:49.386303,  0, pid=6633, effective(1000002, 1000009), real(1000002, 0), class=locking] ../source3/smbd/oplock_linux.c:184(linux_release_kernel_oplock)
  linux_release_kernel_oplock: Error when removing kernel oplock on file New Text Document.txt, file_id = fd1c:83:0, gen_id = 394143052. Error was Resource temporarily unavailable
  
Notice that fcntl(F_GETLEASE) returned 2(F_UNLCK).



On file deletion linux_release_kernel_oplock() is also called, but here fsp->fh->fd was not opened, and remained -1. So linux_release_kernel_oplock() fails with another error:

[2017/05/10 14:16:57.812556, 10, pid=6633, effective(1000002, 1000009), real(1000002, 0), class=locking] ../source3/smbd/oplock_linux.c:167(linux_release_kernel_oplock)
  linux_release_kernel_oplock: file New Text Document.txt, file_id = fd1c:83:0 gen_id = 4142255055 has kernel oplock state of ffffffff.
[2017/05/10 14:16:57.813472,  0, pid=6633, effective(1000002, 1000009), real(1000002, 0), class=locking] ../source3/smbd/oplock_linux.c:184(linux_release_kernel_oplock)
  linux_release_kernel_oplock: Error when removing kernel oplock on file New Text Document.txt, file_id = fd1c:83:0, gen_id = 4142255055. Error was Bad file descriptor
Comment 1 Lev 2017-05-10 13:09:21 UTC
Created attachment 13204 [details]
testparm -sv
Comment 2 Jeremy Allison 2017-05-10 23:27:22 UTC
Ah, with leases we shouldn't be blundering into the remove_oplock() code. Let me take a look (good analysis BTW).
Comment 3 Ralph Böhme 2017-05-22 07:19:16 UTC
This is similar to bug #12797: we end up with SMB2 leases enabled as when doing the check against incompatible kernel oplocks we only check the global setting. As the runtime check is done at the negprot stage this can't be improved.

smb2_negprot.c:

        if (protocol >= PROTOCOL_SMB2_10 &&
            lp_smb2_leases() &&
            lp_oplocks(GLOBAL_SECTION_SNUM) &&
            !lp_kernel_oplocks(GLOBAL_SECTION_SNUM))
        {
                capabilities |= SMB2_CAP_LEASING;
        }

I can imagine only one way to address: by doing an incompatible change in 4.7 of making kernel oplocks a global option.
Comment 4 Jeremy Allison 2023-01-25 17:51:44 UTC
Yes, IMHO this is the only viable solution. If we're gating SMB2_CAP_LEASING at negprot time on a global option, we can't then allow it on a per-share basis.