From nobody Mon Nov 22 22:37:40 2021 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 7DB411892C32; Mon, 22 Nov 2021 22:37:42 +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 4Hyhx13BrFz4YP0; Mon, 22 Nov 2021 22:37:41 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 2634D2EF2; Mon, 22 Nov 2021 22:37:40 +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 1AMMbeLG047068; Mon, 22 Nov 2021 22:37:40 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1AMMbe8B047067; Mon, 22 Nov 2021 22:37:40 GMT (envelope-from git) Date: Mon, 22 Nov 2021 22:37:40 GMT Message-Id: <202111222237.1AMMbe8B047067@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Brooks Davis Subject: git: 6eefabd4ca40 - main - syscalls: improve nstat, nfstat, nlstat 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: brooks X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6eefabd4ca40348f0bc0ab829bceb3a308e577b7 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by brooks: URL: https://cgit.FreeBSD.org/src/commit/?id=6eefabd4ca40348f0bc0ab829bceb3a308e577b7 commit 6eefabd4ca40348f0bc0ab829bceb3a308e577b7 Author: Brooks Davis AuthorDate: 2021-11-22 22:36:56 +0000 Commit: Brooks Davis CommitDate: 2021-11-22 22:36:56 +0000 syscalls: improve nstat, nfstat, nlstat Optionally return errors when truncating dev_t, ino_t, and nlink_t. In the interest of code reuse, use freebsd11_cvtstat() to perform the truncation and error handling and then convert the resulting struct freebsd11_stat to struct nstat. Add missing freebsd32 compat syscalls. These syscalls require translation because struct nstat contains four instances of struct timespec which in turn contains a time_t and a long. Reviewed by: kib --- sys/compat/freebsd32/freebsd32.h | 25 ++++++++++ sys/compat/freebsd32/freebsd32_misc.c | 87 +++++++++++++++++++++++++++++++++++ sys/compat/freebsd32/syscalls.master | 10 ++-- sys/kern/kern_descrip.c | 7 +-- sys/kern/vfs_syscalls.c | 56 +++++++++++++--------- sys/sys/vnode.h | 2 +- 6 files changed, 157 insertions(+), 30 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h index e5bb253aef78..4d5cea688a21 100644 --- a/sys/compat/freebsd32/freebsd32.h +++ b/sys/compat/freebsd32/freebsd32.h @@ -167,6 +167,31 @@ struct ostatfs32 { int32_t f_spare[2]; }; +struct nstat32 { + __uint32_t st_dev; /* inode's device */ + __uint32_t st_ino; /* inode's number */ + __uint32_t st_mode; /* inode protection mode */ + __uint32_t st_nlink; /* number of hard links */ + uid_t st_uid; /* user ID of the file's owner */ + gid_t st_gid; /* group ID of the file's group */ + __uint32_t st_rdev; /* device type */ + struct timespec32 st_atim; /* time of last access */ + struct timespec32 st_mtim; /* time of last data modification */ + struct timespec32 st_ctim; /* time of last file status change */ + off_t st_size; /* file size, in bytes */ + blkcnt_t st_blocks; /* blocks allocated for file */ + blksize_t st_blksize; /* optimal blocksize for I/O */ + fflags_t st_flags; /* user defined flags for file */ + __uint32_t st_gen; /* file generation number */ + struct timespec32 st_birthtim; /* time of file creation */ + /* + * See comment in the definition of struct freebsd11_stat + * in sys/stat.h about the following padding. + */ + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); + unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec32)); +}; + struct iovec32 { u_int32_t iov_base; int iov_len; diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 69ae3a1cd85d..e81148d3577c 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -2473,6 +2473,93 @@ freebsd11_freebsd32_fhstat(struct thread *td, error = copyout(&sb32, uap->sb, sizeof (sb32)); return (error); } + +static int +freebsd11_cvtnstat32(struct stat *sb, struct nstat32 *nsb32) +{ + struct nstat nsb; + int error; + + error = freebsd11_cvtnstat(sb, &nsb); + if (error != 0) + return (error); + + bzero(nsb32, sizeof(*nsb32)); + CP(nsb, *nsb32, st_dev); + CP(nsb, *nsb32, st_ino); + CP(nsb, *nsb32, st_mode); + CP(nsb, *nsb32, st_nlink); + CP(nsb, *nsb32, st_uid); + CP(nsb, *nsb32, st_gid); + CP(nsb, *nsb32, st_rdev); + CP(nsb, *nsb32, st_atim.tv_sec); + CP(nsb, *nsb32, st_atim.tv_nsec); + CP(nsb, *nsb32, st_mtim.tv_sec); + CP(nsb, *nsb32, st_mtim.tv_nsec); + CP(nsb, *nsb32, st_ctim.tv_sec); + CP(nsb, *nsb32, st_ctim.tv_nsec); + CP(nsb, *nsb32, st_size); + CP(nsb, *nsb32, st_blocks); + CP(nsb, *nsb32, st_blksize); + CP(nsb, *nsb32, st_flags); + CP(nsb, *nsb32, st_gen); + CP(nsb, *nsb32, st_birthtim.tv_sec); + CP(nsb, *nsb32, st_birthtim.tv_nsec); + return (0); +} + +int +freebsd11_freebsd32_nstat(struct thread *td, + struct freebsd11_freebsd32_nstat_args *uap) +{ + struct stat sb; + struct nstat32 nsb; + int error; + + error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE, + &sb, NULL); + if (error != 0) + return (error); + error = freebsd11_cvtnstat32(&sb, &nsb); + if (error != 0) + error = copyout(&nsb, uap->ub, sizeof (nsb)); + return (error); +} + +int +freebsd11_freebsd32_nlstat(struct thread *td, + struct freebsd11_freebsd32_nlstat_args *uap) +{ + struct stat sb; + struct nstat32 nsb; + int error; + + error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path, + UIO_USERSPACE, &sb, NULL); + if (error != 0) + return (error); + error = freebsd11_cvtnstat32(&sb, &nsb); + if (error == 0) + error = copyout(&nsb, uap->ub, sizeof (nsb)); + return (error); +} + +int +freebsd11_freebsd32_nfstat(struct thread *td, + struct freebsd11_freebsd32_nfstat_args *uap) +{ + struct nstat32 nub; + struct stat ub; + int error; + + error = kern_fstat(td, uap->fd, &ub); + if (error != 0) + return (error); + error = freebsd11_cvtnstat32(&ub, &nub); + if (error == 0) + error = copyout(&nub, uap->sb, sizeof(nub)); + return (error); +} #endif int diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 2e11fdb03a17..4fd7b2235d99 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -525,11 +525,11 @@ 276 AUE_LUTIMES STD { int freebsd32_lutimes(const char *path, \ const struct timeval32 *tptr); } 277 AUE_NULL OBSOL netbsd_msync -278 AUE_STAT COMPAT11|NOPROTO { int nstat(const char *path, \ - struct nstat *ub); } -279 AUE_FSTAT COMPAT11|NOPROTO { int nfstat(int fd, struct nstat *sb); } -280 AUE_LSTAT COMPAT11|NOPROTO { int nlstat(const char *path, \ - struct nstat *ub); } +278 AUE_STAT COMPAT11 { int freebsd32_nstat(const char *path, \ + struct nstat32 *ub); } +279 AUE_FSTAT COMPAT11 { int freebsd32_nfstat(int fd, struct nstat32 *sb); } +280 AUE_LSTAT COMPAT11 { int freebsd32_nlstat(const char *path, \ + struct nstat32 *ub); } 281 AUE_NULL RESERVED 282 AUE_NULL RESERVED 283 AUE_NULL RESERVED diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 37d978e96de5..37fec097dcfc 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1561,10 +1561,11 @@ freebsd11_nfstat(struct thread *td, struct freebsd11_nfstat_args *uap) int error; error = kern_fstat(td, uap->fd, &ub); - if (error == 0) { - freebsd11_cvtnstat(&ub, &nub); + if (error != 0) + return (error); + error = freebsd11_cvtnstat(&ub, &nub); + if (error != 0) error = copyout(&nub, uap->sb, sizeof(nub)); - } return (error); } #endif /* COMPAT_FREEBSD11 */ diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 1cffe903aef3..4391853337bd 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -44,6 +44,9 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef COMPAT_FREEBSD11 +#include +#endif #include #include #include @@ -2475,27 +2478,34 @@ kern_statat(struct thread *td, int flag, int fd, const char *path, /* * Implementation of the NetBSD [l]stat() functions. */ -void +int freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb) { + struct freebsd11_stat sb11; + int error; + + error = freebsd11_cvtstat(sb, &sb11); + if (error != 0) + return (error); bzero(nsb, sizeof(*nsb)); - nsb->st_dev = sb->st_dev; - nsb->st_ino = sb->st_ino; - nsb->st_mode = sb->st_mode; - nsb->st_nlink = sb->st_nlink; - nsb->st_uid = sb->st_uid; - nsb->st_gid = sb->st_gid; - nsb->st_rdev = sb->st_rdev; - nsb->st_atim = sb->st_atim; - nsb->st_mtim = sb->st_mtim; - nsb->st_ctim = sb->st_ctim; - nsb->st_size = sb->st_size; - nsb->st_blocks = sb->st_blocks; - nsb->st_blksize = sb->st_blksize; - nsb->st_flags = sb->st_flags; - nsb->st_gen = sb->st_gen; - nsb->st_birthtim = sb->st_birthtim; + CP(sb11, *nsb, st_dev); + CP(sb11, *nsb, st_ino); + CP(sb11, *nsb, st_mode); + CP(sb11, *nsb, st_nlink); + CP(sb11, *nsb, st_uid); + CP(sb11, *nsb, st_gid); + CP(sb11, *nsb, st_rdev); + CP(sb11, *nsb, st_atim); + CP(sb11, *nsb, st_mtim); + CP(sb11, *nsb, st_ctim); + CP(sb11, *nsb, st_size); + CP(sb11, *nsb, st_blocks); + CP(sb11, *nsb, st_blksize); + CP(sb11, *nsb, st_flags); + CP(sb11, *nsb, st_gen); + CP(sb11, *nsb, st_birthtim); + return (0); } #ifndef _SYS_SYSPROTO_H_ @@ -2515,8 +2525,10 @@ freebsd11_nstat(struct thread *td, struct freebsd11_nstat_args *uap) &sb, NULL); if (error != 0) return (error); - freebsd11_cvtnstat(&sb, &nsb); - return (copyout(&nsb, uap->ub, sizeof (nsb))); + error = freebsd11_cvtnstat(&sb, &nsb); + if (error == 0) + error = copyout(&nsb, uap->ub, sizeof (nsb)); + return (error); } /* @@ -2539,8 +2551,10 @@ freebsd11_nlstat(struct thread *td, struct freebsd11_nlstat_args *uap) UIO_USERSPACE, &sb, NULL); if (error != 0) return (error); - freebsd11_cvtnstat(&sb, &nsb); - return (copyout(&nsb, uap->ub, sizeof (nsb))); + error = freebsd11_cvtnstat(&sb, &nsb); + if (error == 0) + error = copyout(&nsb, uap->ub, sizeof (nsb)); + return (error); } #endif /* COMPAT_FREEBSD11 */ diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 1a202abfd4dd..3d04b6f68784 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -682,7 +682,7 @@ cache_validate(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) void cache_fast_lookup_enabled_recalc(void); int change_dir(struct vnode *vp, struct thread *td); void cvtstat(struct stat *st, struct ostat *ost); -void freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb); +int freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb); int freebsd11_cvtstat(struct stat *st, struct freebsd11_stat *ost); int getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops, struct vnode **vpp);