From nobody Fri Apr 28 08:57:20 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Q761X4QqQz48CNt; Fri, 28 Apr 2023 08:57:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Q761X3hVMz4SBM; Fri, 28 Apr 2023 08:57:20 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682672240; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Iq0yULDWxQeuh2/V+P9N3XqjvDBzbbZ3cdnx2ZkJKXU=; b=nkF640jBasytc8W3V0auGGeaXPLHqDT4tQq6VfQ1O66CZVKP2Y7+/AqJydnT9aihg/Txq0 QgnWP0zka1s+2hJWx2Sg5E9Ppt/jsYiAUZ6lZ57ZZ+WCiegtYT3TAhN0w8xG+CnfmGoHN4 FRfr4fp3NykHf5X4dybUaAWkW8YATSlPCA2EezE4fO+ZXxay1JMo6qJxxWz6er5zsyWB7J wowmYmGZ1mYIOwEbMqW+EWxhRFexvgF1+IBrPPkj6Ye+lnrBd/A2wjtIfVrFTk0jhNl88i Z3NSwiAct+5l7N3gWawNxyRSxyJBcP7RfyloGh+JlmORqiz5oQnfHQcn4QAeiQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1682672240; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Iq0yULDWxQeuh2/V+P9N3XqjvDBzbbZ3cdnx2ZkJKXU=; b=SrALi2z9Kk8c0LsNjOUFIYSnJQgdY1RfMPGHjsDDU98ZqTQ1CylT70bkJxMjKGMu2nG5K3 VEsETkgqplXPLdMkxsXHc9L6run/0JehqrCSBHnZu6zlghxBAZJwXhnFE2EzNqeynhcIqH BZi2QfXG5prn5UImFRjlrmA7qBA2M6e+/iQFcO79JkrcDAU/ygdbbu5RcYR89mFgpEZKRx FHtE+OvWPQ1yA9o7crsozCX6oTOqQZlD2kN17+0dulFLhVkN5XfWGASuTS4JTAwzUow+8f Q88CESHv6XVMBJnpKyTHG/8KkhEVbZNaIU1SUrfpTaPtH1IRy8tEw/nHz1yjog== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1682672240; a=rsa-sha256; cv=none; b=BWY9EQNHfQ6kYK1R0Hte9+H9UBJk5GCAUwZvDpnuZV7osOBARTd2cS0jbeMhs2s1fm0pYj NQEi3wG317PbAt9HiK+k1VYJlSAf2sQX20fQ+0krBzovz/91kXyjh6QqOvFo4fS8Z2Uw1j CTOeb/P6UASvvzQj6f6PPwMrMBedYS7nvt//4X8aOZErV5Jp2gCGkqyB9TTGMaDW3a6ui4 C4pLRh7u3bKBKVj11LKBJLMDPnbVTvKQnWDMDPQ9c032KsZnlNf7Fejmj0krG83sfGgtL2 0GRJxHfSMF++46xkOKjLj0ZSlzWdra/Sr2b2Fkoe+NrP+HTQvZsecy5ZJBvX1A== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Q761X2nh0zt09; Fri, 28 Apr 2023 08:57:20 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 33S8vKo4018143; Fri, 28 Apr 2023 08:57:20 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 33S8vKe1018142; Fri, 28 Apr 2023 08:57:20 GMT (envelope-from git) Date: Fri, 28 Apr 2023 08:57:20 GMT Message-Id: <202304280857.33S8vKe1018142@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dmitry Chagin Subject: git: cb858340dcbf - main - linux(4): Add a dedicated statat() implementation List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: dchagin X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: cb858340dcbf214cc4c4d78dbb741620d7b3a252 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=cb858340dcbf214cc4c4d78dbb741620d7b3a252 commit cb858340dcbf214cc4c4d78dbb741620d7b3a252 Author: Dmitry Chagin AuthorDate: 2023-04-28 08:55:04 +0000 Commit: Dmitry Chagin CommitDate: 2023-04-28 08:55:04 +0000 linux(4): Add a dedicated statat() implementation Get rid of calling Linux stat translation hook and specific to Linux handling of non-vnode dirfd from kern_statat(), Reviewed by: kib, mjg Differential revision: https://reviews.freebsd.org/D35474 --- sys/compat/freebsd32/freebsd32_misc.c | 19 ++++++++----------- sys/compat/linux/linux_file.c | 8 ++++---- sys/compat/linux/linux_stats.c | 34 ++++++++++++++++++++++++++++++++-- sys/kern/vfs_mountroot.c | 2 +- sys/kern/vfs_syscalls.c | 35 +++++++++++------------------------ sys/sys/syscallsubr.h | 4 ++-- 6 files changed, 58 insertions(+), 44 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 7e96dd9296ee..8b54b50a39c2 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -2284,8 +2284,7 @@ ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap) struct ostat32 sb32; int error; - error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, - &sb, NULL); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb); if (error) return (error); copy_ostat(&sb, &sb32); @@ -2334,7 +2333,7 @@ freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap) int error; error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, - &ub, NULL); + &ub); if (error) return (error); copy_stat(&ub, &ub32); @@ -2351,7 +2350,7 @@ ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap) int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, - UIO_USERSPACE, &sb, NULL); + UIO_USERSPACE, &sb); if (error) return (error); copy_ostat(&sb, &sb32); @@ -2469,8 +2468,7 @@ freebsd11_freebsd32_stat(struct thread *td, struct freebsd11_stat32 sb32; int error; - error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, - &sb, NULL); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtstat32(&sb, &sb32); @@ -2505,7 +2503,7 @@ freebsd11_freebsd32_fstatat(struct thread *td, int error; error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE, - &sb, NULL); + &sb); if (error != 0) return (error); error = freebsd11_cvtstat32(&sb, &sb32); @@ -2523,7 +2521,7 @@ freebsd11_freebsd32_lstat(struct thread *td, int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, - UIO_USERSPACE, &sb, NULL); + UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtstat32(&sb, &sb32); @@ -2595,8 +2593,7 @@ freebsd11_freebsd32_nstat(struct thread *td, struct nstat32 nsb; int error; - error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, - &sb, NULL); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtnstat32(&sb, &nsb); @@ -2614,7 +2611,7 @@ freebsd11_freebsd32_nlstat(struct thread *td, int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, - UIO_USERSPACE, &sb, NULL); + UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtnstat32(&sb, &nsb); diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index 5e2236dc7502..4ce0a2cb4c0e 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -732,7 +732,7 @@ linux_unlink(struct thread *td, struct linux_unlink_args *args) if (error == EPERM) { /* Introduce POSIX noncompliant behaviour of Linux */ if (kern_statat(td, 0, AT_FDCWD, args->path, - UIO_USERSPACE, &st, NULL) == 0) { + UIO_USERSPACE, &st) == 0) { if (S_ISDIR(st.st_mode)) error = EISDIR; } @@ -742,8 +742,8 @@ linux_unlink(struct thread *td, struct linux_unlink_args *args) error = kern_funlinkat(td, AT_FDCWD, path, FD_NONE, UIO_SYSSPACE, 0, 0); if (error == EPERM) { /* Introduce POSIX noncompliant behaviour of Linux */ - if (kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, - NULL) == 0) { + if (kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, + &st) == 0) { if (S_ISDIR(st.st_mode)) error = EISDIR; } @@ -769,7 +769,7 @@ linux_unlinkat_impl(struct thread *td, enum uio_seg pathseg, const char *path, if (error == EPERM && !(args->flag & LINUX_AT_REMOVEDIR)) { /* Introduce POSIX noncompliant behaviour of Linux */ if (kern_statat(td, AT_SYMLINK_NOFOLLOW, dfd, path, - pathseg, &st, NULL) == 0 && S_ISDIR(st.st_mode)) + pathseg, &st) == 0 && S_ISDIR(st.st_mode)) error = EISDIR; } return (error); diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index 58c378d6bc08..dc1e50a4fa00 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -29,17 +29,23 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_ktrace.h" + #include #include #include #include #include #include +#include #include #include #include #include #include +#ifdef KTRACE +#include +#endif #ifdef COMPAT_LINUX32 #include @@ -57,9 +63,33 @@ static int linux_kern_statat(struct thread *td, int flag, int fd, const char *path, enum uio_seg pathseg, struct stat *sbp) { + struct nameidata nd; + int error; + + if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_RESOLVE_BENEATH | + AT_EMPTY_PATH)) != 0) + return (EINVAL); + + NDINIT_ATRIGHTS(&nd, LOOKUP, at2cnpflags(flag, AT_RESOLVE_BENEATH | + AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH) | LOCKSHARED | LOCKLEAF | + AUDITVNODE1, pathseg, path, fd, &cap_fstat_rights); - return (kern_statat(td, flag, fd, path, pathseg, sbp, - translate_vnhook_major_minor)); + if ((error = namei(&nd)) != 0) { + if (error == ENOTDIR && + (nd.ni_resflags & NIRES_EMPTYPATH) != 0) + error = kern_fstat(td, fd, sbp); + return (error); + } + error = VOP_STAT(nd.ni_vp, sbp, td->td_ucred, NOCRED); + if (error == 0) + translate_vnhook_major_minor(nd.ni_vp, sbp); + NDFREE_PNBUF(&nd); + vput(nd.ni_vp); +#ifdef KTRACE + if (KTRPOINT(td, KTR_STRUCT)) + ktrstat_error(sbp, error); +#endif + return (error); } #ifdef LINUX_LEGACY_SYSCALLS diff --git a/sys/kern/vfs_mountroot.c b/sys/kern/vfs_mountroot.c index 79019c4bbc8e..956d29e3f084 100644 --- a/sys/kern/vfs_mountroot.c +++ b/sys/kern/vfs_mountroot.c @@ -594,7 +594,7 @@ parse_dir_md(char **conf) free(tok, M_TEMP); /* Get file status. */ - error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &sb, NULL); + error = kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &sb); if (error) goto out; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index fa5888ad836c..5c0a291e3b0b 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -110,7 +110,7 @@ static int kern_readlink_vp(struct vnode *vp, char *buf, enum uio_seg bufseg, static int kern_linkat_vp(struct thread *td, struct vnode *vp, int fd, const char *path, enum uio_seg segflag); -static uint64_t +uint64_t at2cnpflags(u_int at_flags, u_int mask) { uint64_t res; @@ -2193,8 +2193,7 @@ ostat(struct thread *td, struct ostat_args *uap) struct ostat osb; int error; - error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, - &sb, NULL); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb); if (error != 0) return (error); cvtstat(&sb, &osb); @@ -2218,7 +2217,7 @@ olstat(struct thread *td, struct olstat_args *uap) int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, - UIO_USERSPACE, &sb, NULL); + UIO_USERSPACE, &sb); if (error != 0) return (error); cvtstat(&sb, &osb); @@ -2336,8 +2335,7 @@ freebsd11_stat(struct thread *td, struct freebsd11_stat_args* uap) struct freebsd11_stat osb; int error; - error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, - &sb, NULL); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtstat(&sb, &osb); @@ -2354,7 +2352,7 @@ freebsd11_lstat(struct thread *td, struct freebsd11_lstat_args* uap) int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, - UIO_USERSPACE, &sb, NULL); + UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtstat(&sb, &osb); @@ -2391,7 +2389,7 @@ freebsd11_fstatat(struct thread *td, struct freebsd11_fstatat_args* uap) int error; error = kern_statat(td, uap->flag, uap->fd, uap->path, - UIO_USERSPACE, &sb, NULL); + UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtstat(&sb, &osb); @@ -2419,7 +2417,7 @@ sys_fstatat(struct thread *td, struct fstatat_args *uap) int error; error = kern_statat(td, uap->flag, uap->fd, uap->path, - UIO_USERSPACE, &sb, NULL); + UIO_USERSPACE, &sb); if (error == 0) error = copyout(&sb, uap->buf, sizeof (sb)); return (error); @@ -2427,8 +2425,7 @@ sys_fstatat(struct thread *td, struct fstatat_args *uap) int kern_statat(struct thread *td, int flag, int fd, const char *path, - enum uio_seg pathseg, struct stat *sbp, - void (*hook)(struct vnode *vp, struct stat *sbp)) + enum uio_seg pathseg, struct stat *sbp) { struct nameidata nd; int error; @@ -2441,18 +2438,9 @@ kern_statat(struct thread *td, int flag, int fd, const char *path, AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH) | LOCKSHARED | LOCKLEAF | AUDITVNODE1, pathseg, path, fd, &cap_fstat_rights); - if ((error = namei(&nd)) != 0) { - if (error == ENOTDIR && - (nd.ni_resflags & NIRES_EMPTYPATH) != 0) - error = kern_fstat(td, fd, sbp); + if ((error = namei(&nd)) != 0) return (error); - } error = VOP_STAT(nd.ni_vp, sbp, td->td_ucred, NOCRED); - if (__predict_false(hook != NULL)) { - if (error == 0) { - hook(nd.ni_vp, sbp); - } - } NDFREE_PNBUF(&nd); vput(nd.ni_vp); #ifdef __STAT_TIME_T_EXT @@ -2515,8 +2503,7 @@ freebsd11_nstat(struct thread *td, struct freebsd11_nstat_args *uap) struct nstat nsb; int error; - error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, - &sb, NULL); + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtnstat(&sb, &nsb); @@ -2542,7 +2529,7 @@ freebsd11_nlstat(struct thread *td, struct freebsd11_nlstat_args *uap) int error; error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, - UIO_USERSPACE, &sb, NULL); + UIO_USERSPACE, &sb); if (error != 0) return (error); error = freebsd11_cvtnstat(&sb, &nsb); diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h index 5520d1ea8f89..d91b2c18dbe0 100644 --- a/sys/sys/syscallsubr.h +++ b/sys/sys/syscallsubr.h @@ -81,6 +81,7 @@ struct mmap_req { mmap_check_fp_fn mr_check_fp_fn; }; +uint64_t at2cnpflags(u_int at_flags, u_int mask); int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, size_t buflen, size_t path_max); int kern_abort2(struct thread *td, const char *why, int nargs, @@ -319,8 +320,7 @@ int kern_sigqueue(struct thread *td, pid_t pid, int signum, union sigval *value); int kern_socket(struct thread *td, int domain, int type, int protocol); int kern_statat(struct thread *td, int flag, int fd, const char *path, - enum uio_seg pathseg, struct stat *sbp, - void (*hook)(struct vnode *vp, struct stat *sbp)); + enum uio_seg pathseg, struct stat *sbp); int kern_specialfd(struct thread *td, int type, void *arg); int kern_statfs(struct thread *td, const char *path, enum uio_seg pathseg, struct statfs *buf);