PATCH: Performance optimization

Volker Lendecke Volker.Lendecke at SerNet.DE
Fri Nov 22 12:34:05 MST 2013


Hi!

Attached find a performance optimization patchset that is
particularly relevant in the cluster case.

Please review&push!

Thanks,

Volker

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 8273f6ed3a002a73556386b21a7cb909bc070c62 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 22 Nov 2013 14:36:49 +0000
Subject: [PATCH 1/3] smbd: Factor out get_share_mode_write_time of
 get_file_infos

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/locking/locking.c |   19 +++++++++++--------
 source3/locking/proto.h   |    1 +
 2 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index b5d4f24..54c92b1 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -600,14 +600,7 @@ void get_file_infos(struct file_id id,
 	}
 
 	if (write_time) {
-		struct timespec wt;
-
-		wt = lck->data->changed_write_time;
-		if (null_timespec(wt)) {
-			wt = lck->data->old_write_time;
-		}
-
-		*write_time = wt;
+		*write_time = get_share_mode_write_time(lck);
 	}
 
 	TALLOC_FREE(lck);
@@ -1088,3 +1081,13 @@ bool set_write_time(struct file_id fileid, struct timespec write_time)
 	TALLOC_FREE(lck);
 	return True;
 }
+
+struct timespec get_share_mode_write_time(struct share_mode_lock *lck)
+{
+	struct share_mode_data *d = lck->data;
+
+	if (!null_timespec(d->changed_write_time)) {
+		return d->changed_write_time;
+	}
+	return d->old_write_time;
+}
diff --git a/source3/locking/proto.h b/source3/locking/proto.h
index 2c9654c..a897fea 100644
--- a/source3/locking/proto.h
+++ b/source3/locking/proto.h
@@ -197,6 +197,7 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close,
 bool is_delete_on_close_set(struct share_mode_lock *lck, uint32_t name_hash);
 bool set_sticky_write_time(struct file_id fileid, struct timespec write_time);
 bool set_write_time(struct file_id fileid, struct timespec write_time);
+struct timespec get_share_mode_write_time(struct share_mode_lock *lck);
 int share_mode_forall(void (*fn)(const struct share_mode_entry *, const char *,
 				 const char *, void *),
 		      void *private_data);
-- 
1.7.9.5


From 9e4a41aa9810fd2b229ccaa6450ec8aedb6877bc Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 22 Nov 2013 16:17:44 +0000
Subject: [PATCH 2/3] smbd: Point reply_open at the correct stat struct

Not sure if anybody will ever notice this these days, but the same is
done in the createfile calls.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/smbd/reply.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index b160290..7a6335b 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1960,6 +1960,10 @@ void reply_open(struct smb_request *req)
 		goto out;
 	}
 
+	/* Ensure we're pointing at the correct stat struct. */
+	TALLOC_FREE(smb_fname);
+	smb_fname = fsp->fsp_name;
+
 	size = smb_fname->st.st_ex_size;
 	fattr = dos_mode(conn, smb_fname);
 
@@ -2007,7 +2011,6 @@ void reply_open(struct smb_request *req)
 		      CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
 	}
  out:
-	TALLOC_FREE(smb_fname);
 	END_PROFILE(SMBopen);
 	return;
 }
-- 
1.7.9.5


From b5b2349fb32c631c71ecee3da1966287604a0dec Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 22 Nov 2013 16:24:42 +0000
Subject: [PATCH 3/3] smbd: Pull mtime handling into open_file_ntcreate

This is a performance improvement for heavily contended files, in
particular in a cluster. The separate call to get_file_infos makes us
pull the locking.tdb record twice per open. For a contended file this
can be a performance penalty, this gets the # of record accesses for
the open/close cycle down from 3 to 2.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/smbd/nttrans.c     |   18 ------------------
 source3/smbd/open.c        |   23 +++++++++++++++++++++++
 source3/smbd/reply.c       |   12 ------------
 source3/smbd/smb2_create.c |    8 --------
 4 files changed, 23 insertions(+), 38 deletions(-)

diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 94be9f6..e901ff2 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -457,7 +457,6 @@ void reply_ntcreate_and_X(struct smb_request *req)
 	struct timespec c_timespec;
 	struct timespec a_timespec;
 	struct timespec m_timespec;
-	struct timespec write_time_ts;
 	NTSTATUS status;
 	int oplock_request;
 	uint8_t oplock_granted = NO_OPLOCK_RETURN;
@@ -657,14 +656,6 @@ void reply_ntcreate_and_X(struct smb_request *req)
 		fattr = FILE_ATTRIBUTE_NORMAL;
 	}
 
-	/* Deal with other possible opens having a modified
-	   write time. JRA. */
-	ZERO_STRUCT(write_time_ts);
-	get_file_infos(fsp->file_id, 0, NULL, &write_time_ts);
-	if (!null_timespec(write_time_ts)) {
-		update_stat_ex_mtime(&smb_fname->st, write_time_ts);
-	}
-
 	/* Create time. */
 	create_timespec = get_create_timespec(conn, fsp, smb_fname);
 	a_timespec = smb_fname->st.st_ex_atime;
@@ -1001,7 +992,6 @@ static void call_nt_transact_create(connection_struct *conn,
 	struct timespec c_timespec;
 	struct timespec a_timespec;
 	struct timespec m_timespec;
-	struct timespec write_time_ts;
 	struct ea_list *ea_list = NULL;
 	NTSTATUS status;
 	size_t param_len;
@@ -1270,14 +1260,6 @@ static void call_nt_transact_create(connection_struct *conn,
 		fattr = FILE_ATTRIBUTE_NORMAL;
 	}
 
-	/* Deal with other possible opens having a modified
-	   write time. JRA. */
-	ZERO_STRUCT(write_time_ts);
-	get_file_infos(fsp->file_id, 0, NULL, &write_time_ts);
-	if (!null_timespec(write_time_ts)) {
-		update_stat_ex_mtime(&smb_fname->st, write_time_ts);
-	}
-
 	/* Create time. */
 	create_timespec = get_create_timespec(conn, fsp, smb_fname);
 	a_timespec = smb_fname->st.st_ex_atime;
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 105eb09..ea32a90 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -2844,6 +2844,17 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
 				  (unsigned int)new_unx_mode));
 	}
 
+	{
+		/*
+		 * Deal with other opens having a modified write time.
+		 */
+		struct timespec write_time = get_share_mode_write_time(lck);
+
+		if (!null_timespec(write_time)) {
+			update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
+		}
+	}
+
 	TALLOC_FREE(lck);
 
 	return NT_STATUS_OK;
@@ -3280,6 +3291,18 @@ static NTSTATUS open_directory(connection_struct *conn,
 		}
 	}
 
+	{
+		/*
+		 * Deal with other opens having a modified write time. Is this
+		 * possible for directories?
+		 */
+		struct timespec write_time = get_share_mode_write_time(lck);
+
+		if (!null_timespec(write_time)) {
+			update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
+		}
+	}
+
 	TALLOC_FREE(lck);
 
 	if (pinfo) {
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 7a6335b..a4d1ebe 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1967,18 +1967,6 @@ void reply_open(struct smb_request *req)
 	size = smb_fname->st.st_ex_size;
 	fattr = dos_mode(conn, smb_fname);
 
-	/* Deal with other possible opens having a modified
-	   write time. JRA. */
-	if (ask_sharemode) {
-		struct timespec write_time_ts;
-
-		ZERO_STRUCT(write_time_ts);
-		get_file_infos(fsp->file_id, 0, NULL, &write_time_ts);
-		if (!null_timespec(write_time_ts)) {
-			update_stat_ex_mtime(&smb_fname->st, write_time_ts);
-		}
-	}
-
 	mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
 
 	if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index f48c8ee..38eba4f 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -411,7 +411,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 	struct smb_request *smb1req = NULL;
 	files_struct *result = NULL;
 	int info;
-	struct timespec write_time_ts;
 	struct smb2_create_blobs out_context_blobs;
 	int requested_oplock_level;
 	struct smb2_create_blob *dhnc = NULL;
@@ -1066,13 +1065,6 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 	}
 	state->out_file_attributes = dos_mode(result->conn,
 					   result->fsp_name);
-	/* Deal with other possible opens having a modified
-	   write time. JRA. */
-	ZERO_STRUCT(write_time_ts);
-	get_file_infos(result->file_id, 0, NULL, &write_time_ts);
-	if (!null_timespec(write_time_ts)) {
-		update_stat_ex_mtime(&result->fsp_name->st, write_time_ts);
-	}
 
 	unix_timespec_to_nt_time(&state->out_creation_time,
 			get_create_timespec(smb1req->conn, result,
-- 
1.7.9.5



More information about the samba-technical mailing list