Sigh :-(. Removing optimization prematurely is the root of all evil :-(.
authorJeremy Allison <jra@samba.org>
Thu, 13 Sep 2012 17:13:21 +0000 (10:13 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 13 Sep 2012 19:31:42 +0000 (21:31 +0200)
Sorry for the mistake, but the LastDir singleton cache in vfs_ChDir()
actually plays an important role. When we're processing a stream of
SMB1/SMB2/SMB3 requests we don't want to add a chdir()/getcwd()
system call pair on every request if they're all on the same connection
and dealing with the same base path.

I did some testing with a program that times 1,000,000 chdir()
requests vs. 1,000,000 strcmp requests and it's a penalty of 10x
doing the system calls.

Just because it's old code, doesn't mean it's bad :-(.

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Sep 13 21:31:42 CEST 2012 on sn-devel-104

source3/smbd/globals.c
source3/smbd/globals.h
source3/smbd/vfs.c

index 874f35d1f6f180e11f9085abf3e1571099e7e2a4..80f6a6642773f50c22c7bee14288defaaada68d0 100644 (file)
@@ -85,6 +85,7 @@ int conn_ctx_stack_ndx = 0;
 
 struct vfs_init_function_entry *backends = NULL;
 char *sparse_buf = NULL;
+char *LastDir = NULL;
 
 struct smbd_parent_context *am_parent = NULL;
 struct memcache *smbd_memcache_ctx = NULL;
index 1cefe51faa7e1a3b39b98ba0688305f762a31668..566f04d71f3fe754c72110807ef7e8f552bcf464 100644 (file)
@@ -101,6 +101,7 @@ extern int conn_ctx_stack_ndx;
 struct vfs_init_function_entry;
 extern struct vfs_init_function_entry *backends;
 extern char *sparse_buf;
+extern char *LastDir;
 
 struct smbd_parent_context;
 extern struct smbd_parent_context *am_parent;
index 7d194404f4738e37620def3269bfece9df93566b..fe99ee29e99a2e9e640042019d8da185e9651c63 100644 (file)
@@ -801,14 +801,27 @@ int vfs_ChDir(connection_struct *conn, const char *path)
 {
        int ret;
 
+       if (!LastDir) {
+               LastDir = SMB_STRDUP("");
+       }
+
        if (strcsequal(path,".")) {
                return 0;
        }
 
+       if (*path == '/' && strcsequal(LastDir,path)) {
+               return 0;
+       }
+
        DEBUG(4,("vfs_ChDir to %s\n",path));
 
        ret = SMB_VFS_CHDIR(conn,path);
        if (ret == 0) {
+               /* Global cache. */
+               SAFE_FREE(LastDir);
+               LastDir = SMB_STRDUP(path);
+
+               /* conn cache. */
                TALLOC_FREE(conn->cwd);
                conn->cwd = vfs_GetWd(conn, conn);
                DEBUG(4,("vfs_ChDir got %s\n",conn->cwd));