[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Fri Jun 29 20:11:02 MDT 2012
The branch, master has been updated
via 5679ba1 Don't allow asynchronous creates to be canceled in SMB2.
via 6617c2c Make schedule_deferred_open_message_smb() return an indication of success.
via 0d2f6ca Make schedule_deferred_open_message_smb2() return an indication of success.
via b004121 Allow for async opens.
via d1e1aa5 Add new bool field async_open to struct deferred_open_record. Not used yet.
via 0362dcb Fix defer_open() fuction in the open code path to cope with a NULL lck parameter.
via 34bb743 Add uint64_t mid field to the files_struct.
from 84f29b8 s3:waf add sendfile support for Tru64, which is the same as HP-UX's
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 5679ba10189aaa17023384be869ac600fa24a435
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jun 29 14:25:53 2012 -0700
Don't allow asynchronous creates to be canceled in SMB2.
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Sat Jun 30 04:10:02 CEST 2012 on sn-devel-104
commit 6617c2c1f586b355950e41edb5ca655b4f6dca54
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jun 29 13:56:26 2012 -0700
Make schedule_deferred_open_message_smb() return an indication of success.
commit 0d2f6cae418706ac2e72632d1b0187cfa66f9ec9
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jun 29 13:53:31 2012 -0700
Make schedule_deferred_open_message_smb2() return an indication of success.
commit b004121d9beb890054b373f96c8145bf8a830065
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jun 29 13:14:10 2012 -0700
Allow for async opens.
If the SMB_VFS_OPEN() function returns -1, EINTR -> NT_STATUS_RETRY,
then queue the open up to be completed when the async open completes.
commit d1e1aa552d3feb430b6b48c572ba2b713dfffec5
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jun 29 13:00:29 2012 -0700
Add new bool field async_open to struct deferred_open_record. Not used yet.
commit 0362dcbd09f27b33ed8c5264c7f22ee00ddc5d64
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jun 29 12:56:57 2012 -0700
Fix defer_open() fuction in the open code path to cope with a NULL lck parameter.
commit 34bb743ce3e24dde8b8fccdccb8f9c443fb2cd6f
Author: Jeremy Allison <jra at samba.org>
Date: Fri Jun 29 12:41:47 2012 -0700
Add uint64_t mid field to the files_struct.
Ensure it is initialized so we know what mid created this file.
-----------------------------------------------------------------------
Summary of changes:
source3/include/vfs.h | 1 +
source3/smbd/files.c | 1 +
source3/smbd/globals.h | 2 +-
source3/smbd/open.c | 87 +++++++++++++++++++++++++++++++++++---------
source3/smbd/process.c | 9 +++--
source3/smbd/proto.h | 3 +-
source3/smbd/smb2_create.c | 19 +++++++---
7 files changed, 92 insertions(+), 30 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 754d4e4..be4399f 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -227,6 +227,7 @@ typedef struct files_struct {
bool is_sparse;
struct smb_filename *fsp_name;
uint32_t name_hash; /* Jenkins hash of full pathname. */
+ uint64_t mid; /* Mid of the operation that created us. */
struct vfs_fsp_data *vfs_extension;
struct fake_file_handle *fake_file_handle;
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index 0929d99..390718f 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -126,6 +126,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
fsp_fnum_dbg(fsp), (unsigned int)sconn->num_files));
if (req != NULL) {
+ fsp->mid = req->mid;
req->chain_fsp = fsp;
}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 6c1efaf..b07ee3a 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -310,7 +310,7 @@ bool open_was_deferred_smb2(struct smbd_server_connection *sconn,
uint64_t mid);
void remove_deferred_open_message_smb2(
struct smbd_server_connection *sconn, uint64_t mid);
-void schedule_deferred_open_message_smb2(
+bool schedule_deferred_open_message_smb2(
struct smbd_server_connection *sconn, uint64_t mid);
bool push_deferred_open_message_smb2(struct smbd_smb2_request *smb2req,
struct timeval request_time,
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index f259cc9..c2bf8ed 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -35,6 +35,7 @@ extern const struct generic_mapping file_generic_mapping;
struct deferred_open_record {
bool delayed_for_oplocks;
+ bool async_open;
struct file_id id;
};
@@ -1355,20 +1356,23 @@ static void defer_open(struct share_mode_lock *lck,
struct deferred_open_record *state)
{
struct server_id self = messaging_server_id(req->sconn->msg_ctx);
- int i;
/* Paranoia check */
- for (i=0; i<lck->data->num_share_modes; i++) {
- struct share_mode_entry *e = &lck->data->share_modes[i];
+ if (lck) {
+ int i;
- if (is_deferred_open_entry(e) &&
- serverid_equal(&self, &e->pid) &&
- (e->op_mid == req->mid)) {
- DEBUG(0, ("Trying to defer an already deferred "
- "request: mid=%llu, exiting\n",
- (unsigned long long)req->mid));
- exit_server("attempt to defer a deferred request");
+ for (i=0; i<lck->data->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->data->share_modes[i];
+
+ if (is_deferred_open_entry(e) &&
+ serverid_equal(&self, &e->pid) &&
+ (e->op_mid == req->mid)) {
+ DEBUG(0, ("Trying to defer an already deferred "
+ "request: mid=%llu, exiting\n",
+ (unsigned long long)req->mid));
+ exit_server("attempt to defer a deferred request");
+ }
}
}
@@ -1384,7 +1388,9 @@ static void defer_open(struct share_mode_lock *lck,
state->id, (char *)state, sizeof(*state))) {
exit_server("push_deferred_open_message_smb failed");
}
- add_deferred_open(lck, req->mid, request_time, self, state->id);
+ if (lck) {
+ add_deferred_open(lck, req->mid, request_time, self, state->id);
+ }
}
@@ -1527,6 +1533,7 @@ static void schedule_defer_open(struct share_mode_lock *lck,
a 1 second delay for share mode conflicts. */
state.delayed_for_oplocks = True;
+ state.async_open = false;
state.id = lck->data->id;
if (!request_timed_out(request_time, timeout)) {
@@ -1535,6 +1542,27 @@ static void schedule_defer_open(struct share_mode_lock *lck,
}
/****************************************************************************
+ Reschedule an open call that went asynchronous.
+****************************************************************************/
+
+static void schedule_async_open(struct timeval request_time,
+ struct smb_request *req)
+{
+ struct deferred_open_record state;
+ struct timeval timeout;
+
+ timeout = timeval_set(20, 0);
+
+ ZERO_STRUCT(state);
+ state.delayed_for_oplocks = false;
+ state.async_open = true;
+
+ if (!request_timed_out(request_time, timeout)) {
+ defer_open(NULL, request_time, timeout, req, &state);
+ }
+}
+
+/****************************************************************************
Work out what access_mask to use from what the client sent us.
****************************************************************************/
@@ -1657,6 +1685,17 @@ void remove_deferred_open_entry(struct file_id id, uint64_t mid,
}
/****************************************************************************
+ Return true if this is a state pointer to an asynchronous create.
+****************************************************************************/
+
+bool is_deferred_open_async(const void *ptr)
+{
+ const struct deferred_open_record *state = (const struct deferred_open_record *)ptr;
+
+ return state->async_open;
+}
+
+/****************************************************************************
Open a file with a share mode. Passed in an already created files_struct *.
****************************************************************************/
@@ -1760,16 +1799,23 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
if (get_deferred_open_message_state(req,
&request_time,
&ptr)) {
-
- struct deferred_open_record *state = (struct deferred_open_record *)ptr;
/* Remember the absolute time of the original
request with this mid. We'll use it later to
see if this has timed out. */
- /* Remove the deferred open entry under lock. */
- remove_deferred_open_entry(
- state->id, req->mid,
- messaging_server_id(req->sconn->msg_ctx));
+ /* If it was an async create retry, the file
+ didn't exist. */
+
+ if (is_deferred_open_async(ptr)) {
+ SET_STAT_INVALID(smb_fname->st);
+ file_existed = false;
+ } else {
+ struct deferred_open_record *state = (struct deferred_open_record *)ptr;
+ /* Remove the deferred open entry under lock. */
+ remove_deferred_open_entry(
+ state->id, req->mid,
+ messaging_server_id(req->sconn->msg_ctx));
+ }
/* Ensure we don't reprocess this message. */
remove_deferred_open_message_smb(req->sconn, req->mid);
@@ -2161,6 +2207,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
a 1 second delay for share mode conflicts. */
state.delayed_for_oplocks = False;
+ state.async_open = false;
state.id = id;
if ((req != NULL)
@@ -2215,6 +2262,9 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
open_access_mask);
if (!NT_STATUS_IS_OK(fsp_open)) {
+ if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
+ schedule_async_open(request_time, req);
+ }
TALLOC_FREE(lck);
return fsp_open;
}
@@ -2302,6 +2352,7 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
struct deferred_open_record state;
state.delayed_for_oplocks = False;
+ state.async_open = false;
state.id = id;
/* Do it all over again immediately. In the second
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 55a125f..f8757fa 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -718,15 +718,14 @@ void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
schedule it for immediate processing.
****************************************************************************/
-void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
+bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
uint64_t mid)
{
struct pending_message_list *pml;
int i = 0;
if (sconn->using_smb2) {
- schedule_deferred_open_message_smb2(sconn, mid);
- return;
+ return schedule_deferred_open_message_smb2(sconn, mid);
}
for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
@@ -768,13 +767,15 @@ void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
TALLOC_FREE(pml->te);
pml->te = te;
DLIST_PROMOTE(sconn->deferred_open_queue, pml);
- return;
+ return true;
}
}
DEBUG(10,("schedule_deferred_open_message_smb: failed to "
"find message mid %llu\n",
(unsigned long long)mid ));
+
+ return false;
}
/****************************************************************************
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 35a677c..1b28c8b 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -616,6 +616,7 @@ bool open_match_attributes(connection_struct *conn,
mode_t *returned_unx_mode);
void remove_deferred_open_entry(struct file_id id, uint64_t mid,
struct server_id pid);
+bool is_deferred_open_async(const void *ptr);
NTSTATUS open_file_fchmod(connection_struct *conn,
struct smb_filename *smb_fname,
files_struct **result);
@@ -752,7 +753,7 @@ int srv_set_message(char *buf,
bool zero);
void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
uint64_t mid);
-void schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
+bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
uint64_t mid);
bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid);
bool get_deferred_open_message_state(struct smb_request *smbreq,
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 18c3fb9..7b5a262 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -1036,7 +1036,7 @@ static void smbd_smb2_create_request_dispatch_immediate(struct tevent_context *c
}
}
-void schedule_deferred_open_message_smb2(
+bool schedule_deferred_open_message_smb2(
struct smbd_server_connection *sconn, uint64_t mid)
{
struct smbd_smb2_create_state *state = NULL;
@@ -1048,18 +1048,18 @@ void schedule_deferred_open_message_smb2(
DEBUG(10,("schedule_deferred_open_message_smb2: "
"can't find mid %llu\n",
(unsigned long long)mid ));
- return;
+ return false;
}
if (!smb2req->subreq) {
- return;
+ return false;
}
if (!tevent_req_is_in_progress(smb2req->subreq)) {
- return;
+ return false;
}
state = tevent_req_data(smb2req->subreq,
struct smbd_smb2_create_state);
if (!state) {
- return;
+ return false;
}
/* Ensure we don't have any outstanding timer event. */
@@ -1080,7 +1080,7 @@ void schedule_deferred_open_message_smb2(
if (!state->im) {
smbd_server_connection_terminate(smb2req->sconn,
nt_errstr(NT_STATUS_NO_MEMORY));
- return;
+ return false;
}
DEBUG(10,("schedule_deferred_open_message_smb2: "
@@ -1091,6 +1091,8 @@ void schedule_deferred_open_message_smb2(
smb2req->sconn->ev_ctx,
smbd_smb2_create_request_dispatch_immediate,
smb2req);
+
+ return true;
}
/*********************************************************
@@ -1160,6 +1162,11 @@ static bool smbd_smb2_create_cancel(struct tevent_req *req)
smb2req = state->smb2req;
mid = get_mid_from_smb2req(smb2req);
+ if (is_deferred_open_async(state->private_data.data)) {
+ /* Can't cancel an async create. */
+ return false;
+ }
+
remove_deferred_open_entry(state->id, mid,
messaging_server_id(smb2req->sconn->msg_ctx));
remove_deferred_open_message_smb2_internal(smb2req, mid);
--
Samba Shared Repository
More information about the samba-cvs
mailing list