[SCM] Samba Shared Repository - branch v3-4-test updated - release-4-0-0alpha7-660-gf922e22

Tim Prouty tprouty at samba.org
Mon Apr 6 22:31:13 GMT 2009


The branch, v3-4-test has been updated
       via  f922e22d907d4a99e91f00f001c05b2b35d73a26 (commit)
       via  4e091804b86ae9b8318b985d39e826366681e21b (commit)
      from  bd3f30d1dac3febd69c1c9266ca52dc836a92632 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-4-test


- Log -----------------------------------------------------------------
commit f922e22d907d4a99e91f00f001c05b2b35d73a26
Author: Tim Prouty <tprouty at samba.org>
Date:   Thu Apr 2 18:24:43 2009 -0700

    s3 onefs: Simplify level 2 oplock self-contention
    
    This removes all oplock dependence on locking.tdb
    (cherry picked from commit 9d2d07503a17971a63153ecc13fdddb763e614b8)

commit 4e091804b86ae9b8318b985d39e826366681e21b
Author: Tim Prouty <tprouty at samba.org>
Date:   Thu Apr 2 18:33:30 2009 -0700

    s3 oplocks: Refactor level II oplock contention
    
    (cherry picked from commit 651fa0964a6c49a071c28cdb1e4891b1d95d5b09)

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

Summary of changes:
 source3/include/proto.h     |    1 +
 source3/smbd/oplock.c       |  122 +++++++++++++++++++++----------------------
 source3/smbd/oplock_onefs.c |   79 ++--------------------------
 3 files changed, 65 insertions(+), 137 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 48ec64c..0ea7106 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6632,6 +6632,7 @@ 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 break_level2_to_none_async(files_struct *fsp);
 void reply_to_oplock_break_requests(files_struct *fsp);
 void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx,
 						      void *private_data,
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 427eb5d..3b6d4a3 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -344,62 +344,23 @@ static void add_oplock_timeout_handler(files_struct *fsp)
 	}
 }
 
-/*******************************************************************
- This handles the case of a write triggering a break to none
- message on a level2 oplock.
- When we get this message we may be in any of three states :
- NO_OPLOCK, LEVEL_II, FAKE_LEVEL2. We only send a message to
- the client for LEVEL2.
-*******************************************************************/
-
-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 break_level2_to_none_async(files_struct *fsp)
 {
-	struct share_mode_entry msg;
-	files_struct *fsp;
 	char *break_msg;
 	bool sign_state;
 
-	if (data->data == NULL) {
-		DEBUG(0, ("Got NULL buffer\n"));
-		return;
-	}
-
-	if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
-		DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
-		return;
-	}
-
-	/* De-linearize incoming message. */
-	message_to_share_mode_entry(&msg, (char *)data->data);
-
-	DEBUG(10, ("Got oplock async level 2 break message from pid %s: "
-		   "%s/%lu\n", procid_str(debug_ctx(), &src),
-		   file_id_string_tos(&msg.id), msg.share_file_id));
-
-	fsp = initial_break_processing(msg.id, msg.share_file_id);
-
-	if (fsp == NULL) {
-		/* We hit a race here. Break messages are sent, and before we
-		 * get to process this message, we have closed the file. 
-		 * No need to reply as this is an async message. */
-		DEBUG(3, ("process_oplock_async_level2_break_message: Did not find fsp, ignoring\n"));
-		return;
-	}
-
 	if (fsp->oplock_type == NO_OPLOCK) {
-		/* We already got a "break to none" message and we've handled it.
-		 * just ignore. */
-		DEBUG(3, ("process_oplock_async_level2_break_message: already broken to none, ignoring.\n"));
+		/* We already got a "break to none" message and we've handled
+		 * it.  just ignore. */
+		DEBUG(3, ("process_oplock_async_level2_break_message: already "
+			  "broken to none, ignoring.\n"));
 		return;
 	}
 
 	if (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
 		/* Don't tell the client, just downgrade. */
-		DEBUG(3, ("process_oplock_async_level2_break_message: downgrading fake level 2 oplock.\n"));
+		DEBUG(3, ("process_oplock_async_level2_break_message: "
+			  "downgrading fake level 2 oplock.\n"));
 		remove_oplock(fsp);
 		return;
 	}
@@ -407,23 +368,16 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
 	/* Ensure we're really at level2 state. */
 	SMB_ASSERT(fsp->oplock_type == LEVEL_II_OPLOCK);
 
-	DEBUG(10,("process_oplock_async_level2_break_message: sending break to "
-		"none message for fid %d, file %s\n",
-		fsp->fnum,
-		fsp->fsp_name));
+	DEBUG(10,("process_oplock_async_level2_break_message: sending break "
+		  "to none message for fid %d, file %s\n", fsp->fnum,
+		  fsp->fsp_name));
 
 	/* Now send a break to none message to our client. */
-
 	break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE);
 	if (break_msg == NULL) {
 		exit_server("Could not talloc break_msg\n");
 	}
 
-	/* Need to wait before sending a break message if we sent ourselves this message. */
-	if (procid_is_me(&src)) {
-		wait_before_sending_break();
-	}
-
 	/* Save the server smb signing state. */
 	sign_state = srv_oplock_set_signing(False);
 
@@ -442,6 +396,53 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
 
 	/* Async level2 request, don't send a reply, just remove the oplock. */
 	remove_oplock(fsp);
+
+}
+
+/*******************************************************************
+ This handles the case of a write triggering a break to none
+ message on a level2 oplock.
+ When we get this message we may be in any of three states :
+ NO_OPLOCK, LEVEL_II, FAKE_LEVEL2. We only send a message to
+ the client for LEVEL2.
+*******************************************************************/
+
+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)
+{
+	struct share_mode_entry msg;
+	files_struct *fsp;
+
+	if (data->data == NULL) {
+		DEBUG(0, ("Got NULL buffer\n"));
+		return;
+	}
+
+	if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
+		DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
+		return;
+	}
+
+	/* De-linearize incoming message. */
+	message_to_share_mode_entry(&msg, (char *)data->data);
+
+	DEBUG(10, ("Got oplock async level 2 break message from pid %d: %s/%lu\n",
+		   (int)procid_to_pid(&src), file_id_string_tos(&msg.id), msg.share_file_id));
+
+	fsp = initial_break_processing(msg.id, msg.share_file_id);
+
+	if (fsp == NULL) {
+		/* We hit a race here. Break messages are sent, and before we
+		 * get to process this message, we have closed the file. 
+		 * No need to reply as this is an async message. */
+		DEBUG(3, ("process_oplock_async_level2_break_message: Did not find fsp, ignoring\n"));
+		return;
+	}
+
+	break_level2_to_none_async(fsp);
 }
 
 /*******************************************************************
@@ -811,13 +812,8 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp,
  		 */
 
 		if (procid_is_me(&share_entry->pid)) {
-			DATA_BLOB blob = data_blob_const(msg,
-					MSG_SMB_SHARE_MODE_ENTRY_SIZE);
-			process_oplock_async_level2_break_message(smbd_messaging_context(),
-						NULL,
-						MSG_SMB_ASYNC_LEVEL2_BREAK,
-						share_entry->pid,
-						&blob);
+			wait_before_sending_break();
+			break_level2_to_none_async(fsp);
 		} else {
 			messaging_send_buf(smbd_messaging_context(),
 					share_entry->pid,
diff --git a/source3/smbd/oplock_onefs.c b/source3/smbd/oplock_onefs.c
index d4f181f..b69d937 100644
--- a/source3/smbd/oplock_onefs.c
+++ b/source3/smbd/oplock_onefs.c
@@ -550,87 +550,18 @@ static void onefs_semlock_write(int fd, enum level2_contention_type type,
  * the cluster except the fsp's own level 2 oplock.  This lack of
  * self-contention is a limitation of the current OneFS kernel oplocks
  * implementation.  Luckily it is easy to contend our own level 2 oplock by
- * iterating the share mode entries and only breaking the oplock if the pid
- * matches our's.
+ * checking the the fsp's oplock_type.  If it's a level2, send a break message
+ * to the client and remove the oplock.
  */
 static void onefs_contend_level2_oplocks_begin(files_struct *fsp,
 					       enum level2_contention_type type)
 {
-	int i;
-	struct share_mode_lock *lck;
-
 	/* Take care of level 2 kernel contention. */
 	onefs_semlock_write(fsp->fh->fd, type, SEMLOCK_LOCK);
 
-	/*
-	 * If this file is level II oplocked then we need
-	 * to grab the shared memory lock and inform all
-	 * other files with a level II lock that they need
-	 * to flush their read caches. We keep the lock over
-	 * the shared memory area whilst doing this.
-	 */
-
-	if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
-		return;
-
-	lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
-				  NULL);
-	if (lck == NULL) {
-		DEBUG(0,("onefs_contend_level2_oplocks_begin: failed to lock "
-			 "share mode entry for file %s.\n", fsp->fsp_name ));
-		return;
-	}
-
-	DEBUG(10,("onefs_contend_level2_oplocks_begin: num_share_modes = %d\n",
-		  lck->num_share_modes ));
-
-	for(i = 0; i < lck->num_share_modes; i++) {
-		struct share_mode_entry *share_entry = &lck->share_modes[i];
-		char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
-
-		if (!is_valid_share_mode_entry(share_entry)) {
-			continue;
-		}
-
-		DEBUG(10,("onefs_contend_level2_oplocks_begin: "
-			  "share_entry[%i]->op_type == %d\n",
-			  i, share_entry->op_type ));
-
-		if (share_entry->op_type == NO_OPLOCK) {
-			continue;
-		}
-
-		/* Paranoia .... */
-		if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
-			DEBUG(0,("onefs_contend_level2_oplocks_begin: PANIC. "
-				 "share mode entry %d is an exlusive "
-				 "oplock !\n", i ));
-			TALLOC_FREE(lck);
-			abort();
-		}
-
-		share_mode_entry_to_message(msg, share_entry);
-
-		/*
-		 * Only contend our own level 2 oplock.  The other processes
-		 * will be get break events from the kernel.
-		 */
-		if (procid_is_me(&share_entry->pid)) {
-			DATA_BLOB blob = data_blob_const(msg,
-			    MSG_SMB_SHARE_MODE_ENTRY_SIZE);
-			process_oplock_async_level2_break_message(
-				smbd_messaging_context(),
-				NULL,
-				MSG_SMB_ASYNC_LEVEL2_BREAK,
-				share_entry->pid,
-				&blob);
-		}
-	}
-
-	/* We let the message receivers handle removing the oplock state
-	   in the share mode lock db. */
-
-	TALLOC_FREE(lck);
+	/* Take care of level 2 self contention. */
+	if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
+		break_level2_to_none_async(fsp);
 }
 
 /**


-- 
Samba Shared Repository


More information about the samba-cvs mailing list