summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-04-09 22:46:59 -0700
committerJeremy Allison <jra@samba.org>2009-04-09 22:46:59 -0700
commit7f10bf980edef3ace1522d0c9c082b35e225c950 (patch)
treed4e9af21de194cca812e754b28f9358a3651f4ce /source3/smbd
parentf8f68703da58cf7f61b655b48bbbc45cda647748 (diff)
parentf930f504e1d5e78d2f6f36cab9ce36dbeb34e955 (diff)
downloadsamba-7f10bf980edef3ace1522d0c9c082b35e225c950.tar.gz
samba-7f10bf980edef3ace1522d0c9c082b35e225c950.tar.bz2
samba-7f10bf980edef3ace1522d0c9c082b35e225c950.zip
Merge branch 'master' of ssh://jra@git.samba.org/data/git/samba
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/ipc.c4
-rw-r--r--source3/smbd/oplock.c131
-rw-r--r--source3/smbd/oplock_onefs.c79
-rw-r--r--source3/smbd/sesssetup.c8
4 files changed, 74 insertions, 148 deletions
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index d39aab4f47..2d5713590d 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -754,6 +754,8 @@ void reply_trans(struct smb_request *req)
return;
}
+ talloc_steal(talloc_tos(), state);
+
handle_trans(conn, req, state);
SAFE_FREE(state->data);
@@ -852,6 +854,8 @@ void reply_transs(struct smb_request *req)
return;
}
+ talloc_steal(talloc_tos(), state);
+
handle_trans(conn, req, state);
DLIST_REMOVE(conn->pending_trans, state);
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index ce00397bbd..b937e8e07d 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,8 +422,9 @@ 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 %d: %s/%lu\n",
- (int)procid_to_pid(&src), file_id_string_tos(&msg.id), msg.share_file_id));
+ 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);
@@ -388,52 +436,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_to_pid(&src) == sys_getpid()) {
- 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);
}
/*******************************************************************
@@ -464,8 +467,9 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
/* De-linearize incoming message. */
message_to_share_mode_entry(&msg, (char *)data->data);
- DEBUG(10, ("Got oplock break message from pid %d: %s/%lu\n",
- (int)procid_to_pid(&src), file_id_string_tos(&msg.id), msg.share_file_id));
+ DEBUG(10, ("Got oplock 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);
@@ -518,7 +522,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
}
/* Need to wait before sending a break message if we sent ourselves this message. */
- if (procid_to_pid(&src) == sys_getpid()) {
+ if (procid_is_me(&src)) {
wait_before_sending_break();
}
@@ -571,8 +575,8 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
pull_file_id_24((char *)data->data, &id);
file_id = (unsigned long)IVAL(data->data, 24);
- DEBUG(10, ("Got kernel oplock break message from pid %d: %s/%u\n",
- (int)procid_to_pid(&src), file_id_string_tos(&id),
+ DEBUG(10, ("Got kernel oplock break message from pid %s: %s/%u\n",
+ procid_str(debug_ctx(), &src), file_id_string_tos(&id),
(unsigned int)file_id));
fsp = initial_break_processing(id, file_id);
@@ -667,9 +671,9 @@ static void process_oplock_break_response(struct messaging_context *msg_ctx,
/* De-linearize incoming message. */
message_to_share_mode_entry(&msg, (char *)data->data);
- DEBUG(10, ("Got oplock break response from pid %d: %s/%lu mid %u\n",
- (int)procid_to_pid(&src), file_id_string_tos(&msg.id), msg.share_file_id,
- (unsigned int)msg.op_mid));
+ DEBUG(10, ("Got oplock break response from pid %s: %s/%lu mid %u\n",
+ procid_str(debug_ctx(), &src), file_id_string_tos(&msg.id),
+ msg.share_file_id, (unsigned int)msg.op_mid));
/* Here's the hack from open.c, store the mid in the 'port' field */
schedule_deferred_open_smb_message(msg.op_mid);
@@ -696,8 +700,8 @@ static void process_open_retry_message(struct messaging_context *msg_ctx,
/* De-linearize incoming message. */
message_to_share_mode_entry(&msg, (char *)data->data);
- DEBUG(10, ("Got open retry msg from pid %d: %s mid %u\n",
- (int)procid_to_pid(&src), file_id_string_tos(&msg.id),
+ DEBUG(10, ("Got open retry msg from pid %s: %s mid %u\n",
+ procid_str(debug_ctx(), &src), file_id_string_tos(&msg.id),
(unsigned int)msg.op_mid));
schedule_deferred_open_smb_message(msg.op_mid);
@@ -788,13 +792,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 d4f181fc47..b69d937915 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);
}
/**
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index e8878a29ab..d524f21817 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -333,7 +333,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
DEBUG(3,("Doesn't look like a valid principal\n"));
data_blob_free(&ap_rep);
data_blob_free(&session_key);
- SAFE_FREE(client);
talloc_destroy(mem_ctx);
reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE));
return;
@@ -355,7 +354,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
if (!lp_allow_trusted_domains()) {
data_blob_free(&ap_rep);
data_blob_free(&session_key);
- SAFE_FREE(client);
talloc_destroy(mem_ctx);
reply_nterror(req, nt_status_squash(
NT_STATUS_LOGON_FAILURE));
@@ -445,7 +443,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
if ( !pw ) {
DEBUG(1,("Username %s is invalid on this system\n",
user));
- SAFE_FREE(client);
data_blob_free(&ap_rep);
data_blob_free(&session_key);
TALLOC_FREE(mem_ctx);
@@ -471,7 +468,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
if ( !NT_STATUS_IS_OK(ret) ) {
DEBUG(1,("make_server_info_info3 failed: %s!\n",
nt_errstr(ret)));
- SAFE_FREE(client);
data_blob_free(&ap_rep);
data_blob_free(&session_key);
TALLOC_FREE(mem_ctx);
@@ -485,7 +481,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
if ( !NT_STATUS_IS_OK(ret) ) {
DEBUG(1,("make_server_info_pw failed: %s!\n",
nt_errstr(ret)));
- SAFE_FREE(client);
data_blob_free(&ap_rep);
data_blob_free(&session_key);
TALLOC_FREE(mem_ctx);
@@ -513,7 +508,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
if ( !NT_STATUS_IS_OK(ret) ) {
DEBUG(10,("failed to create local token: %s\n",
nt_errstr(ret)));
- SAFE_FREE(client);
data_blob_free(&ap_rep);
data_blob_free(&session_key);
TALLOC_FREE( mem_ctx );
@@ -541,8 +535,6 @@ static void reply_spnego_kerberos(struct smb_request *req,
nullblob,
client);
- SAFE_FREE(client);
-
reply_outbuf(req, 4, 0);
SSVAL(req->outbuf,smb_uid,sess_vuid);