aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorBrooks Davis <brooks@FreeBSD.org>2021-11-22 22:36:56 +0000
committerBrooks Davis <brooks@FreeBSD.org>2021-11-22 22:36:56 +0000
commit6eefabd4ca40348f0bc0ab829bceb3a308e577b7 (patch)
treee3859170b99f3b7d17959d33a2d68008f644901a /sys/kern/vfs_syscalls.c
parent8460d3e9e6cbc78f4ae363b7894d765189b2ad44 (diff)
downloadsrc-6eefabd4ca40348f0bc0ab829bceb3a308e577b7.tar.gz
src-6eefabd4ca40348f0bc0ab829bceb3a308e577b7.zip
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
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c56
1 files changed, 35 insertions, 21 deletions
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 <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 */