[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