summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/open.c5
-rw-r--r--source3/smbd/oplock.c35
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 &&