From: Ralph Boehme Date: Fri, 16 Oct 2020 13:40:56 +0000 (+0200) Subject: vfs_default: simplify vfswrap_readdir() X-Git-Tag: samba-4.14.0rc1~321 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dd36847928992ee5dc39f09e12992ab65c138923;p=thirdparty%2Fsamba.git vfs_default: simplify vfswrap_readdir() No change in behaviour. Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 929c4ce7d0e..b242e677717 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -576,40 +576,57 @@ static struct dirent *vfswrap_readdir(vfs_handle_struct *handle, SMB_STRUCT_STAT *sbuf) { struct dirent *result; + bool do_stat = false; + bool fake_ctime = lp_fake_directory_create_times(SNUM(handle->conn)); + int flags = AT_SYMLINK_NOFOLLOW; + struct stat st; + int ret; START_PROFILE(syscall_readdir); - result = readdir(dirp); - 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 = AT_SYMLINK_NOFOLLOW; - int ret = fstatat(dirfd(dirp), - result->d_name, - &st, - flags); - /* - * As this is an optimization, - * ignore it if we stat'ed a - * symlink. Make the caller - * do it again as we don't - * know if they wanted the link - * info, or its target info. - */ - if ((ret == 0) && (!S_ISLNK(st.st_mode))) { - init_stat_ex_from_stat(sbuf, - &st, - lp_fake_directory_create_times( - SNUM(handle->conn))); - } - } + do_stat = true; #endif + + result = readdir(dirp); + END_PROFILE(syscall_readdir); + + if (sbuf == NULL) { + return result; + } + if (result == NULL) { + return NULL; } + + /* + * Default Posix readdir() does not give us stat info. + * Set to invalid to indicate we didn't return this info. + */ + SET_STAT_INVALID(*sbuf); + + /* See if we can efficiently return this. */ + if (!do_stat) { + return result; + } + + ret = fstatat(dirfd(dirp), + result->d_name, + &st, + flags); + if (ret != 0) { + return result; + } + + /* + * As this is an optimization, ignore it if we stat'ed a + * symlink. Make the caller do it again as we don't know if + * they wanted the link info, or its target info. + */ + if (S_ISLNK(st.st_mode)) { + return result; + } + init_stat_ex_from_stat(sbuf, &st, fake_ctime); + return result; }