Patch: Tune "dir" a bit

Volker Lendecke Volker.Lendecke at SerNet.DE
Fri Mar 22 07:37:31 MDT 2013


Hi!

Attached find a patch that makes trans2_findfirst take 10%
less user-space CPU. If someone has the time, can you try to
verify this improvement and 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 887cfce82e7c47c50e2dd10048acd26ad9043cf0 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 21 Mar 2013 22:00:06 +0100
Subject: [PATCH] smbd: Tune "dir" a bit.

for i in $(seq 1 20000) ; do echo dir ; done | smbclient //127.0.0.1/tmp -U%

without and with this patch:

$ time bin/smbd -d0 -i
smbd version 4.1.0pre1-GIT-1f139ae started.
Copyright Andrew Tridgell and the Samba Team 1992-2013
Beendet

real    0m28.342s
user    0m10.249s
sys     0m10.513s

$ time bin/smbd -d0 -i
smbd version 4.1.0pre1-GIT-1f139ae started.
Copyright Andrew Tridgell and the Samba Team 1992-2013
Beendet

real    0m27.348s
user    0m9.089s
sys     0m10.853s

The "real" timestamp is irrelevant, this also contains the time between
starting smbd and the smbclient job. It's the "user" time. The result that this
patch improves the time spent in user space by 10% is consistent.

Signed-off-by: Volker Lendecke <vl at samba.org>
---
 source3/smbd/dir.c |   25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 525f20e..f1c177f 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -1038,12 +1038,14 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 			   long *_prev_offset)
 {
 	connection_struct *conn = dirptr->conn;
-	bool needslash;
+	size_t slashlen;
+	size_t pathlen;
 
 	*_smb_fname = NULL;
 	*_mode = 0;
 
-	needslash = ( dirptr->path[strlen(dirptr->path) -1] != '/');
+	pathlen = strlen(dirptr->path);
+	slashlen = ( dirptr->path[pathlen-1] != '/') ? 1 : 0;
 
 	while (true) {
 		long cur_offset;
@@ -1087,16 +1089,27 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
 			continue;
 		}
 
-		pathreal = talloc_asprintf(ctx, "%s%s%s",
-					   dirptr->path,
-					   needslash?"/":"",
-					   dname);
+		/*
+		 * This used to be
+		 * pathreal = talloc_asprintf(ctx, "%s%s%s", dirptr->path,
+		 *			      needslash?"/":"", dname);
+		 * but this was measurably slower than doing the memcpy.
+		 */
+
+		pathreal = talloc_array(
+			ctx, char,
+			pathlen + slashlen + talloc_get_size(dname));
 		if (!pathreal) {
 			TALLOC_FREE(dname);
 			TALLOC_FREE(fname);
 			return false;
 		}
 
+		memcpy(pathreal, dirptr->path, pathlen);
+		pathreal[pathlen] = '/';
+		memcpy(pathreal + slashlen + pathlen, dname,
+		       talloc_get_size(dname));
+
 		/* Create smb_fname with NULL stream_name. */
 		ZERO_STRUCT(smb_fname);
 		smb_fname.base_name = pathreal;
-- 
1.7.9.5



More information about the samba-technical mailing list