Optimization on POSIX platforms that have fstatat.
authorJeremy Allison <jra@samba.org>
Fri, 24 May 2013 17:33:38 +0000 (10:33 -0700)
committerAndreas Schneider <asn@cryptomilk.org>
Mon, 10 Jun 2013 18:14:12 +0000 (20:14 +0200)
Tests show significant speedup in directory listings
by using fstatat instead of a full pathname walk.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Mon Jun 10 20:14:12 CEST 2013 on sn-devel-104

source3/modules/vfs_default.c

index 8804e623acf8fc01e41481297ed1cfb8898ec642..82d059c28fae90afe03c6b0e84ebfcf438bb511e 100644 (file)
@@ -376,11 +376,30 @@ static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
 
        START_PROFILE(syscall_readdir);
        result = readdir(dirp);
-       /* Default Posix readdir() does not give us stat info.
-        * Set to invalid to indicate we didn't return this info. */
-       if (sbuf)
-               SET_STAT_INVALID(*sbuf);
        END_PROFILE(syscall_readdir);
+       if (sbuf) {
+               /* Default Posix readdir() does not give us stat info.
+                * Set to invalid to indicate we didn't return this info. */
+               SET_STAT_INVALID(*sbuf);
+#if defined(HAVE_DIRFD) && defined(HAVE_FSTATAT)
+               if (result != NULL) {
+                       /* See if we can efficiently return this. */
+                       struct stat st;
+                       int flags = (lp_posix_pathnames() ?
+                               AT_SYMLINK_NOFOLLOW : 0);
+                       int ret = fstatat(dirfd(dirp),
+                                       result->d_name,
+                                       &st,
+                                       flags);
+                       if (ret == 0) {
+                               init_stat_ex_from_stat(sbuf,
+                                       &st,
+                                       lp_fake_dir_create_times(
+                                               SNUM(handle->conn)));
+                       }
+               }
+#endif
+       }
        return result;
 }