[SCM] Samba Shared Repository - branch master updated -
release-4-0-0alpha7-883-g9d2d075
Tim Prouty
tprouty at samba.org
Mon Apr 6 20:55:26 GMT 2009
The branch, master has been updated
via 9d2d07503a17971a63153ecc13fdddb763e614b8 (commit)
via 651fa0964a6c49a071c28cdb1e4891b1d95d5b09 (commit)
from 12d9765177fc16f7b13e460e1d79c50c256d6fa8 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 9d2d07503a17971a63153ecc13fdddb763e614b8
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
commit 651fa0964a6c49a071c28cdb1e4891b1d95d5b09
Author: Tim Prouty <tprouty at samba.org>
Date: Thu Apr 2 18:33:30 2009 -0700
s3 oplocks: Refactor level II oplock contention
-----------------------------------------------------------------------
Summary of changes:
source3/include/proto.h | 1 +
source3/smbd/oplock.c | 110 +++++++++++++++++++++----------------------
source3/smbd/oplock_onefs.c | 79 ++-----------------------------
3 files changed, 59 insertions(+), 131 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d76ee08..b677c3d 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6677,6 +6677,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 6add9f5..98f89ac 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -344,6 +344,54 @@ static void add_oplock_timeout_handler(files_struct *fsp)
}
}
+void break_level2_to_none_async(files_struct *fsp)
+{
+ char *break_msg;
+
+ 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"));
+ 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"));
+ remove_oplock(fsp);
+ return;
+ }
+
+ /* 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));
+
+ /* 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");
+ }
+
+ show_msg(break_msg);
+ if (!srv_send_smb(smbd_server_fd(),
+ break_msg, false, 0,
+ IS_CONN_ENCRYPTED(fsp->conn),
+ NULL)) {
+ exit_server_cleanly("oplock_break: srv_send_smb failed.");
+ }
+
+ TALLOC_FREE(break_msg);
+
+ /* 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.
@@ -360,7 +408,6 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
{
struct share_mode_entry msg;
files_struct *fsp;
- char *break_msg;
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
@@ -375,9 +422,8 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
/* 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));
+ 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);
@@ -389,52 +435,7 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx
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"));
- 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"));
- remove_oplock(fsp);
- return;
- }
-
- /* 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));
-
- /* 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();
- }
-
- show_msg(break_msg);
- if (!srv_send_smb(smbd_server_fd(),
- break_msg, false, 0,
- IS_CONN_ENCRYPTED(fsp->conn),
- NULL)) {
- exit_server_cleanly("oplock_break: srv_send_smb failed.");
- }
-
- TALLOC_FREE(break_msg);
-
- /* Async level2 request, don't send a reply, just remove the oplock. */
- remove_oplock(fsp);
+ break_level2_to_none_async(fsp);
}
/*******************************************************************
@@ -790,13 +791,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