diff options
author | Pavel Shilovsky <piastry@etersoft.ru> | 2011-01-31 12:00:15 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2011-01-31 12:00:15 -0800 |
commit | 7690d9d70c2425f6357732c0901d9dd18483e097 (patch) | |
tree | ea384f3e757c9256d9b41bd596483fadc4932cfa /source3/smbd | |
parent | c9027b664b42ada5a392472cfcaac1a1040cfe91 (diff) | |
download | samba-7690d9d70c2425f6357732c0901d9dd18483e097.tar.gz samba-7690d9d70c2425f6357732c0901d9dd18483e097.tar.bz2 samba-7690d9d70c2425f6357732c0901d9dd18483e097.zip |
Fix bug #7928 - Samba problems with kernel oplocks option set to "no"
We should not grant levelII oplocks on a file with existing
byte range locks.
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/open.c | 5 | ||||
-rw-r--r-- | source3/smbd/oplock.c | 35 |
2 files changed, 32 insertions, 8 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 0de70451da..5a725c6634 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -2182,7 +2182,10 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, */ if (!set_file_oplock(fsp, fsp->oplock_type)) { - /* Could not get the kernel oplock */ + /* + * Could not get the kernel oplock or there are byte-range + * locks on the file. + */ fsp->oplock_type = NO_OPLOCK; } diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index e92fbd43af..31cedc415e 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -52,19 +52,40 @@ void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp) msg, MSG_SMB_KERNEL_BREAK_SIZE); } +static bool file_has_brlocks(files_struct *fsp) +{ + struct byte_range_lock *br_lck; + + br_lck = brl_get_locks_readonly(fsp); + if (!br_lck) + return false; + + return br_lck->num_locks > 0 ? true : false; +} + /**************************************************************************** - Attempt to set an oplock on a file. Always succeeds if kernel oplocks are - disabled (just sets flags). Returns True if oplock set. + Attempt to set an oplock on a file. Succeeds if kernel oplocks are + disabled (just sets flags) and no byte-range locks in the file. Returns True + if oplock set. ****************************************************************************/ bool set_file_oplock(files_struct *fsp, int oplock_type) { - if ((fsp->oplock_type == LEVEL_II_OPLOCK) - && koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) { - DEBUG(10, ("Refusing level2 oplock, kernel oplocks don't " - "support them\n")); - return false; + if (fsp->oplock_type == LEVEL_II_OPLOCK) { + if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) { + DEBUG(10, ("Refusing level2 oplock because of " + "byte-range locks on the file\n")); + return false; + } + + if (koplocks && + !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) { + DEBUG(10, ("Refusing level2 oplock, kernel oplocks " + "don't support them\n")); + return false; + } } + if ((fsp->oplock_type != NO_OPLOCK) && (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) && koplocks && |