From 1de93178bf8bc7e3f30782942ac855a422a7f4bc Mon Sep 17 00:00:00 2001 From: Volker Lendecke 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 Reviewed-by: Jeremy Allison --- 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.8.1.3