From 17eba16bad9b20518a5d336bc751e749a587ec68 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 3 Feb 2009 15:40:23 -0800 Subject: s3 oplocks: Add capabilites flags field to the kernel_oplocks struct Here is a short description for each of the new capability flags: KOPLOCKS_LEVEL2_SUPPORTED: Level 2 oplocks are supported natively in the kernel. KOPLOCKS_DEFERRED_OPEN_NOTIFICATION: The kernel notifies deferred openers when they can retry the open. KOPLOCKS_TIMEOUT_NOTIFICATION: The kernel notifies smbds when an oplock break times out. KOPLOCKS_OPLOCK_BROKEN_NOTIFICATION: The kernel notifies smbds when an oplock is broken. --- source3/smbd/oplock.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'source3/smbd/oplock.c') 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; inum_pending_break_messages; i++) { struct share_mode_entry *e = &fsp->pending_break_messages[i]; char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE]; -- cgit