From: Volker Lendecke Date: Fri, 17 Jun 2022 15:41:52 +0000 (+0200) Subject: vfs_default: Use openat2(RESOLVE_NO_SYMLINKS) if available X-Git-Tag: talloc-2.4.0~1428 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4708ba2f013c5f5ea5aa5dcf4873c2b4a86fb8ff;p=thirdparty%2Fsamba.git vfs_default: Use openat2(RESOLVE_NO_SYMLINKS) if available This improves the following test: time smbtorture //127.0.0.1/m -Uroot%test \ smb2.create.bench-path-contention-shared \ --option='torture:bench_path=Apps\1\2\3\4\5\6\7\8\9\10' \ --option="torture:timelimit=600" \ --option="torture:nprocs=1" From: open[num/s=14186,avslat=0.000044,minlat=0.000042,maxlat=0.000079] close[num/s=14185,avslat=0.000027,minlat=0.000025,maxlat=0.000057] to: open[num/s=16917,avslat=0.000038,minlat=0.000035,maxlat=0.000340] close[num/s=16916,avslat=0.000020,minlat=0.000019,maxlat=0.000104] Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Volker Lendecke Signed-off-by: Stefan Metzmacher --- diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 847eddd8991..48ff174ebbe 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -49,7 +49,28 @@ static int vfswrap_connect(vfs_handle_struct *handle, const char *service, const char *user) { + bool bval; + handle->conn->have_proc_fds = sys_have_proc_fds(); + + /* + * assume the kernel will support openat2(), + * it will be reset on the first ENOSYS. + * + * Note that libreplace will always provide openat2(), + * but return -1/errno = ENOSYS... + * + * The option is only there to test the fallback code. + */ + bval = lp_parm_bool(SNUM(handle->conn), + "vfs_default", + "VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS", + true); + if (bval) { + handle->conn->open_how_resolve |= + VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS; + } + return 0; /* Return >= 0 for success */ } @@ -701,7 +722,7 @@ static int vfswrap_openat(vfs_handle_struct *handle, START_PROFILE(syscall_openat); - if (how->resolve != 0) { + if (how->resolve & ~VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS) { errno = ENOSYS; result = -1; goto out; @@ -734,6 +755,35 @@ static int vfswrap_openat(vfs_handle_struct *handle, } #endif + if (how->resolve & VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS) { + struct open_how linux_how = { + .flags = flags, + .mode = mode, + .resolve = RESOLVE_NO_SYMLINKS, + }; + + result = openat2(fsp_get_pathref_fd(dirfsp), + smb_fname->base_name, + &linux_how, + sizeof(linux_how)); + if (result == -1) { + if (errno == ENOSYS) { + /* + * The kernel doesn't support + * openat2(), so indicate to + * the callers that + * VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS + * would just be a waste of time. + */ + fsp->conn->open_how_resolve &= + ~VFS_OPEN_HOW_RESOLVE_NO_SYMLINKS; + } + goto out; + } + + goto done; + } + if (fsp->fsp_flags.is_pathref && !have_opath) { become_root(); became_root = true; @@ -748,6 +798,7 @@ static int vfswrap_openat(vfs_handle_struct *handle, unbecome_root(); } +done: fsp->fsp_flags.have_proc_fds = fsp->conn->have_proc_fds; out: