diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/close.c | 4 | ||||
-rw-r--r-- | source3/smbd/oplock.c | 30 |
2 files changed, 32 insertions, 2 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c index 2fb8ec2bb5..e484fa8e01 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -134,6 +134,10 @@ static NTSTATUS close_filestruct(files_struct *fsp) static void notify_deferred_opens(struct share_mode_lock *lck) { int i; + + if (!should_notify_deferred_opens()) { + return; + } for (i=0; i<lck->num_share_modes; i++) { struct share_mode_entry *e = &lck->share_modes[i]; diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 4c84fd41ed..a6ec9cfa2d 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -188,6 +188,15 @@ bool downgrade_oplock(files_struct *fsp) return ret; } +/* + * Some kernel oplock implementations handle the notification themselves. + */ +bool should_notify_deferred_opens() +{ + return !(koplocks && + (koplocks->flags & KOPLOCKS_DEFERRED_OPEN_NOTIFICATION)); +} + /**************************************************************************** Set up an oplock break message. ****************************************************************************/ @@ -306,6 +315,15 @@ static void oplock_timeout_handler(struct event_context *ctx, static void add_oplock_timeout_handler(files_struct *fsp) { + /* + * If kernel oplocks already notifies smbds when an oplock break times + * out, just return. + */ + if (koplocks && + (koplocks->flags & KOPLOCKS_TIMEOUT_NOTIFICATION)) { + return; + } + if (fsp->oplock_timeout != NULL) { DEBUG(0, ("Logic problem -- have an oplock event hanging " "around\n")); @@ -491,8 +509,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && !(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) && - !koplocks && /* NOTE: we force levelII off for kernel oplocks - - * this will change when it is supported */ + !(koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) && lp_level2_oplocks(SNUM(fsp->conn))) { break_to_level2 = True; } @@ -613,6 +630,15 @@ void reply_to_oplock_break_requests(files_struct *fsp) { int i; + /* + * If kernel oplocks already notifies smbds when oplocks are + * broken/removed, just return. + */ + if (koplocks && + (koplocks->flags & KOPLOCKS_OPLOCK_BROKEN_NOTIFICATION)) { + return; + } + for (i=0; i<fsp->num_pending_break_messages; i++) { struct share_mode_entry *e = &fsp->pending_break_messages[i]; char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; |