[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha6-710-g9a7491e

Tim Prouty tprouty at samba.org
Tue Feb 10 07:54:48 GMT 2009


The branch, master has been updated
       via  9a7491e83177ba32e30f29e1b84b8b8be9888953 (commit)
       via  16d2c2fa58c57539a9b540eb93825806caaea0b5 (commit)
       via  32d68b8ec3aee7853c7547296e829277515813d1 (commit)
       via  17eba16bad9b20518a5d336bc751e749a587ec68 (commit)
       via  c6f1f055fdeee29ad7c5b2ae9909e8f1b1a7daec (commit)
       via  9c1310fa6ae1a67dc0fea3bf549d805ff167e78f (commit)
       via  122dbbf00acc1768f98e5b57e94aab2b61671f40 (commit)
      from  fe5b0b595c926aea0916541ceeaf610bc018cb63 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 9a7491e83177ba32e30f29e1b84b8b8be9888953
Author: Tim Prouty <tprouty at samba.org>
Date:   Wed Feb 4 17:28:21 2009 -0800

    s3 OneFS: Change ACLs to do a stat-only open before get/set_security_descriptor
    
    This ensures that getting/stting a security descriptor does not
    contend an oplock.  The correct access checks will be still be done in
    the kernel on the get/set rather than the open.

commit 16d2c2fa58c57539a9b540eb93825806caaea0b5
Author: Tim Prouty <tprouty at samba.org>
Date:   Tue Jan 27 16:13:35 2009 -0800

    s3 OneFS: Add kernel oplocks implementation
    
    A few functions in oplocks_onefs.c need to be accessed from the onefs
    vfs module.  It would be ideal if oplocks were implemented at the vfs
    layer, but since they aren't yet, a new header is added to
    source3/include to make these functions available to the onefs vfs
    module.  oplocks_onefs.o doesn't need to be linked into the onefs vfs
    module explicitly, since it is already linked into smbd by default.

commit 32d68b8ec3aee7853c7547296e829277515813d1
Author: Tim Prouty <tprouty at samba.org>
Date:   Tue Feb 3 23:17:48 2009 -0800

    s3 oplocks: Remove oplocks before handling delete on close semantics
    
    Unlinking a file while still holding an oplock can cause problems with
    kernel oplocks.  This simply releases the oplock before actually
    unlinking the file.

commit 17eba16bad9b20518a5d336bc751e749a587ec68
Author: Tim Prouty <tprouty at samba.org>
Date:   Tue Feb 3 15:40:23 2009 -0800

    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.

commit c6f1f055fdeee29ad7c5b2ae9909e8f1b1a7daec
Author: Tim Prouty <tprouty at samba.org>
Date:   Tue Feb 3 11:56:35 2009 -0800

    s3 oplocks: Make the level2 oplock contention API more granular
    
    This replaces release_level2_oplocks_on_change with
    contend_level2_oplock_begin/end in order to contend level2 oplocks
    throughout an operation rather than just at the begining.  This is
    necessary for some kernel oplock implementations, and also lays the
    groundwork for better correctness in Samba's standard level2 oplock
    handling.  The next step for non-kernel oplocks is to add additional
    state to the share mode lock struct that prevents any new opens from
    granting oplocks while a contending operation is in progress.
    
    All operations that contend level 2 oplocks are now correctly spanned
    except for aio and synchronous writes.  The two write paths both have
    non-trivial error paths that need extra care to get right.
    
    RAW-OPLOCK and the rest of 'make test' are still passing with this
    change.

commit 9c1310fa6ae1a67dc0fea3bf549d805ff167e78f
Author: Tim Prouty <tprouty at samba.org>
Date:   Fri Jan 9 13:07:58 2009 -0800

    s3 oplocks: Differentiate between releasing an oplock vs. downgrading to Level 2 for kernel oplocks
    
    Pass in an extra argument when releasing an oplock so kernel oplock
    implementations can support downgrading from Level 1 to Level 2.

commit 122dbbf00acc1768f98e5b57e94aab2b61671f40
Author: Tim Prouty <tprouty at samba.org>
Date:   Sat Jan 31 20:51:04 2009 -0800

    s3 vfs: Add a destructor to the fsp extension data API
    
    I'm not certain if the dummy pointer is needed in struct vfs_fsp_data,
    but I added it to be consistent with the comment below.

-----------------------------------------------------------------------

Summary of changes:
 source3/Makefile.in                 |    2 +-
 source3/configure.in                |    2 +
 source3/include/oplock_onefs.h      |   50 +++
 source3/include/proto.h             |   19 +-
 source3/include/smb.h               |   37 ++-
 source3/include/vfs.h               |    4 +-
 source3/lib/dummysmbd.c             |   19 +
 source3/locking/brlock.c            |   85 ++++-
 source3/modules/onefs.h             |    2 +-
 source3/modules/onefs_acl.c         |   26 +-
 source3/modules/onefs_open.c        |  155 ++++++--
 source3/modules/onefs_system.c      |   58 +---
 source3/modules/vfs_cacheprime.c    |    2 +-
 source3/modules/vfs_commit.c        |    2 +-
 source3/modules/vfs_prealloc.c      |    2 +-
 source3/modules/vfs_streams_xattr.c |    3 +-
 source3/smbd/aio.c                  |    4 +-
 source3/smbd/close.c                |   13 +-
 source3/smbd/fileio.c               |    4 +-
 source3/smbd/oplock.c               |   66 +++-
 source3/smbd/oplock_irix.c          |    8 +-
 source3/smbd/oplock_linux.c         |    8 +-
 source3/smbd/oplock_onefs.c         |  798 +++++++++++++++++++++++++++++++++++
 source3/smbd/reply.c                |   11 -
 source3/smbd/vfs.c                  |   41 ++-
 25 files changed, 1258 insertions(+), 163 deletions(-)
 create mode 100644 source3/include/oplock_onefs.h
 create mode 100644 source3/smbd/oplock_onefs.c


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 942c5b3..2049953 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -620,7 +620,7 @@ PROFILES_OBJ = utils/profiles.o \
                $(LIB_OBJ) $(LIB_DUMMY_OBJ) \
                $(POPT_LIB_OBJ)
 
-OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o
+OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o smbd/oplock_onefs.o
 
 NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o
 
diff --git a/source3/configure.in b/source3/configure.in
index b81e768..10ce6f6 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -1099,6 +1099,8 @@ if test x"$samba_cv_HAVE_ONEFS" = x"yes"; then
     AC_DEFINE(HAVE_ONEFS,1,[Whether building on Isilon OneFS])
     default_shared_modules="$default_shared_modules vfs_onefs perfcount_onefs"
     ONEFS_LIBS="-lisi_acl"
+    # Need to also add general libs for oplocks support
+    save_LIBS="$save_LIBS -lisi_ecs -lisi_event -lisi_util -ldevstat"
 fi
 AC_SUBST(ONEFS_LIBS)
 LIBS="$save_LIBS"
diff --git a/source3/include/oplock_onefs.h b/source3/include/oplock_onefs.h
new file mode 100644
index 0000000..a20becd
--- /dev/null
+++ b/source3/include/oplock_onefs.h
@@ -0,0 +1,50 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Support for OneFS kernel oplocks
+ *
+ * Copyright (C) Tim Prouty, 2009
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _OPLOCK_ONEFS_H
+#define _OPLOCK_ONEFS_H
+
+#if HAVE_ONEFS
+
+#include <sys/isi_oplock.h>
+
+struct deferred_open_record {
+	bool delayed_for_oplocks;
+	bool failed; /* added for onefs_oplocks */
+	struct file_id id;
+};
+
+/*
+ * OneFS oplock utility functions
+ */
+const char *onefs_oplock_str(enum oplock_type onefs_oplock_type);
+int onefs_oplock_to_samba_oplock(enum oplock_type onefs_oplock);
+enum oplock_type onefs_samba_oplock_to_oplock(int samba_oplock_type);
+
+/*
+ * OneFS oplock callback tracking
+ */
+void destroy_onefs_callback_record(uint64 id);
+uint64 onefs_oplock_wait_record(uint16 mid);
+void onefs_set_oplock_callback(uint64 id, files_struct *fsp);
+
+#endif /* HAVE_ONEFS */
+
+#endif /* _OPLOCK_ONEFS_H */
diff --git a/source3/include/proto.h b/source3/include/proto.h
index e5dbe60..1566a01 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6898,8 +6898,17 @@ bool set_file_oplock(files_struct *fsp, int oplock_type);
 void release_file_oplock(files_struct *fsp);
 bool remove_oplock(files_struct *fsp);
 bool downgrade_oplock(files_struct *fsp);
+bool should_notify_deferred_opens(void);
 void reply_to_oplock_break_requests(files_struct *fsp);
-void release_level_2_oplocks_on_change(files_struct *fsp);
+void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx,
+						      void *private_data,
+						      uint32_t msg_type,
+						      struct server_id src,
+						      DATA_BLOB *data);
+void contend_level2_oplocks_begin(files_struct *fsp,
+				  enum level2_contention_type type);
+void contend_level2_oplocks_end(files_struct *fsp,
+				enum level2_contention_type type);
 void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e);
 void message_to_share_mode_entry(struct share_mode_entry *e, char *msg);
 bool init_oplocks(struct messaging_context *msg_ctx);
@@ -6915,6 +6924,10 @@ int linux_set_lease_sighandler(int fd);
 int linux_setlease(int fd, int leasetype);
 struct kernel_oplocks *linux_init_kernel_oplocks(TALLOC_CTX *mem_ctx) ;
 
+/* The following definitions come from smbd/oplock_onefs.c  */
+
+struct kernel_oplocks *onefs_init_kernel_oplocks(TALLOC_CTX *mem_ctx);
+
 /* The following definitions come from smbd/password.c  */
 
 user_struct *get_valid_user_struct(uint16 vuid);
@@ -7317,7 +7330,9 @@ void sys_utmp_claim(const char *username, const char *hostname,
 
 NTSTATUS smb_register_vfs(int version, const char *name, const vfs_op_tuple *vfs_op_tuples);
 bool vfs_init_custom(connection_struct *conn, const char *vfs_object);
-void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle, files_struct *fsp, size_t ext_size);
+void *vfs_add_fsp_extension_notype(vfs_handle_struct *handle,
+				   files_struct *fsp, size_t ext_size,
+				   void (*destroy_fn)(void *p_data));
 void vfs_remove_fsp_extension(vfs_handle_struct *handle, files_struct *fsp);
 void *vfs_memctx_fsp_extension(vfs_handle_struct *handle, files_struct *fsp);
 void *vfs_fetch_fsp_extension(vfs_handle_struct *handle, files_struct *fsp);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 3da63cf..bef0fd1 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -373,7 +373,9 @@ struct rpc_cli_smbd_conn;
 struct vfs_fsp_data {
     struct vfs_fsp_data *next;
     struct vfs_handle_struct *owner;
-    /* NOTE: This structure contains two pointers so that we can guarantee
+    void (*destroy)(void *p_data);
+    void *_dummy_;
+    /* NOTE: This structure contains four pointers so that we can guarantee
      * that the end of the structure is always both 4-byte and 8-byte aligned.
      */
 };
@@ -1687,19 +1689,50 @@ enum smbd_capability {
     LEASE_CAPABILITY
 };
 
+/*
+ * Kernel oplocks capability flags.
+ */
+
+/* Level 2 oplocks are supported natively by kernel oplocks. */
+#define KOPLOCKS_LEVEL2_SUPPORTED		0x1
+
+/* The kernel notifies deferred openers when they can retry the open. */
+#define KOPLOCKS_DEFERRED_OPEN_NOTIFICATION	0x2
+
+/* The kernel notifies smbds when an oplock break times out. */
+#define KOPLOCKS_TIMEOUT_NOTIFICATION		0x4
+
+/* The kernel notifies smbds when an oplock is broken. */
+#define KOPLOCKS_OPLOCK_BROKEN_NOTIFICATION	0x8
+
 struct kernel_oplocks_ops;
 struct kernel_oplocks {
 	const struct kernel_oplocks_ops *ops;
+	uint32_t flags;
 	void *private_data;
 };
 
+enum level2_contention_type {
+	LEVEL2_CONTEND_ALLOC_SHRINK,
+	LEVEL2_CONTEND_ALLOC_GROW,
+	LEVEL2_CONTEND_SET_FILE_LEN,
+	LEVEL2_CONTEND_FILL_SPARSE,
+	LEVEL2_CONTEND_WRITE,
+	LEVEL2_CONTEND_WINDOWS_BRL,
+	LEVEL2_CONTEND_POSIX_BRL
+};
+
 /* if a kernel does support oplocks then a structure of the following
    typee is used to describe how to interact with the kernel */
 struct kernel_oplocks_ops {
 	bool (*set_oplock)(struct kernel_oplocks *ctx,
 			   files_struct *fsp, int oplock_type);
 	void (*release_oplock)(struct kernel_oplocks *ctx,
-			       files_struct *fsp);
+			       files_struct *fsp, int oplock_type);
+	void (*contend_level2_oplocks_begin)(files_struct *fsp,
+					     enum level2_contention_type type);
+	void (*contend_level2_oplocks_end)(files_struct *fsp,
+					   enum level2_contention_type type);
 };
 
 #include "smb_macros.h"
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index e9115ab..228f090 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -679,8 +679,8 @@ typedef struct vfs_statvfs_struct {
 /* Add a new FSP extension of the given type. Returns a pointer to the
  * extenstion data.
  */
-#define VFS_ADD_FSP_EXTENSION(handle, fsp, type) \
-    vfs_add_fsp_extension_notype(handle, (fsp), sizeof(type))
+#define VFS_ADD_FSP_EXTENSION(handle, fsp, type, destroy_fn)		\
+    vfs_add_fsp_extension_notype(handle, (fsp), sizeof(type), (destroy_fn))
 
 /* Return a pointer to the existing FSP extension data. */
 #define VFS_FETCH_FSP_EXTENSION(handle, fsp) \
diff --git a/source3/lib/dummysmbd.c b/source3/lib/dummysmbd.c
index 5c624bd..a41e6dc 100644
--- a/source3/lib/dummysmbd.c
+++ b/source3/lib/dummysmbd.c
@@ -66,3 +66,22 @@ struct messaging_context *smbd_messaging_context(void)
 {
 	return NULL;
 }
+
+/**
+ * The following two functions need to be called from inside the low-level BRL
+ * code for oplocks correctness in smbd.  Since other utility binaries also
+ * link in some of the brl code directly, these dummy functions are necessary
+ * to avoid needing to link in the oplocks code and its dependencies to all of
+ * the utility binaries.
+ */
+void contend_level2_oplocks_begin(files_struct *fsp,
+				  enum level2_contention_type type)
+{
+	return;
+}
+
+void contend_level2_oplocks_end(files_struct *fsp,
+				enum level2_contention_type type)
+{
+	return;
+}
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index 032aaa5..76496d1 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -311,6 +311,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
 	unsigned int i;
 	files_struct *fsp = br_lck->fsp;
 	struct lock_struct *locks = br_lck->lock_data;
+	NTSTATUS status;
 
 	for (i=0; i < br_lck->num_locks; i++) {
 		/* Do any Windows or POSIX locks conflict ? */
@@ -327,6 +328,10 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
 #endif
 	}
 
+	if (!IS_PENDING_LOCK(plock->lock_type)) {
+		contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_WINDOWS_BRL);
+	}
+
 	/* We can get the Windows lock, now see if it needs to
 	   be mapped into a lower level POSIX one, and if so can
 	   we get it ? */
@@ -346,9 +351,11 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
 			plock->context.smbpid = 0xFFFFFFFF;
 
 			if (errno_ret == EACCES || errno_ret == EAGAIN) {
-				return NT_STATUS_FILE_LOCK_CONFLICT;
+				status = NT_STATUS_FILE_LOCK_CONFLICT;
+				goto fail;
 			} else {
-				return map_nt_error_from_unix(errno);
+				status = map_nt_error_from_unix(errno);
+				goto fail;
 			}
 		}
 	}
@@ -356,7 +363,8 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
 	/* no conflicts - add it to the list of locks */
 	locks = (struct lock_struct *)SMB_REALLOC(locks, (br_lck->num_locks + 1) * sizeof(*locks));
 	if (!locks) {
-		return NT_STATUS_NO_MEMORY;
+		status = NT_STATUS_NO_MEMORY;
+		goto fail;
 	}
 
 	memcpy(&locks[br_lck->num_locks], plock, sizeof(struct lock_struct));
@@ -365,6 +373,11 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
 	br_lck->modified = True;
 
 	return NT_STATUS_OK;
+ fail:
+	if (!IS_PENDING_LOCK(plock->lock_type)) {
+		contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_WINDOWS_BRL);
+	}
+	return status;
 }
 
 /****************************************************************************
@@ -587,11 +600,13 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
 			       struct byte_range_lock *br_lck,
 			       struct lock_struct *plock)
 {
-	unsigned int i, count;
+	unsigned int i, count, posix_count;
 	struct lock_struct *locks = br_lck->lock_data;
 	struct lock_struct *tp;
 	bool lock_was_added = False;
 	bool signal_pending_read = False;
+	bool break_oplocks = false;
+	NTSTATUS status;
 
 	/* No zero-zero locks for POSIX. */
 	if (plock->start == 0 && plock->size == 0) {
@@ -613,7 +628,7 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
 		return NT_STATUS_NO_MEMORY;
 	}
 	
-	count = 0;
+	count = posix_count = 0;
 	for (i=0; i < br_lck->num_locks; i++) {
 		struct lock_struct *curr_lock = &locks[i];
 
@@ -637,6 +652,8 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
 			memcpy(&tp[count], curr_lock, sizeof(struct lock_struct));
 			count++;
 		} else {
+			unsigned int tmp_count;
+
 			/* POSIX conflict semantics are different. */
 			if (brl_conflict_posix(curr_lock, plock)) {
 				/* Can't block ourselves with POSIX locks. */
@@ -648,10 +665,27 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
 			}
 
 			/* Work out overlaps. */
-			count += brlock_posix_split_merge(&tp[count], curr_lock, plock, &lock_was_added);
+			tmp_count += brlock_posix_split_merge(&tp[count], curr_lock, plock, &lock_was_added);
+			posix_count += tmp_count;
+			count += tmp_count;
 		}
 	}
 
+	/*
+	 * Break oplocks while we hold a brl. Since lock() and unlock() calls
+	 * are not symetric with POSIX semantics, we cannot guarantee our
+	 * contend_level2_oplocks_begin/end calls will be acquired and
+	 * released one-for-one as with Windows semantics. Therefore we only
+	 * call contend_level2_oplocks_begin if this is the first POSIX brl on
+	 * the file.
+	 */
+	break_oplocks = (!IS_PENDING_LOCK(plock->lock_type) &&
+			 posix_count == 0);
+	if (break_oplocks) {
+		contend_level2_oplocks_begin(br_lck->fsp,
+					     LEVEL2_CONTEND_POSIX_BRL);
+	}
+
 	if (!lock_was_added) {
 		memcpy(&tp[count], plock, sizeof(struct lock_struct));
 		count++;
@@ -679,10 +713,12 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
 
 			if (errno_ret == EACCES || errno_ret == EAGAIN) {
 				SAFE_FREE(tp);
-				return NT_STATUS_FILE_LOCK_CONFLICT;
+				status = NT_STATUS_FILE_LOCK_CONFLICT;
+				goto fail;
 			} else {
 				SAFE_FREE(tp);
-				return map_nt_error_from_unix(errno);
+				status = map_nt_error_from_unix(errno);
+				goto fail;
 			}
 		}
 	}
@@ -690,7 +726,8 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
 	/* Realloc so we don't leak entries per lock call. */
 	tp = (struct lock_struct *)SMB_REALLOC(tp, count * sizeof(*locks));
 	if (!tp) {
-		return NT_STATUS_NO_MEMORY;
+		status = NT_STATUS_NO_MEMORY;
+		goto fail;
 	}
 	br_lck->num_locks = count;
 	SAFE_FREE(br_lck->lock_data);
@@ -723,6 +760,12 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
 	}
 
 	return NT_STATUS_OK;
+ fail:
+	if (break_oplocks) {
+		contend_level2_oplocks_end(br_lck->fsp,
+					   LEVEL2_CONTEND_POSIX_BRL);
+	}
+	return status;
 }
 
 /****************************************************************************
@@ -881,6 +924,7 @@ static bool brl_unlock_windows(struct messaging_context *msg_ctx,
 		}
 	}
 
+	contend_level2_oplocks_end(br_lck->fsp, LEVEL2_CONTEND_WINDOWS_BRL);
 	return True;
 }
 
@@ -892,7 +936,7 @@ static bool brl_unlock_posix(struct messaging_context *msg_ctx,
 			     struct byte_range_lock *br_lck,
 			     const struct lock_struct *plock)
 {
-	unsigned int i, j, count;
+	unsigned int i, j, count, posix_count;
 	struct lock_struct *tp;
 	struct lock_struct *locks = br_lck->lock_data;
 	bool overlap_found = False;
@@ -919,7 +963,7 @@ static bool brl_unlock_posix(struct messaging_context *msg_ctx,
 		return False;
 	}
 
-	count = 0;
+	count = posix_count = 0;
 	for (i = 0; i < br_lck->num_locks; i++) {
 		struct lock_struct *lock = &locks[i];
 		struct lock_struct tmp_lock[3];
@@ -946,6 +990,7 @@ static bool brl_unlock_posix(struct messaging_context *msg_ctx,
 				/* No change in this lock. */
 				memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct));
 				count++;
+				posix_count++;
 			} else {
 				SMB_ASSERT(tmp_lock[0].lock_type == UNLOCK_LOCK);
 				overlap_found = True;
@@ -970,6 +1015,7 @@ static bool brl_unlock_posix(struct messaging_context *msg_ctx,
 				}
 			}
 			count++;
+			posix_count++;
 			continue;
 		} else {
 			/* tmp_count == 3 - (we split a lock range in two). */
@@ -979,8 +1025,10 @@ static bool brl_unlock_posix(struct messaging_context *msg_ctx,
 
 			memcpy(&tp[count], &tmp_lock[0], sizeof(struct lock_struct));
 			count++;
+			posix_count++;
 			memcpy(&tp[count], &tmp_lock[2], sizeof(struct lock_struct));
 			count++;
+			posix_count++;
 			overlap_found = True;
 			/* Optimisation... */
 			/* We know we're finished here as we can't overlap any
@@ -1024,6 +1072,11 @@ static bool brl_unlock_posix(struct messaging_context *msg_ctx,
 		tp = NULL;
 	}
 
+	if (posix_count == 0) {
+		contend_level2_oplocks_end(br_lck->fsp,
+					   LEVEL2_CONTEND_POSIX_BRL);
+	}
+
 	br_lck->num_locks = count;
 	SAFE_FREE(br_lck->lock_data);
 	locks = tp;
@@ -1276,6 +1329,7 @@ void brl_close_fnum(struct messaging_context *msg_ctx,
 	struct lock_struct *locks = br_lck->lock_data;
 	struct server_id pid = procid_self();
 	bool unlock_individually = False;
+	bool posix_level2_contention_ended = false;
 
 	if(lp_posix_locking(fsp->conn->params)) {
 
@@ -1346,8 +1400,17 @@ void brl_close_fnum(struct messaging_context *msg_ctx,
 			if ((lock->lock_flav == WINDOWS_LOCK) && (lock->fnum == fnum)) {
 				del_this_lock = True;
 				num_deleted_windows_locks++;
+				contend_level2_oplocks_end(br_lck->fsp,
+				    LEVEL2_CONTEND_WINDOWS_BRL);
 			} else if (lock->lock_flav == POSIX_LOCK) {
 				del_this_lock = True;
+
+				/* Only end level2 contention once for posix */
+				if (!posix_level2_contention_ended) {
+					posix_level2_contention_ended = true;
+					contend_level2_oplocks_end(br_lck->fsp,
+					    LEVEL2_CONTEND_POSIX_BRL);
+				}
 			}
 		}
 
diff --git a/source3/modules/onefs.h b/source3/modules/onefs.h
index 2044ebe..c8f19f4 100644
--- a/source3/modules/onefs.h
+++ b/source3/modules/onefs.h
@@ -22,7 +22,7 @@
 #define _ONEFS_H
 
 #include "includes.h"
-
+#include "oplock_onefs.h"
 #include <sys/isi_acl.h>
 
 /* OneFS Module smb.conf parameters and defaults */
diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c


-- 
Samba Shared Repository


More information about the samba-cvs mailing list