diff options
author | Volker Lendecke <vl@samba.org> | 2013-09-26 16:15:31 -0700 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2013-10-23 11:58:56 +0200 |
commit | 20669d4a75386eef4fdcea07fb99812c4e09de13 (patch) | |
tree | 403e4ca912e16316e21f6467cc3e02886d03f4d8 /source3/smbd/oplock.c | |
parent | ccc808e0d72be5933ae2449ee8ee56262e631b72 (diff) | |
download | samba-20669d4a75386eef4fdcea07fb99812c4e09de13.tar.gz samba-20669d4a75386eef4fdcea07fb99812c4e09de13.tar.bz2 samba-20669d4a75386eef4fdcea07fb99812c4e09de13.zip |
smbd: Fix raw.batch.exclusive[59]
The level we have to break to depend on the breakers create_disposition:
If we overwrite, we have to break to none.
This patch overloads the "op_type" field in the break message we send
across to the smbd holding the oplock with the oplock level we want to
break to. Because it depends on the create_disposition in the breaking
open, only the breaker can make that decision. We might want to use
a different mechanism for this in the future, but for now using the
op_type field seems acceptable to me.
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source3/smbd/oplock.c')
-rw-r--r-- | source3/smbd/oplock.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index e2880c5de9..f1b89b4650 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -510,6 +510,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, struct smbd_server_connection); struct server_id self = messaging_server_id(sconn->msg_ctx); struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops; + uint16_t break_to; if (data->data == NULL) { DEBUG(0, ("Got NULL buffer\n")); @@ -523,9 +524,10 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, /* De-linearize incoming message. */ message_to_share_mode_entry(&msg, (char *)data->data); + break_to = msg.op_type; - DEBUG(10, ("Got oplock break message from pid %s: %s/%llu\n", - server_id_str(talloc_tos(), &src), + DEBUG(10, ("Got oplock break to %u message from pid %s: %s/%llu\n", + (unsigned)break_to, server_id_str(talloc_tos(), &src), file_id_string_tos(&msg.id), (unsigned long long)msg.share_file_id)); @@ -545,8 +547,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, return; } - if (EXCLUSIVE_OPLOCK_TYPE(msg.op_type) && - !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { + if (break_to == fsp->oplock_type) { DEBUG(3, ("Already downgraded oplock on %s: %s\n", file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp))); @@ -556,6 +557,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && koplocks; if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && + (break_to != NO_OPLOCK) && !(use_kernel && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) && lp_level2_oplocks(SNUM(fsp->conn))) { break_to_level2 = True; |