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
This commit is contained in:
parent
8460d3e9e6
commit
6eefabd4ca
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -44,6 +44,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#ifdef COMPAT_FREEBSD11
|
||||
#include <sys/abi_compat.h>
|
||||
#endif
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/capsicum.h>
|
||||
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user