aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2017-05-23 09:29:05 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2017-05-23 09:29:05 +0000
commit69921123490b99c2588b0c743bc4af32bbe6601c (patch)
tree4828066c23bd9bbd1672af14fbf0a9e31e47f4a0 /sys
parent5f7c516f216995249523ed43e57e3f91bd8f5ff0 (diff)
Commit the 64-bit inode project.
Extend the ino_t, dev_t, nlink_t types to 64-bit ints. Modify struct dirent layout to add d_off, increase the size of d_fileno to 64-bits, increase the size of d_namlen to 16-bits, and change the required alignment. Increase struct statfs f_mntfromname[] and f_mntonname[] array length MNAMELEN to 1024. ABI breakage is mitigated by providing compatibility using versioned symbols, ingenious use of the existing padding in structures, and by employing other tricks. Unfortunately, not everything can be fixed, especially outside the base system. For instance, third-party APIs which pass struct stat around are broken in backward and forward incompatible ways. Kinfo sysctl MIBs ABI is changed in backward-compatible way, but there is no general mechanism to handle other sysctl MIBS which return structures where the layout has changed. It was considered that the breakage is either in the management interfaces, where we usually allow ABI slip, or is not important. Struct xvnode changed layout, no compat shims are provided. For struct xtty, dev_t tty device member was reduced to uint32_t. It was decided that keeping ABI compat in this case is more useful than reporting 64-bit dev_t, for the sake of pstat. Update note: strictly follow the instructions in UPDATING. Build and install the new kernel with COMPAT_FREEBSD11 option enabled, then reboot, and only then install new world. Credits: The 64-bit inode project, also known as ino64, started life many years ago as a project by Gleb Kurtsou (gleb). Kirk McKusick (mckusick) then picked up and updated the patch, and acted as a flag-waver. Feedback, suggestions, and discussions were carried by Ed Maste (emaste), John Baldwin (jhb), Jilles Tjoelker (jilles), and Rick Macklem (rmacklem). Kris Moore (kris) performed an initial ports investigation followed by an exp-run by Antoine Brodin (antoine). Essential and all-embracing testing was done by Peter Holm (pho). The heavy lifting of coordinating all these efforts and bringing the project to completion were done by Konstantin Belousov (kib). Sponsored by: The FreeBSD Foundation (emaste, kib) Differential revision: https://reviews.freebsd.org/D10439
Notes
svn path=/head/; revision=318736
Diffstat (limited to 'sys')
-rw-r--r--sys/bsm/audit.h4
-rw-r--r--sys/cddl/compat/opensolaris/sys/dirent.h4
-rw-r--r--sys/compat/freebsd32/capabilities.conf5
-rw-r--r--sys/compat/freebsd32/freebsd32.h57
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c214
-rw-r--r--sys/compat/freebsd32/syscalls.master77
-rw-r--r--sys/compat/linux/linux_file.c28
-rw-r--r--sys/dev/snp/snp.c8
-rw-r--r--sys/fs/devfs/devfs_devs.c14
-rw-r--r--sys/fs/devfs/devfs_vnops.c1
-rw-r--r--sys/fs/fdescfs/fdesc_vnops.c2
-rw-r--r--sys/fs/nandfs/nandfs_fs.h2
-rw-r--r--sys/fs/nfs/nfsport.h6
-rw-r--r--sys/fs/nfsclient/nfs_clrpcops.c68
-rw-r--r--sys/fs/nfsclient/nfs_clvnops.c2
-rw-r--r--sys/fs/nfsserver/nfs_nfsdport.c39
-rw-r--r--sys/kern/capabilities.conf5
-rw-r--r--sys/kern/kern_acct.c9
-rw-r--r--sys/kern/kern_descrip.c53
-rw-r--r--sys/kern/kern_proc.c11
-rw-r--r--sys/kern/makesyscalls.sh37
-rw-r--r--sys/kern/sys_socket.c21
-rw-r--r--sys/kern/syscalls.master64
-rw-r--r--sys/kern/tty.c2
-rw-r--r--sys/kern/tty_pts.c2
-rw-r--r--sys/kern/vfs_syscalls.c602
-rw-r--r--sys/kern/vfs_vnops.c6
-rw-r--r--sys/nlm/nlm_advlock.c5
-rw-r--r--sys/security/audit/audit_private.h8
-rw-r--r--sys/sys/_types.h6
-rw-r--r--sys/sys/acct.h35
-rw-r--r--sys/sys/dirent.h43
-rw-r--r--sys/sys/mount.h32
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/stat.h63
-rw-r--r--sys/sys/syscallsubr.h11
-rw-r--r--sys/sys/tty.h2
-rw-r--r--sys/sys/user.h74
-rw-r--r--sys/sys/vnode.h9
-rw-r--r--sys/vm/swap_pager.c27
-rw-r--r--sys/vm/vm_object.c3
-rw-r--r--sys/vm/vm_param.h2
42 files changed, 1216 insertions, 449 deletions
diff --git a/sys/bsm/audit.h b/sys/bsm/audit.h
index af9622af314e..57edb5e4e83f 100644
--- a/sys/bsm/audit.h
+++ b/sys/bsm/audit.h
@@ -183,13 +183,13 @@ typedef u_int32_t au_class_t;
typedef u_int64_t au_asflgs_t __attribute__ ((aligned (8)));
struct au_tid {
- dev_t port;
+ u_int32_t port; /* XXX dev_t compatibility */
u_int32_t machine;
};
typedef struct au_tid au_tid_t;
struct au_tid_addr {
- dev_t at_port;
+ u_int32_t at_port; /* XXX dev_t compatibility */
u_int32_t at_type;
u_int32_t at_addr[4];
};
diff --git a/sys/cddl/compat/opensolaris/sys/dirent.h b/sys/cddl/compat/opensolaris/sys/dirent.h
index d273f8a0fce4..81ea4fa3a97f 100644
--- a/sys/cddl/compat/opensolaris/sys/dirent.h
+++ b/sys/cddl/compat/opensolaris/sys/dirent.h
@@ -40,8 +40,6 @@ typedef ino_t ino64_t;
#define d_ino d_fileno
-#define DIRENT64_RECLEN(len) ((sizeof(struct dirent) - \
- sizeof(((struct dirent *)NULL)->d_name) + \
- (len) + 1 + 3) & ~3)
+#define DIRENT64_RECLEN(len) _GENERIC_DIRLEN(len)
#endif /* !_OPENSOLARIS_SYS_DIRENT_H_ */
diff --git a/sys/compat/freebsd32/capabilities.conf b/sys/compat/freebsd32/capabilities.conf
index 6d815f1ab522..1a5670cade91 100644
--- a/sys/compat/freebsd32/capabilities.conf
+++ b/sys/compat/freebsd32/capabilities.conf
@@ -94,6 +94,11 @@ freebsd32_fexecve
flock
fork
fpathconf
+freebsd11_freebsd32_fstat
+freebsd11_freebsd32_fstatat
+freebsd11_freebsd32_getdirentries
+freebsd11_freebsd32_fstatfs
+freebsd11_freebsd32_mknodat
freebsd6_freebsd32_ftruncate
freebsd6_freebsd32_lseek
freebsd6_freebsd32_mmap
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index 39213aec94d3..05447da3696b 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -107,7 +107,8 @@ struct itimerval32 {
struct timeval32 it_value;
};
-#define FREEBSD4_MNAMELEN (88 - 2 * sizeof(int32_t)) /* size of on/from name bufs */
+#define FREEBSD4_MFSNAMELEN 16
+#define FREEBSD4_MNAMELEN (88 - 2 * sizeof(int32_t))
/* 4.x version */
struct statfs32 {
@@ -125,7 +126,7 @@ struct statfs32 {
int32_t f_flags;
int32_t f_syncwrites;
int32_t f_asyncwrites;
- char f_fstypename[MFSNAMELEN];
+ char f_fstypename[FREEBSD4_MFSNAMELEN];
char f_mntonname[FREEBSD4_MNAMELEN];
int32_t f_syncreads;
int32_t f_asyncreads;
@@ -159,14 +160,51 @@ struct msghdr32 {
int msg_flags;
};
+#if defined(__amd64__)
+#define __STAT32_TIME_T_EXT 1
+#endif
+
struct stat32 {
- dev_t st_dev;
- ino_t st_ino;
+ dev_t st_dev;
+ ino_t st_ino;
+ nlink_t st_nlink;
+ mode_t st_mode;
+ u_int16_t st_padding0;
+ uid_t st_uid;
+ gid_t st_gid;
+ u_int32_t st_padding1;
+ dev_t st_rdev;
+#ifdef __STAT32_TIME_T_EXT
+ __int32_t st_atim_ext;
+#endif
+ struct timespec32 st_atim;
+#ifdef __STAT32_TIME_T_EXT
+ __int32_t st_mtim_ext;
+#endif
+ struct timespec32 st_mtim;
+#ifdef __STAT32_TIME_T_EXT
+ __int32_t st_ctim_ext;
+#endif
+ struct timespec32 st_ctim;
+#ifdef __STAT32_TIME_T_EXT
+ __int32_t st_btim_ext;
+#endif
+ struct timespec32 st_birthtim;
+ off_t st_size;
+ int64_t st_blocks;
+ u_int32_t st_blksize;
+ u_int32_t st_flags;
+ u_int64_t st_gen;
+ u_int64_t st_spare[10];
+};
+struct freebsd11_stat32 {
+ u_int32_t st_dev;
+ u_int32_t st_ino;
mode_t st_mode;
- nlink_t st_nlink;
+ u_int16_t st_nlink;
uid_t st_uid;
gid_t st_gid;
- dev_t st_rdev;
+ u_int32_t st_rdev;
struct timespec32 st_atim;
struct timespec32 st_mtim;
struct timespec32 st_ctim;
@@ -183,9 +221,9 @@ struct stat32 {
struct ostat32 {
__uint16_t st_dev;
- ino_t st_ino;
+ __uint32_t st_ino;
mode_t st_mode;
- nlink_t st_nlink;
+ __uint16_t st_nlink;
__uint16_t st_uid;
__uint16_t st_gid;
__uint16_t st_rdev;
@@ -270,7 +308,7 @@ struct kinfo_proc32 {
pid_t ki_tsid;
short ki_jobc;
short ki_spare_short1;
- dev_t ki_tdev;
+ uint32_t ki_tdev_freebsd11;
sigset_t ki_siglist;
sigset_t ki_sigmask;
sigset_t ki_sigignore;
@@ -318,6 +356,7 @@ struct kinfo_proc32 {
char ki_moretdname[MAXCOMLEN-TDNAMLEN+1];
char ki_sparestrings[46];
int ki_spareints[KI_NSPARE_INT];
+ uint64_t ki_tdev;
int ki_oncpu;
int ki_lastcpu;
int ki_tracer;
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index a8e69b731fe7..d73f95f3d071 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -122,8 +122,11 @@ CTASSERT(sizeof(struct sigaltstack32) == 12);
CTASSERT(sizeof(struct kevent32) == 20);
CTASSERT(sizeof(struct iovec32) == 8);
CTASSERT(sizeof(struct msghdr32) == 28);
+#ifdef __amd64__
+CTASSERT(sizeof(struct stat32) == 208);
+#endif
#ifndef __mips__
-CTASSERT(sizeof(struct stat32) == 96);
+CTASSERT(sizeof(struct freebsd11_stat32) == 96);
#endif
CTASSERT(sizeof(struct sigaction32) == 24);
@@ -448,6 +451,26 @@ freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap)
return (error);
}
+#if defined(COMPAT_FREEBSD11)
+int
+freebsd11_freebsd32_mknod(struct thread *td,
+ struct freebsd11_freebsd32_mknod_args *uap)
+{
+
+ return (kern_mknodat(td, AT_FDCWD, uap->path, UIO_USERSPACE, uap->mode,
+ uap->dev));
+}
+
+int
+freebsd11_freebsd32_mknodat(struct thread *td,
+ struct freebsd11_freebsd32_mknodat_args *uap)
+{
+
+ return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode,
+ uap->dev));
+}
+#endif /* COMPAT_FREEBSD11 */
+
int
freebsd32_mprotect(struct thread *td, struct freebsd32_mprotect_args *uap)
{
@@ -1519,6 +1542,40 @@ ofreebsd32_getdirentries(struct thread *td,
}
#endif
+#if defined(COMPAT_FREEBSD11)
+int
+freebsd11_freebsd32_getdirentries(struct thread *td,
+ struct freebsd11_freebsd32_getdirentries_args *uap)
+{
+ long base;
+ int32_t base32;
+ int error;
+
+ error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
+ &base, NULL);
+ if (error)
+ return (error);
+ if (uap->basep != NULL) {
+ base32 = base;
+ error = copyout(&base32, uap->basep, sizeof(int32_t));
+ }
+ return (error);
+}
+
+int
+freebsd11_freebsd32_getdents(struct thread *td,
+ struct freebsd11_freebsd32_getdents_args *uap)
+{
+ struct freebsd11_freebsd32_getdirentries_args ap;
+
+ ap.fd = uap->fd;
+ ap.buf = uap->buf;
+ ap.count = uap->count;
+ ap.basep = NULL;
+ return (freebsd11_freebsd32_getdirentries(td, &ap));
+}
+#endif /* COMPAT_FREEBSD11 */
+
int
freebsd32_getdirentries(struct thread *td,
struct freebsd32_getdirentries_args *uap)
@@ -1709,6 +1766,15 @@ copy_stat(struct stat *in, struct stat32 *out)
CP(*in, *out, st_flags);
CP(*in, *out, st_gen);
TS_CP(*in, *out, st_birthtim);
+ out->st_padding0 = 0;
+ out->st_padding1 = 0;
+#ifdef __STAT32_TIME_T_EXT
+ out->st_atim_ext = 0;
+ out->st_mtim_ext = 0;
+ out->st_ctim_ext = 0;
+ out->st_btim_ext = 0;
+#endif
+ bzero(out->st_spare, sizeof(out->st_spare));
}
#ifdef COMPAT_43
@@ -1734,22 +1800,6 @@ copy_ostat(struct stat *in, struct ostat32 *out)
}
#endif
-int
-freebsd32_stat(struct thread *td, struct freebsd32_stat_args *uap)
-{
- struct stat sb;
- struct stat32 sb32;
- int error;
-
- error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE,
- &sb, NULL);
- if (error)
- return (error);
- copy_stat(&sb, &sb32);
- error = copyout(&sb32, uap->ub, sizeof (sb32));
- return (error);
-}
-
#ifdef COMPAT_43
int
ofreebsd32_stat(struct thread *td, struct ofreebsd32_stat_args *uap)
@@ -1816,38 +1866,156 @@ freebsd32_fstatat(struct thread *td, struct freebsd32_fstatat_args *uap)
return (error);
}
+#ifdef COMPAT_43
int
-freebsd32_lstat(struct thread *td, struct freebsd32_lstat_args *uap)
+ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
{
struct stat sb;
- struct stat32 sb32;
+ struct ostat32 sb32;
int error;
error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
UIO_USERSPACE, &sb, NULL);
if (error)
return (error);
+ copy_ostat(&sb, &sb32);
+ error = copyout(&sb32, uap->ub, sizeof (sb32));
+ return (error);
+}
+#endif
+
+int
+freebsd32_fhstat(struct thread *td, struct freebsd32_fhstat_args *uap)
+{
+ struct stat sb;
+ struct stat32 sb32;
+ struct fhandle fh;
+ int error;
+
+ error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
+ if (error != 0)
+ return (error);
+ error = kern_fhstat(td, fh, &sb);
+ if (error != 0)
+ return (error);
copy_stat(&sb, &sb32);
+ error = copyout(&sb32, uap->sb, sizeof (sb32));
+ return (error);
+}
+
+#if defined(COMPAT_FREEBSD11)
+static void
+freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out)
+{
+
+ CP(*in, *out, st_ino);
+ CP(*in, *out, st_nlink);
+ CP(*in, *out, st_dev);
+ CP(*in, *out, st_mode);
+ CP(*in, *out, st_uid);
+ CP(*in, *out, st_gid);
+ CP(*in, *out, st_rdev);
+ TS_CP(*in, *out, st_atim);
+ TS_CP(*in, *out, st_mtim);
+ TS_CP(*in, *out, st_ctim);
+ CP(*in, *out, st_size);
+ CP(*in, *out, st_blocks);
+ CP(*in, *out, st_blksize);
+ CP(*in, *out, st_flags);
+ CP(*in, *out, st_gen);
+ TS_CP(*in, *out, st_birthtim);
+ out->st_lspare = 0;
+ bzero((char *)&out->st_birthtim + sizeof(out->st_birthtim),
+ sizeof(*out) - offsetof(struct freebsd11_stat32,
+ st_birthtim) - sizeof(out->st_birthtim));
+}
+
+int
+freebsd11_freebsd32_stat(struct thread *td,
+ struct freebsd11_freebsd32_stat_args *uap)
+{
+ struct stat sb;
+ struct freebsd11_stat32 sb32;
+ int error;
+
+ error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE,
+ &sb, NULL);
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat32(&sb, &sb32);
error = copyout(&sb32, uap->ub, sizeof (sb32));
return (error);
}
-#ifdef COMPAT_43
int
-ofreebsd32_lstat(struct thread *td, struct ofreebsd32_lstat_args *uap)
+freebsd11_freebsd32_fstat(struct thread *td,
+ struct freebsd11_freebsd32_fstat_args *uap)
{
struct stat sb;
- struct ostat32 sb32;
+ struct freebsd11_stat32 sb32;
+ int error;
+
+ error = kern_fstat(td, uap->fd, &sb);
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat32(&sb, &sb32);
+ error = copyout(&sb32, uap->ub, sizeof (sb32));
+ return (error);
+}
+
+int
+freebsd11_freebsd32_fstatat(struct thread *td,
+ struct freebsd11_freebsd32_fstatat_args *uap)
+{
+ struct stat sb;
+ struct freebsd11_stat32 sb32;
+ int error;
+
+ error = kern_statat(td, uap->flag, uap->fd, uap->path, UIO_USERSPACE,
+ &sb, NULL);
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat32(&sb, &sb32);
+ error = copyout(&sb32, uap->buf, sizeof (sb32));
+ return (error);
+}
+
+int
+freebsd11_freebsd32_lstat(struct thread *td,
+ struct freebsd11_freebsd32_lstat_args *uap)
+{
+ struct stat sb;
+ struct freebsd11_stat32 sb32;
int error;
error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
UIO_USERSPACE, &sb, NULL);
if (error)
return (error);
- copy_ostat(&sb, &sb32);
+ freebsd11_cvtstat32(&sb, &sb32);
error = copyout(&sb32, uap->ub, sizeof (sb32));
return (error);
}
+
+int
+freebsd11_freebsd32_fhstat(struct thread *td,
+ struct freebsd11_freebsd32_fhstat_args *uap)
+{
+ struct stat sb;
+ struct freebsd11_stat32 sb32;
+ struct fhandle fh;
+ int error;
+
+ error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
+ if (error != 0)
+ return (error);
+ error = kern_fhstat(td, fh, &sb);
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat32(&sb, &sb32);
+ error = copyout(&sb32, uap->sb, sizeof (sb32));
+ return (error);
+}
#endif
int
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index ac624e4f7df2..fce75fe3488a 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -13,7 +13,7 @@
; case where the event exists, but we don't want auditing, the
; event should be #defined to AUE_NULL in audit_kevents.h.
; type one of STD, OBSOL, UNIMPL, COMPAT, COMPAT4, COMPAT6,
-; COMPAT7, NODEF, NOARGS, NOPROTO, NOSTD
+; COMPAT7, COMPAT11, NODEF, NOARGS, NOPROTO, NOSTD
; The COMPAT* options may be combined with one or more NO*
; options separated by '|' with no spaces (e.g. COMPAT|NOARGS)
; name psuedo-prototype of syscall routine
@@ -30,6 +30,7 @@
; COMPAT6 included on COMPAT6 #ifdef (FreeBSD 6 compat)
; COMPAT7 included on COMPAT7 #ifdef (FreeBSD 7 compat)
; COMPAT10 included on COMPAT10 #ifdef (FreeBSD 10 compat)
+; COMPAT11 included on COMPAT11 #ifdef (FreeBSD 11 compat)
; OBSOL obsolete, not included in system, only specifies name
; UNIMPL not implemented, placeholder only
; NOSTD implemented but as a lkm that can be statically
@@ -82,7 +83,8 @@
11 AUE_NULL OBSOL execv
12 AUE_CHDIR NOPROTO { int chdir(char *path); }
13 AUE_FCHDIR NOPROTO { int fchdir(int fd); }
-14 AUE_MKNOD NOPROTO { int mknod(char *path, int mode, int dev); }
+14 AUE_MKNOD COMPAT11 { int freebsd32_mknod(char *path, \
+ int mode, int dev); }
15 AUE_CHMOD NOPROTO { int chmod(char *path, int mode); }
16 AUE_CHOWN NOPROTO { int chown(char *path, int uid, int gid); }
17 AUE_NULL NOPROTO { int obreak(char *nsize); } break \
@@ -348,12 +350,12 @@
185 AUE_NULL UNIMPL lfs_markv
186 AUE_NULL UNIMPL lfs_segclean
187 AUE_NULL UNIMPL lfs_segwait
-188 AUE_STAT STD { int freebsd32_stat(char *path, \
- struct stat32 *ub); }
-189 AUE_FSTAT STD { int freebsd32_fstat(int fd, \
- struct stat32 *ub); }
-190 AUE_LSTAT STD { int freebsd32_lstat(char *path, \
- struct stat32 *ub); }
+188 AUE_STAT COMPAT11 { int freebsd32_stat(char *path, \
+ struct freebsd11_stat32 *ub); }
+189 AUE_FSTAT COMPAT11 { int freebsd32_fstat(int fd, \
+ struct freebsd11_stat32 *ub); }
+190 AUE_LSTAT COMPAT11 { int freebsd32_lstat(char *path, \
+ struct freebsd11_stat32 *ub); }
191 AUE_PATHCONF NOPROTO { int pathconf(char *path, int name); }
192 AUE_FPATHCONF NOPROTO { int fpathconf(int fd, int name); }
193 AUE_NULL UNIMPL nosys
@@ -363,7 +365,7 @@
195 AUE_SETRLIMIT NOPROTO { int setrlimit(u_int which, \
struct rlimit *rlp); } setrlimit \
__setrlimit_args int
-196 AUE_GETDIRENTRIES STD { int freebsd32_getdirentries(int fd, \
+196 AUE_GETDIRENTRIES COMPAT11 { int freebsd32_getdirentries(int fd, \
char *buf, u_int count, int32_t *basep); }
197 AUE_MMAP COMPAT6 { caddr_t freebsd32_mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
@@ -501,8 +503,8 @@
269 AUE_NULL UNIMPL nosys
270 AUE_NULL UNIMPL nosys
271 AUE_NULL UNIMPL nosys
-272 AUE_O_GETDENTS NOPROTO { int getdents(int fd, char *buf, \
- size_t count); }
+272 AUE_O_GETDENTS COMPAT11 { int freebsd32_getdents(int fd, char *buf, \
+ int count); }
273 AUE_NULL UNIMPL nosys
274 AUE_LCHMOD NOPROTO { int lchmod(char *path, mode_t mode); }
275 AUE_LCHOWN NOPROTO { int lchown(char *path, uid_t uid, \
@@ -512,9 +514,9 @@
struct timeval32 *tptr); }
277 AUE_MSYNC NOPROTO { int msync(void *addr, size_t len, \
int flags); } netbsd_msync msync_args int
-278 AUE_STAT NOPROTO { int nstat(char *path, struct nstat *ub); }
-279 AUE_FSTAT NOPROTO { int nfstat(int fd, struct nstat *sb); }
-280 AUE_LSTAT NOPROTO { int nlstat(char *path, struct nstat *ub); }
+278 AUE_STAT COMPAT11|NOPROTO { int nstat(char *path, struct nstat *ub); }
+279 AUE_FSTAT COMPAT11|NOPROTO { int nfstat(int fd, struct nstat *sb); }
+280 AUE_LSTAT COMPAT11|NOPROTO { int nlstat(char *path, struct nstat *ub); }
281 AUE_NULL UNIMPL nosys
282 AUE_NULL UNIMPL nosys
283 AUE_NULL UNIMPL nosys
@@ -544,8 +546,9 @@
struct statfs32 *buf); }
298 AUE_FHOPEN NOPROTO { int fhopen(const struct fhandle *u_fhp, \
int flags); }
-299 AUE_FHSTAT NOPROTO { int fhstat(const struct fhandle *u_fhp, \
- struct stat *sb); }
+299 AUE_FHSTAT COMPAT11 { int freebsd32_fhstat( \
+ const struct fhandle *u_fhp, \
+ struct freebsd11_stat32 *sb); }
; syscall numbers for FreeBSD
300 AUE_NULL NOPROTO { int modnext(int modid); }
301 AUE_NULL STD { int freebsd32_modstat(int modid, \
@@ -713,13 +716,16 @@
size_t nbytes, struct sf_hdtr32 *hdtr, \
off_t *sbytes, int flags); }
394 AUE_NULL UNIMPL mac_syscall
-395 AUE_GETFSSTAT NOPROTO { int getfsstat(struct statfs *buf, \
+395 AUE_GETFSSTAT COMPAT11|NOPROTO { int getfsstat( \
+ struct freebsd11_statfs *buf, \
long bufsize, int mode); }
-396 AUE_STATFS NOPROTO { int statfs(char *path, \
- struct statfs *buf); }
-397 AUE_FSTATFS NOPROTO { int fstatfs(int fd, struct statfs *buf); }
-398 AUE_FHSTATFS NOPROTO { int fhstatfs(const struct fhandle *u_fhp, \
+396 AUE_STATFS COMPAT11|NOPROTO { int statfs(char *path, \
struct statfs *buf); }
+397 AUE_FSTATFS COMPAT11|NOPROTO { int fstatfs(int fd, \
+ struct freebsd11_statfs *buf); }
+398 AUE_FHSTATFS COMPAT11|NOPROTO { int fhstatfs( \
+ const struct fhandle *u_fhp, \
+ struct freebsd11_statfs *buf); }
399 AUE_NULL UNIMPL nosys
400 AUE_SEMCLOSE NOSTD|NOPROTO { int ksem_close(semid_t id); }
401 AUE_SEMPOST NOSTD|NOPROTO { int ksem_post(semid_t id); }
@@ -936,8 +942,9 @@
gid_t gid, int flag); }
492 AUE_FEXECVE STD { int freebsd32_fexecve(int fd, \
uint32_t *argv, uint32_t *envv); }
-493 AUE_FSTATAT STD { int freebsd32_fstatat(int fd, char *path, \
- struct stat *buf, int flag); }
+493 AUE_FSTATAT COMPAT11 { int freebsd32_fstatat(int fd, \
+ char *path, struct freebsd11_stat32 *buf, \
+ int flag); }
494 AUE_FUTIMESAT STD { int freebsd32_futimesat(int fd, char *path, \
struct timeval *times); }
495 AUE_LINKAT NOPROTO { int linkat(int fd1, char *path1, int fd2, \
@@ -946,8 +953,8 @@
mode_t mode); }
497 AUE_MKFIFOAT NOPROTO { int mkfifoat(int fd, char *path, \
mode_t mode); }
-498 AUE_MKNODAT NOPROTO { int mknodat(int fd, char *path, \
- mode_t mode, dev_t dev); }
+498 AUE_MKNODAT COMPAT11 { int freebsd32_mknodat(int fd, char *path, \
+ mode_t mode, uint32_t dev); }
499 AUE_OPENAT_RWTC NOPROTO { int openat(int fd, char *path, int flag, \
mode_t mode); }
500 AUE_READLINKAT NOPROTO { int readlinkat(int fd, char *path, char *buf, \
@@ -1084,3 +1091,23 @@
id_t id, \
const struct vm_domain_policy *policy); }
550 AUE_FSYNC NOPROTO { int fdatasync(int fd); }
+551 AUE_FSTAT STD { int freebsd32_fstat(int fd, \
+ struct stat32 *ub); }
+552 AUE_FSTATAT STD { int freebsd32_fstatat(int fd, \
+ char *path, struct stat32 *buf, \
+ int flag); }
+553 AUE_FHSTAT STD { int freebsd32_fhstat( \
+ const struct fhandle *u_fhp, \
+ struct stat32 *sb); }
+554 AUE_GETDIRENTRIES STD { ssize_t freebsd32_getdirentries( \
+ int fd, char *buf, size_t count, \
+ int32_t *basep); }
+555 AUE_STATFS NOPROTO { int statfs(char *path, \
+ struct statfs32 *buf); }
+556 AUE_FSTATFS NOPROTO { int fstatfs(int fd, struct statfs32 *buf); }
+557 AUE_GETFSSTAT NOPROTO { int getfsstat(struct statfs32 *buf, \
+ long bufsize, int mode); }
+558 AUE_FHSTATFS NOPROTO { int fhstatfs(const struct fhandle *u_fhp, \
+ struct statfs32 *buf); }
+559 AUE_MKNODAT NOPROTO { int mknodat(int fd, char *path, mode_t mode, \
+ dev_t dev); }
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 6480fc823a55..4bacee37df38 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -328,7 +328,7 @@ linux_getdents(struct thread *td, struct linux_getdents_args *args)
caddr_t outp; /* Linux-format */
int resid, linuxreclen; /* Linux-format */
caddr_t lbuf; /* Linux-format */
- long base;
+ off_t base;
struct l_dirent *linux_dirent;
int buflen, error;
size_t retval;
@@ -409,7 +409,7 @@ linux_getdents64(struct thread *td, struct linux_getdents64_args *args)
caddr_t outp; /* Linux-format */
int resid, linuxreclen; /* Linux-format */
caddr_t lbuf; /* Linux-format */
- long base;
+ off_t base;
struct l_dirent64 *linux_dirent64;
int buflen, error;
size_t retval;
@@ -486,7 +486,7 @@ linux_readdir(struct thread *td, struct linux_readdir_args *args)
caddr_t buf; /* BSD-format */
int linuxreclen; /* Linux-format */
caddr_t lbuf; /* Linux-format */
- long base;
+ off_t base;
struct l_dirent *linux_dirent;
int buflen, error;
@@ -1087,20 +1087,21 @@ int
linux_mount(struct thread *td, struct linux_mount_args *args)
{
char fstypename[MFSNAMELEN];
- char mntonname[MNAMELEN], mntfromname[MNAMELEN];
- int error;
- int fsflags;
+ char *mntonname, *mntfromname;
+ int error, fsflags;
+ mntonname = malloc(MNAMELEN, M_TEMP, M_WAITOK);
+ mntfromname = malloc(MNAMELEN, M_TEMP, M_WAITOK);
error = copyinstr(args->filesystemtype, fstypename, MFSNAMELEN - 1,
NULL);
- if (error)
- return (error);
+ if (error != 0)
+ goto out;
error = copyinstr(args->specialfile, mntfromname, MNAMELEN - 1, NULL);
- if (error)
- return (error);
+ if (error != 0)
+ goto out;
error = copyinstr(args->dir, mntonname, MNAMELEN - 1, NULL);
- if (error)
- return (error);
+ if (error != 0)
+ goto out;
#ifdef DEBUG
if (ldebug(mount))
@@ -1138,6 +1139,9 @@ linux_mount(struct thread *td, struct linux_mount_args *args)
"fspath", mntonname,
"from", mntfromname,
NULL);
+out:
+ free(mntonname, M_TEMP);
+ free(mntfromname, M_TEMP);
return (error);
}
diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c
index 1c02660bec1d..84260182265c 100644
--- a/sys/dev/snp/snp.c
+++ b/sys/dev/snp/snp.c
@@ -60,6 +60,8 @@ SX_SYSINIT(snp_register_lock, &snp_register_lock,
#define SNP_UNLOCK() sx_xunlock(&snp_register_lock)
#endif
+#define SNPGTYY_32DEV _IOR('T', 89, uint32_t)
+
/*
* There is no need to have a big input buffer. In most typical setups,
* we won't inject much data into the TTY, because users can't type
@@ -275,6 +277,12 @@ snp_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags,
else
*(dev_t *)data = tty_udev(ss->snp_tty);
return (0);
+ case SNPGTYY_32DEV:
+ if (ss->snp_tty == NULL)
+ *(uint32_t *)data = -1;
+ else
+ *(uint32_t *)data = tty_udev(ss->snp_tty); /* trunc */
+ return (0);
case FIONREAD:
tp = ss->snp_tty;
if (tp != NULL) {
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c
index e600ff1cea47..695d3315cca6 100644
--- a/sys/fs/devfs/devfs_devs.c
+++ b/sys/fs/devfs/devfs_devs.c
@@ -28,6 +28,8 @@
* $FreeBSD$
*/
+#include "opt_compat.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
@@ -80,10 +82,20 @@ sysctl_devname(SYSCTL_HANDLER_ARGS)
{
int error;
dev_t ud;
+#ifdef COMPAT_FREEBSD11
+ uint32_t ud_compat;
+#endif
struct cdev_priv *cdp;
struct cdev *dev;
- error = SYSCTL_IN(req, &ud, sizeof (ud));
+#ifdef COMPAT_FREEBSD11
+ if (req->newlen == sizeof(ud_compat)) {
+ error = SYSCTL_IN(req, &ud_compat, sizeof(ud_compat));
+ if (error == 0)
+ ud = ud_compat == (uint32_t)NODEV ? NODEV : ud_compat;
+ } else
+#endif
+ error = SYSCTL_IN(req, &ud, sizeof (ud));
if (error)
return (error);
if (ud == NODEV)
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 49435608e2da..18b962eadffc 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -1315,6 +1315,7 @@ devfs_readdir(struct vop_readdir_args *ap)
else
de = dd;
dp = dd->de_dirent;
+ MPASS(dp->d_reclen == GENERIC_DIRSIZ(dp));
if (dp->d_reclen > uio->uio_resid)
break;
dp->d_fileno = de->de_inode;
diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c
index 65b8a54657be..885cc35b038e 100644
--- a/sys/fs/fdescfs/fdesc_vnops.c
+++ b/sys/fs/fdescfs/fdesc_vnops.c
@@ -485,7 +485,7 @@ fdesc_setattr(struct vop_setattr_args *ap)
return (error);
}
-#define UIO_MX 16
+#define UIO_MX _GENERIC_DIRLEN(10) /* number of symbols in INT_MAX printout */
static int
fdesc_readdir(struct vop_readdir_args *ap)
diff --git a/sys/fs/nandfs/nandfs_fs.h b/sys/fs/nandfs/nandfs_fs.h
index 3e23d7729993..d010830a9042 100644
--- a/sys/fs/nandfs/nandfs_fs.h
+++ b/sys/fs/nandfs/nandfs_fs.h
@@ -537,7 +537,7 @@ struct nandfs_bdesc {
#ifndef _KERNEL
#ifndef MNAMELEN
-#define MNAMELEN 88
+#define MNAMELEN 1024
#endif
#endif
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
index 0bdd26b1f8c5..67849e1543dc 100644
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -730,12 +730,6 @@ int nfsmsleep(void *, void *, int, const char *, struct timespec *);
#define NFSMINOR(d) minor(d)
/*
- * Define this to be the macro that returns the minimum size required
- * for a directory entry.
- */
-#define DIRENT_SIZE(dp) GENERIC_DIRSIZ(dp)
-
-/*
* The vnode tag for nfsv4root.
*/
#define VT_NFSV4ROOT "nfsv4root"
diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c
index c5c6592b84c5..c93ab0865b9e 100644
--- a/sys/fs/nfsclient/nfs_clrpcops.c
+++ b/sys/fs/nfsclient/nfs_clrpcops.c
@@ -72,7 +72,7 @@ short nfsv4_cbport = NFSV4_CBPORT;
int nfstest_openallsetattr = 0;
#endif /* !APPLEKEXT */
-#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1))
+#define DIRHDSIZ offsetof(struct dirent, d_name)
/*
* nfscl_getsameserver() can return one of three values:
@@ -2861,17 +2861,18 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
if (error)
return (error);
nd->nd_mrep = NULL;
- dp = (struct dirent *) CAST_DOWN(caddr_t, uio_iov_base(uiop));
+ dp = (struct dirent *)uio_iov_base(uiop);
+ dp->d_off = 0;
dp->d_type = DT_DIR;
dp->d_fileno = dotfileid;
dp->d_namlen = 1;
+ *((uint64_t *)dp->d_name) = 0; /* Zero pad it. */
dp->d_name[0] = '.';
- dp->d_name[1] = '\0';
- dp->d_reclen = DIRENT_SIZE(dp) + NFSX_HYPER;
+ dp->d_reclen = _GENERIC_DIRSIZ(dp) + NFSX_HYPER;
/*
* Just make these offset cookie 0.
*/
- tl = (u_int32_t *)&dp->d_name[4];
+ tl = (u_int32_t *)&dp->d_name[8];
*tl++ = 0;
*tl = 0;
blksiz += dp->d_reclen;
@@ -2879,18 +2880,19 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
uiop->uio_offset += dp->d_reclen;
uio_iov_base_add(uiop, dp->d_reclen);
uio_iov_len_add(uiop, -(dp->d_reclen));
- dp = (struct dirent *) CAST_DOWN(caddr_t, uio_iov_base(uiop));
+ dp = (struct dirent *)uio_iov_base(uiop);
+ dp->d_off = 0;
dp->d_type = DT_DIR;
dp->d_fileno = dotdotfileid;
dp->d_namlen = 2;
+ *((uint64_t *)dp->d_name) = 0;
dp->d_name[0] = '.';
dp->d_name[1] = '.';
- dp->d_name[2] = '\0';
- dp->d_reclen = DIRENT_SIZE(dp) + NFSX_HYPER;
+ dp->d_reclen = _GENERIC_DIRSIZ(dp) + NFSX_HYPER;
/*
* Just make these offset cookie 0.
*/
- tl = (u_int32_t *)&dp->d_name[4];
+ tl = (u_int32_t *)&dp->d_name[8];
*tl++ = 0;
*tl = 0;
blksiz += dp->d_reclen;
@@ -2987,11 +2989,11 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
error = EBADRPC;
goto nfsmout;
}
- tlen = NFSM_RNDUP(len);
+ tlen = roundup2(len, 8);
if (tlen == len)
- tlen += 4; /* To ensure null termination */
+ tlen += 8; /* To ensure null termination. */
left = DIRBLKSIZ - blksiz;
- if ((int)(tlen + DIRHDSIZ + NFSX_HYPER) > left) {
+ if (_GENERIC_DIRLEN(len) + NFSX_HYPER > left) {
dp->d_reclen += left;
uio_iov_base_add(uiop, left);
uio_iov_len_add(uiop, -(left));
@@ -2999,12 +3001,15 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
uiop->uio_offset += left;
blksiz = 0;
}
- if ((int)(tlen + DIRHDSIZ + NFSX_HYPER) > uio_uio_resid(uiop))
+ if (_GENERIC_DIRLEN(len) + NFSX_HYPER >
+ uio_uio_resid(uiop))
bigenough = 0;
if (bigenough) {
- dp = (struct dirent *) CAST_DOWN(caddr_t, uio_iov_base(uiop));
+ dp = (struct dirent *)uio_iov_base(uiop);
+ dp->d_off = 0;
dp->d_namlen = len;
- dp->d_reclen = tlen + DIRHDSIZ + NFSX_HYPER;
+ dp->d_reclen = _GENERIC_DIRLEN(len) +
+ NFSX_HYPER;
dp->d_type = DT_UNKNOWN;
blksiz += dp->d_reclen;
if (blksiz == DIRBLKSIZ)
@@ -3016,7 +3021,7 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
error = nfsm_mbufuio(nd, uiop, len);
if (error)
goto nfsmout;
- cp = CAST_DOWN(caddr_t, uio_iov_base(uiop));
+ cp = uio_iov_base(uiop);
tlen -= len;
*cp = '\0'; /* null terminate */
cp += tlen; /* points to cookie storage */
@@ -3131,8 +3136,8 @@ nfsrpc_readdir(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
/*
* Add extra empty records to any remaining DIRBLKSIZ chunks.
*/
- while (uio_uio_resid(uiop) > 0 && ((size_t)(uio_uio_resid(uiop))) != tresid) {
- dp = (struct dirent *) CAST_DOWN(caddr_t, uio_iov_base(uiop));
+ while (uio_uio_resid(uiop) > 0 && uio_uio_resid(uiop) != tresid) {
+ dp = (struct dirent *)uio_iov_base(uiop);
dp->d_type = DT_UNKNOWN;
dp->d_fileno = 0;
dp->d_namlen = 0;
@@ -3289,16 +3294,17 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
return (error);
nd->nd_mrep = NULL;
dp = (struct dirent *)uio_iov_base(uiop);
+ dp->d_off = 0;
dp->d_type = DT_DIR;
dp->d_fileno = dotfileid;
dp->d_namlen = 1;
+ *((uint64_t *)dp->d_name) = 0; /* Zero pad it. */
dp->d_name[0] = '.';
- dp->d_name[1] = '\0';
- dp->d_reclen = DIRENT_SIZE(dp) + NFSX_HYPER;
+ dp->d_reclen = _GENERIC_DIRSIZ(dp) + NFSX_HYPER;
/*
* Just make these offset cookie 0.
*/
- tl = (u_int32_t *)&dp->d_name[4];
+ tl = (u_int32_t *)&dp->d_name[8];
*tl++ = 0;
*tl = 0;
blksiz += dp->d_reclen;
@@ -3307,17 +3313,18 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
uio_iov_base_add(uiop, dp->d_reclen);
uio_iov_len_add(uiop, -(dp->d_reclen));
dp = (struct dirent *)uio_iov_base(uiop);
+ dp->d_off = 0;
dp->d_type = DT_DIR;
dp->d_fileno = dotdotfileid;
dp->d_namlen = 2;
+ *((uint64_t *)dp->d_name) = 0;
dp->d_name[0] = '.';
dp->d_name[1] = '.';
- dp->d_name[2] = '\0';
- dp->d_reclen = DIRENT_SIZE(dp) + NFSX_HYPER;
+ dp->d_reclen = _GENERIC_DIRSIZ(dp) + NFSX_HYPER;
/*
* Just make these offset cookie 0.
*/
- tl = (u_int32_t *)&dp->d_name[4];
+ tl = (u_int32_t *)&dp->d_name[8];
*tl++ = 0;
*tl = 0;
blksiz += dp->d_reclen;
@@ -3395,11 +3402,11 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
error = EBADRPC;
goto nfsmout;
}
- tlen = NFSM_RNDUP(len);
+ tlen = roundup2(len, 8);
if (tlen == len)
- tlen += 4; /* To ensure null termination */
+ tlen += 8; /* To ensure null termination. */
left = DIRBLKSIZ - blksiz;
- if ((tlen + DIRHDSIZ + NFSX_HYPER) > left) {
+ if (_GENERIC_DIRLEN(len) + NFSX_HYPER > left) {
dp->d_reclen += left;
uio_iov_base_add(uiop, left);
uio_iov_len_add(uiop, -(left));
@@ -3407,12 +3414,15 @@ nfsrpc_readdirplus(vnode_t vp, struct uio *uiop, nfsuint64 *cookiep,
uiop->uio_offset += left;
blksiz = 0;
}
- if ((tlen + DIRHDSIZ + NFSX_HYPER) > uio_uio_resid(uiop))
+ if (_GENERIC_DIRLEN(len) + NFSX_HYPER >
+ uio_uio_resid(uiop))
bigenough = 0;
if (bigenough) {
dp = (struct dirent *)uio_iov_base(uiop);
+ dp->d_off = 0;
dp->d_namlen = len;
- dp->d_reclen = tlen + DIRHDSIZ + NFSX_HYPER;
+ dp->d_reclen = _GENERIC_DIRLEN(len) +
+ NFSX_HYPER;
dp->d_type = DT_UNKNOWN;
blksiz += dp->d_reclen;
if (blksiz == DIRBLKSIZ)
diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c
index fae2551e1239..e00c25130b07 100644
--- a/sys/fs/nfsclient/nfs_clvnops.c
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -207,8 +207,6 @@ static int nfs_renameit(struct vnode *sdvp, struct vnode *svp,
/*
* Global variables
*/
-#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1))
-
SYSCTL_DECL(_vfs_nfs);
static int nfsaccess_cache_timeout = NFS_MAXATTRTIMO;
diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c
index b0fd83e086b1..e6380238d1e6 100644
--- a/sys/fs/nfsserver/nfs_nfsdport.c
+++ b/sys/fs/nfsserver/nfs_nfsdport.c
@@ -2020,17 +2020,25 @@ again:
}
/*
- * For now ZFS requires VOP_LOOKUP as a workaround. Until ino_t is changed
- * to 64 bit type a ZFS filesystem with over 1 billion files in it
- * will suffer from 64bit -> 32bit truncation.
+ * Check to see if entries in this directory can be safely acquired
+ * via VFS_VGET() or if a switch to VOP_LOOKUP() is required.
+ * ZFS snapshot directories need VOP_LOOKUP(), so that any
+ * automount of the snapshot directory that is required will
+ * be done.
+ * This needs to be done here for NFSv4, since NFSv4 never does
+ * a VFS_VGET() for "." or "..".
*/
- if (is_zfs == 1)
- usevget = 0;
-
- cn.cn_nameiop = LOOKUP;
- cn.cn_lkflags = LK_SHARED | LK_RETRY;
- cn.cn_cred = nd->nd_cred;
- cn.cn_thread = p;
+ if (is_zfs == 1) {
+ r = VFS_VGET(mp, at.na_fileid, LK_SHARED, &nvp);
+ if (r == EOPNOTSUPP) {
+ usevget = 0;
+ cn.cn_nameiop = LOOKUP;
+ cn.cn_lkflags = LK_SHARED | LK_RETRY;
+ cn.cn_cred = nd->nd_cred;
+ cn.cn_thread = p;
+ } else if (r == 0)
+ vput(nvp);
+ }
/*
* Save this position, in case there is an error before one entry
@@ -2099,7 +2107,16 @@ again:
else
r = EOPNOTSUPP;
if (r == EOPNOTSUPP) {
- usevget = 0;
+ if (usevget) {
+ usevget = 0;
+ cn.cn_nameiop = LOOKUP;
+ cn.cn_lkflags =
+ LK_SHARED |
+ LK_RETRY;
+ cn.cn_cred =
+ nd->nd_cred;
+ cn.cn_thread = p;
+ }
cn.cn_nameptr = dp->d_name;
cn.cn_namelen = nlen;
cn.cn_flags = ISLASTCN |
diff --git a/sys/kern/capabilities.conf b/sys/kern/capabilities.conf
index 1c8ca0811d8d..a59601345c9c 100644
--- a/sys/kern/capabilities.conf
+++ b/sys/kern/capabilities.conf
@@ -197,6 +197,11 @@ fpathconf
## Allow various file descriptor-based I/O operations, subject to capability
## rights.
##
+freebsd11_fstat
+freebsd11_fstatat
+freebsd11_getdirentries
+freebsd11_fstatfs
+freebsd11_mknodat
freebsd6_ftruncate
freebsd6_lseek
freebsd6_mmap
diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c
index 622a6a49ea19..c13baa5d3891 100644
--- a/sys/kern/kern_acct.c
+++ b/sys/kern/kern_acct.c
@@ -96,6 +96,11 @@ __FBSDID("$FreeBSD$");
#include <security/mac/mac_framework.h>
+_Static_assert(sizeof(struct acctv3) - offsetof(struct acctv3, ac_trailer) ==
+ sizeof(struct acctv2) - offsetof(struct acctv2, ac_trailer), "trailer");
+_Static_assert(sizeof(struct acctv3) - offsetof(struct acctv3, ac_len2) ==
+ sizeof(struct acctv2) - offsetof(struct acctv2, ac_len2), "len2");
+
/*
* The routines implemented in this file are described in:
* Leffler, et al.: The Design and Implementation of the 4.3BSD
@@ -339,7 +344,7 @@ acct_disable(struct thread *td, int logging)
int
acct_process(struct thread *td)
{
- struct acctv2 acct;
+ struct acctv3 acct;
struct timeval ut, st, tmp;
struct plimit *oldlim;
struct proc *p;
@@ -421,7 +426,7 @@ acct_process(struct thread *td)
/* Setup ancillary structure fields. */
acct.ac_flagx |= ANVER;
acct.ac_zero = 0;
- acct.ac_version = 2;
+ acct.ac_version = 3;
acct.ac_len = acct.ac_len2 = sizeof(acct);
/*
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index bb54f9d8acb7..2baaff77666b 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1304,6 +1304,23 @@ ofstat(struct thread *td, struct ofstat_args *uap)
}
#endif /* COMPAT_43 */
+#if defined(COMPAT_FREEBSD11)
+int
+freebsd11_fstat(struct thread *td, struct freebsd11_fstat_args *uap)
+{
+ struct stat sb;
+ struct freebsd11_stat osb;
+ int error;
+
+ error = kern_fstat(td, uap->fd, &sb);
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat(&sb, &osb);
+ error = copyout(&osb, uap->sb, sizeof(osb));
+ return (error);
+}
+#endif /* COMPAT_FREEBSD11 */
+
/*
* Return status information about a file descriptor.
*/
@@ -1343,6 +1360,14 @@ kern_fstat(struct thread *td, int fd, struct stat *sbp)
error = fo_stat(fp, sbp, td->td_ucred, td);
fdrop(fp, td);
+#ifdef __STAT_TIME_T_EXT
+ if (error == 0) {
+ sbp->st_atim_ext = 0;
+ sbp->st_mtim_ext = 0;
+ sbp->st_ctim_ext = 0;
+ sbp->st_btim_ext = 0;
+ }
+#endif
#ifdef KTRACE
if (error == 0 && KTRPOINT(td, KTR_STRUCT))
ktrstat(sbp);
@@ -1350,18 +1375,19 @@ kern_fstat(struct thread *td, int fd, struct stat *sbp)
return (error);
}
+#if defined(COMPAT_FREEBSD11)
/*
* Return status information about a file descriptor.
*/
#ifndef _SYS_SYSPROTO_H_
-struct nfstat_args {
+struct freebsd11_nfstat_args {
int fd;
struct nstat *sb;
};
#endif
/* ARGSUSED */
int
-sys_nfstat(struct thread *td, struct nfstat_args *uap)
+freebsd11_nfstat(struct thread *td, struct freebsd11_nfstat_args *uap)
{
struct nstat nub;
struct stat ub;
@@ -1369,11 +1395,12 @@ sys_nfstat(struct thread *td, struct nfstat_args *uap)
error = kern_fstat(td, uap->fd, &ub);
if (error == 0) {
- cvtnstat(&ub, &nub);
+ freebsd11_cvtnstat(&ub, &nub);
error = copyout(&nub, uap->sb, sizeof(nub));
}
return (error);
}
+#endif /* COMPAT_FREEBSD11 */
/*
* Return pathconf information about a file descriptor.
@@ -3590,13 +3617,21 @@ kinfo_to_okinfo(struct kinfo_file *kif, struct kinfo_ofile *okif)
KF_FLAG_APPEND | KF_FLAG_ASYNC | KF_FLAG_FSYNC | KF_FLAG_NONBLOCK |
KF_FLAG_DIRECT | KF_FLAG_HASLOCK);
okif->kf_offset = kif->kf_offset;
- okif->kf_vnode_type = kif->kf_vnode_type;
- okif->kf_sock_domain = kif->kf_sock_domain;
- okif->kf_sock_type = kif->kf_sock_type;
- okif->kf_sock_protocol = kif->kf_sock_protocol;
+ if (kif->kf_type == KF_TYPE_VNODE)
+ okif->kf_vnode_type = kif->kf_un.kf_file.kf_file_type;
+ else
+ okif->kf_vnode_type = KF_VTYPE_VNON;
strlcpy(okif->kf_path, kif->kf_path, sizeof(okif->kf_path));
- okif->kf_sa_local = kif->kf_sa_local;
- okif->kf_sa_peer = kif->kf_sa_peer;
+ if (kif->kf_type == KF_TYPE_SOCKET) {
+ okif->kf_sock_domain = kif->kf_un.kf_sock.kf_sock_domain0;
+ okif->kf_sock_type = kif->kf_un.kf_sock.kf_sock_type0;
+ okif->kf_sock_protocol = kif->kf_un.kf_sock.kf_sock_protocol0;
+ okif->kf_sa_local = kif->kf_un.kf_sock.kf_sa_local;
+ okif->kf_sa_peer = kif->kf_un.kf_sock.kf_sa_peer;
+ } else {
+ okif->kf_sa_local.ss_family = AF_UNSPEC;
+ okif->kf_sa_peer.ss_family = AF_UNSPEC;
+ }
}
static int
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 9b4ed9d88a01..c029567b6c44 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -986,11 +986,14 @@ fill_kinfo_proc_only(struct proc *p, struct kinfo_proc *kp)
}
if ((p->p_flag & P_CONTROLT) && tp != NULL) {
kp->ki_tdev = tty_udev(tp);
+ kp->ki_tdev_freebsd11 = kp->ki_tdev; /* truncate */
kp->ki_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
if (tp->t_session)
kp->ki_tsid = tp->t_session->s_sid;
- } else
+ } else {
kp->ki_tdev = NODEV;
+ kp->ki_tdev_freebsd11 = kp->ki_tdev; /* truncate */
+ }
if (p->p_comm[0] != '\0')
strlcpy(kp->ki_comm, p->p_comm, sizeof(kp->ki_comm));
if (p->p_sysent && p->p_sysent->sv_name != NULL &&
@@ -1232,6 +1235,7 @@ freebsd32_kinfo_proc_out(const struct kinfo_proc *ki, struct kinfo_proc32 *ki32)
CP(*ki, *ki32, ki_tsid);
CP(*ki, *ki32, ki_jobc);
CP(*ki, *ki32, ki_tdev);
+ CP(*ki, *ki32, ki_tdev_freebsd11);
CP(*ki, *ki32, ki_siglist);
CP(*ki, *ki32, ki_sigmask);
CP(*ki, *ki32, ki_sigignore);
@@ -2204,6 +2208,7 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS)
vn_lock(vp, LK_SHARED | LK_RETRY);
if (VOP_GETATTR(vp, &va, cred) == 0) {
kve->kve_fileid = va.va_fileid;
+ /* truncate */
kve->kve_fsid = va.va_fsid;
}
vput(vp);
@@ -2443,10 +2448,14 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen, int flags)
if (VOP_GETATTR(vp, &va, cred) == 0) {
kve->kve_vn_fileid = va.va_fileid;
kve->kve_vn_fsid = va.va_fsid;
+ kve->kve_vn_fsid_freebsd11 =
+ kve->kve_vn_fsid; /* truncate */
kve->kve_vn_mode =
MAKEIMODE(va.va_type, va.va_mode);
kve->kve_vn_size = va.va_size;
kve->kve_vn_rdev = va.va_rdev;
+ kve->kve_vn_rdev_freebsd11 =
+ kve->kve_vn_rdev; /* truncate */
kve->kve_status = KF_ATTR_VALID;
}
vput(vp);
diff --git a/sys/kern/makesyscalls.sh b/sys/kern/makesyscalls.sh
index f220554ab04e..7ea37de6e53c 100644
--- a/sys/kern/makesyscalls.sh
+++ b/sys/kern/makesyscalls.sh
@@ -10,6 +10,7 @@ compat4=COMPAT_FREEBSD4
compat6=COMPAT_FREEBSD6
compat7=COMPAT_FREEBSD7
compat10=COMPAT_FREEBSD10
+compat11=COMPAT_FREEBSD11
# output files:
sysnames="syscalls.c"
@@ -36,6 +37,8 @@ syscompat7="sysent.compat7.$$"
syscompat7dcl="sysent.compat7dcl.$$"
syscompat10="sysent.compat10.$$"
syscompat10dcl="sysent.compat10dcl.$$"
+syscompat11="sysent.compat11.$$"
+syscompat11dcl="sysent.compat11dcl.$$"
sysent="sysent.switch.$$"
sysinc="sysinc.switch.$$"
sysarg="sysarg.switch.$$"
@@ -50,9 +53,9 @@ else
capenabled=""
fi
-trap "rm $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4 $syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl $syscompat10 $syscompat10dcl $sysent $sysinc $sysarg $sysprotoend $systracetmp $systraceret" 0
+trap "rm $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4 $syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl $syscompat10 $syscompat10dcl $syscompat11 $syscompat11dcl $sysent $sysinc $sysarg $sysprotoend $systracetmp $systraceret" 0
-touch $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4 $syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl $syscompat10 $syscompat10dcl $sysent $sysinc $sysarg $sysprotoend $systracetmp $systraceret
+touch $sysaue $sysdcl $syscompat $syscompatdcl $syscompat4 $syscompat4dcl $syscompat6 $syscompat6dcl $syscompat7 $syscompat7dcl $syscompat10 $syscompat10dcl $syscompat11 $syscompat11dcl $sysent $sysinc $sysarg $sysprotoend $systracetmp $systraceret
case $# in
0) echo "usage: $0 input-file <config-file>" 1>&2
@@ -92,6 +95,8 @@ sed -e '
syscompat7dcl = \"$syscompat7dcl\"
syscompat10 = \"$syscompat10\"
syscompat10dcl = \"$syscompat10dcl\"
+ syscompat11 = \"$syscompat11\"
+ syscompat11dcl = \"$syscompat11dcl\"
sysent = \"$sysent\"
syssw = \"$syssw\"
sysinc = \"$sysinc\"
@@ -107,6 +112,7 @@ sed -e '
compat6 = \"$compat6\"
compat7 = \"$compat7\"
compat10 = \"$compat10\"
+ compat11 = \"$compat11\"
syscallprefix = \"$syscallprefix\"
switchname = \"$switchname\"
namesname = \"$namesname\"
@@ -155,6 +161,7 @@ sed -e '
printf "\n#ifdef %s\n\n", compat6 > syscompat6
printf "\n#ifdef %s\n\n", compat7 > syscompat7
printf "\n#ifdef %s\n\n", compat10 > syscompat10
+ printf "\n#ifdef %s\n\n", compat11 > syscompat11
printf "/*\n * System call names.\n *\n" > sysnames
printf " * DO NOT EDIT-- this file is automatically generated.\n" > sysnames
@@ -205,6 +212,7 @@ sed -e '
print > syscompat6
print > syscompat7
print > syscompat10
+ print > syscompat11
print > sysnames
print > systrace
print > systracetmp
@@ -221,6 +229,7 @@ sed -e '
print > syscompat6
print > syscompat7
print > syscompat10
+ print > syscompat11
print > sysnames
print > systrace
print > systracetmp
@@ -237,6 +246,7 @@ sed -e '
print > syscompat6
print > syscompat7
print > syscompat10
+ print > syscompat11
print > sysnames
print > systrace
print > systracetmp
@@ -345,6 +355,8 @@ sed -e '
argalias = "freebsd7_" argalias
if (flag("COMPAT10"))
argalias = "freebsd10_" argalias
+ if (flag("COMPAT11"))
+ argalias = "freebsd11_" argalias
}
f++
@@ -497,7 +509,7 @@ sed -e '
next
}
type("COMPAT") || type("COMPAT4") || type("COMPAT6") || \
- type("COMPAT7") || type("COMPAT10") {
+ type("COMPAT7") || type("COMPAT10") || type("COMPAT11") {
if (flag("COMPAT")) {
ncompat++
out = syscompat
@@ -533,6 +545,13 @@ sed -e '
wrap = "compat10"
prefix = "freebsd10_"
descr = "freebsd10"
+ } else if (flag("COMPAT11")) {
+ ncompat11++
+ out = syscompat11
+ outdcl = syscompat11dcl
+ wrap = "compat11"
+ prefix = "freebsd11_"
+ descr = "freebsd11"
}
parseline()
if (argc != 0 && !flag("NOARGS") && !flag("NOPROTO") && \
@@ -608,7 +627,7 @@ sed -e '
END {
printf "\n#define AS(name) (sizeof(struct name) / sizeof(register_t))\n" > sysinc
- if (ncompat != 0 || ncompat4 != 0 || ncompat6 != 0 || ncompat7 != 0 || ncompat10 != 0)
+ if (ncompat != 0 || ncompat4 != 0 || ncompat6 != 0 || ncompat7 != 0 || ncompat10 != 0 || ncompat11 != 0)
printf "#include \"opt_compat.h\"\n\n" > syssw
if (ncompat != 0) {
@@ -649,11 +668,20 @@ sed -e '
printf "#define compat10(n, name) 0, (sy_call_t *)nosys\n" > sysinc
printf "#endif\n" > sysinc
}
+ if (ncompat11 != 0) {
+ printf "\n#ifdef %s\n", compat11 > sysinc
+ printf "#define compat11(n, name) n, (sy_call_t *)__CONCAT(freebsd11_,name)\n" > sysinc
+ printf "#else\n" > sysinc
+ printf "#define compat11(n, name) 0, (sy_call_t *)nosys\n" > sysinc
+ printf "#endif\n" > sysinc
+ }
+
printf("\n#endif /* %s */\n\n", compat) > syscompatdcl
printf("\n#endif /* %s */\n\n", compat4) > syscompat4dcl
printf("\n#endif /* %s */\n\n", compat6) > syscompat6dcl
printf("\n#endif /* %s */\n\n", compat7) > syscompat7dcl
printf("\n#endif /* %s */\n\n", compat10) > syscompat10dcl
+ printf("\n#endif /* %s */\n\n", compat11) > syscompat11dcl
printf("\n#undef PAD_\n") > sysprotoend
printf("#undef PADL_\n") > sysprotoend
@@ -677,6 +705,7 @@ cat $sysarg $sysdcl \
$syscompat6 $syscompat6dcl \
$syscompat7 $syscompat7dcl \
$syscompat10 $syscompat10dcl \
+ $syscompat11 $syscompat11dcl \
$sysaue $sysprotoend > $sysproto
cat $systracetmp >> $systrace
cat $systraceret >> $systrace
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 441a628b7f78..a30260bfeebc 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -346,14 +346,15 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
kif->kf_type = KF_TYPE_SOCKET;
so = fp->f_data;
- kif->kf_sock_domain = so->so_proto->pr_domain->dom_family;
- kif->kf_sock_type = so->so_type;
- kif->kf_sock_protocol = so->so_proto->pr_protocol;
+ kif->kf_un.kf_sock.kf_sock_domain0 =
+ so->so_proto->pr_domain->dom_family;
+ kif->kf_un.kf_sock.kf_sock_type0 = so->so_type;
+ kif->kf_un.kf_sock.kf_sock_protocol0 = so->so_proto->pr_protocol;
kif->kf_un.kf_sock.kf_sock_pcb = (uintptr_t)so->so_pcb;
- switch (kif->kf_sock_domain) {
+ switch (kif->kf_un.kf_sock.kf_sock_domain0) {
case AF_INET:
case AF_INET6:
- if (kif->kf_sock_protocol == IPPROTO_TCP) {
+ if (kif->kf_un.kf_sock.kf_sock_protocol0 == IPPROTO_TCP) {
if (so->so_pcb != NULL) {
inpcb = (struct inpcb *)(so->so_pcb);
kif->kf_un.kf_sock.kf_sock_inpcb =
@@ -376,13 +377,15 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
break;
}
error = so->so_proto->pr_usrreqs->pru_sockaddr(so, &sa);
- if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_local)) {
- bcopy(sa, &kif->kf_sa_local, sa->sa_len);
+ if (error == 0 &&
+ sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_local)) {
+ bcopy(sa, &kif->kf_un.kf_sock.kf_sa_local, sa->sa_len);
free(sa, M_SONAME);
}
error = so->so_proto->pr_usrreqs->pru_peeraddr(so, &sa);
- if (error == 0 && sa->sa_len <= sizeof(kif->kf_sa_peer)) {
- bcopy(sa, &kif->kf_sa_peer, sa->sa_len);
+ if (error == 0 &&
+ sa->sa_len <= sizeof(kif->kf_un.kf_sock.kf_sa_peer)) {
+ bcopy(sa, &kif->kf_un.kf_sock.kf_sa_peer, sa->sa_len);
free(sa, M_SONAME);
}
strncpy(kif->kf_path, so->so_proto->pr_domain->dom_name,
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 999da9c884ce..ad0fdb27545f 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -12,7 +12,7 @@
; case where the event exists, but we don't want auditing, the
; event should be #defined to AUE_NULL in audit_kevents.h.
; type one of STD, OBSOL, UNIMPL, COMPAT, COMPAT4, COMPAT6,
-; COMPAT7, NODEF, NOARGS, NOPROTO, NOSTD
+; COMPAT7, COMPAT11, NODEF, NOARGS, NOPROTO, NOSTD
; The COMPAT* options may be combined with one or more NO*
; options separated by '|' with no spaces (e.g. COMPAT|NOARGS)
; name psuedo-prototype of syscall routine
@@ -29,6 +29,7 @@
; COMPAT6 included on COMPAT_FREEBSD6 #ifdef (FreeBSD 6 compat)
; COMPAT7 included on COMPAT_FREEBSD7 #ifdef (FreeBSD 7 compat)
; COMPAT10 included on COMPAT_FREEBSD10 #ifdef (FreeBSD 10 compat)
+; COMPAT11 included on COMPAT11 #ifdef (FreeBSD 11 compat)
; OBSOL obsolete, not included in system, only specifies name
; UNIMPL not implemented, placeholder only
; NOSTD implemented but as a lkm that can be statically
@@ -79,7 +80,7 @@
11 AUE_NULL OBSOL execv
12 AUE_CHDIR STD { int chdir(char *path); }
13 AUE_FCHDIR STD { int fchdir(int fd); }
-14 AUE_MKNOD STD { int mknod(char *path, int mode, int dev); }
+14 AUE_MKNOD COMPAT11 { int mknod(char *path, int mode, int dev); }
15 AUE_CHMOD STD { int chmod(char *path, int mode); }
16 AUE_CHOWN STD { int chown(char *path, int uid, int gid); }
17 AUE_NULL STD { int obreak(char *nsize); } break \
@@ -363,9 +364,12 @@
185 AUE_NULL UNIMPL lfs_markv
186 AUE_NULL UNIMPL lfs_segclean
187 AUE_NULL UNIMPL lfs_segwait
-188 AUE_STAT STD { int stat(char *path, struct stat *ub); }
-189 AUE_FSTAT STD { int fstat(int fd, struct stat *sb); }
-190 AUE_LSTAT STD { int lstat(char *path, struct stat *ub); }
+188 AUE_STAT COMPAT11 { int stat(char *path, \
+ struct freebsd11_stat *ub); }
+189 AUE_FSTAT COMPAT11 { int fstat(int fd, \
+ struct freebsd11_stat *sb); }
+190 AUE_LSTAT COMPAT11 { int lstat(char *path, \
+ struct freebsd11_stat *ub); }
191 AUE_PATHCONF STD { int pathconf(char *path, int name); }
192 AUE_FPATHCONF STD { int fpathconf(int fd, int name); }
193 AUE_NULL UNIMPL nosys
@@ -375,7 +379,7 @@
195 AUE_SETRLIMIT STD { int setrlimit(u_int which, \
struct rlimit *rlp); } setrlimit \
__setrlimit_args int
-196 AUE_GETDIRENTRIES STD { int getdirentries(int fd, char *buf, \
+196 AUE_GETDIRENTRIES COMPAT11 { int getdirentries(int fd, char *buf, \
u_int count, long *basep); }
197 AUE_MMAP COMPAT6 { caddr_t mmap(caddr_t addr, \
size_t len, int prot, int flags, int fd, \
@@ -496,7 +500,7 @@
269 AUE_NULL UNIMPL nosys
270 AUE_NULL UNIMPL nosys
271 AUE_NULL UNIMPL nosys
-272 AUE_O_GETDENTS STD { int getdents(int fd, char *buf, \
+272 AUE_O_GETDENTS COMPAT11 { int getdents(int fd, char *buf, \
size_t count); }
273 AUE_NULL UNIMPL nosys
274 AUE_LCHMOD STD { int lchmod(char *path, mode_t mode); }
@@ -507,9 +511,9 @@
struct timeval *tptr); }
277 AUE_MSYNC NOPROTO { int msync(void *addr, size_t len, \
int flags); } netbsd_msync msync_args int
-278 AUE_STAT STD { int nstat(char *path, struct nstat *ub); }
-279 AUE_FSTAT STD { int nfstat(int fd, struct nstat *sb); }
-280 AUE_LSTAT STD { int nlstat(char *path, struct nstat *ub); }
+278 AUE_STAT COMPAT11 { int nstat(char *path, struct nstat *ub); }
+279 AUE_FSTAT COMPAT11 { int nfstat(int fd, struct nstat *sb); }
+280 AUE_LSTAT COMPAT11 { int nlstat(char *path, struct nstat *ub); }
281 AUE_NULL UNIMPL nosys
282 AUE_NULL UNIMPL nosys
283 AUE_NULL UNIMPL nosys
@@ -535,8 +539,8 @@
struct ostatfs *buf); }
298 AUE_FHOPEN STD { int fhopen(const struct fhandle *u_fhp, \
int flags); }
-299 AUE_FHSTAT STD { int fhstat(const struct fhandle *u_fhp, \
- struct stat *sb); }
+299 AUE_FHSTAT COMPAT11 { int fhstat(const struct fhandle *u_fhp, \
+ struct freebsd11_stat *sb); }
; syscall numbers for FreeBSD
300 AUE_NULL STD { int modnext(int modid); }
301 AUE_NULL STD { int modstat(int modid, \
@@ -707,13 +711,14 @@
off_t *sbytes, int flags); }
394 AUE_NULL STD { int mac_syscall(const char *policy, \
int call, void *arg); }
-395 AUE_GETFSSTAT STD { int getfsstat(struct statfs *buf, \
+395 AUE_GETFSSTAT COMPAT11 { int getfsstat(struct freebsd11_statfs *buf, \
long bufsize, int mode); }
-396 AUE_STATFS STD { int statfs(char *path, \
- struct statfs *buf); }
-397 AUE_FSTATFS STD { int fstatfs(int fd, struct statfs *buf); }
-398 AUE_FHSTATFS STD { int fhstatfs(const struct fhandle *u_fhp, \
- struct statfs *buf); }
+396 AUE_STATFS COMPAT11 { int statfs(char *path, \
+ struct freebsd11_statfs *buf); }
+397 AUE_FSTATFS COMPAT11 { int fstatfs(int fd, \
+ struct freebsd11_statfs *buf); }
+398 AUE_FHSTATFS COMPAT11 { int fhstatfs(const struct fhandle *u_fhp, \
+ struct freebsd11_statfs *buf); }
399 AUE_NULL UNIMPL nosys
400 AUE_SEMCLOSE NOSTD { int ksem_close(semid_t id); }
401 AUE_SEMPOST NOSTD { int ksem_post(semid_t id); }
@@ -883,16 +888,16 @@
gid_t gid, int flag); }
492 AUE_FEXECVE STD { int fexecve(int fd, char **argv, \
char **envv); }
-493 AUE_FSTATAT STD { int fstatat(int fd, char *path, \
- struct stat *buf, int flag); }
+493 AUE_FSTATAT COMPAT11 { int fstatat(int fd, char *path, \
+ struct freebsd11_stat *buf, int flag); }
494 AUE_FUTIMESAT STD { int futimesat(int fd, char *path, \
struct timeval *times); }
495 AUE_LINKAT STD { int linkat(int fd1, char *path1, int fd2, \
char *path2, int flag); }
496 AUE_MKDIRAT STD { int mkdirat(int fd, char *path, mode_t mode); }
497 AUE_MKFIFOAT STD { int mkfifoat(int fd, char *path, mode_t mode); }
-498 AUE_MKNODAT STD { int mknodat(int fd, char *path, mode_t mode, \
- dev_t dev); }
+498 AUE_MKNODAT COMPAT11 { int mknodat(int fd, char *path, mode_t mode, \
+ uint32_t dev); }
; XXX: see the comment for open
499 AUE_OPENAT_RWTC STD { int openat(int fd, char *path, int flag, \
mode_t mode); }
@@ -997,6 +1002,21 @@
id_t id, const struct \
vm_domain_policy_entry *policy); }
550 AUE_FSYNC STD { int fdatasync(int fd); }
+551 AUE_FSTAT STD { int fstat(int fd, struct stat *sb); }
+552 AUE_FSTATAT STD { int fstatat(int fd, char *path, \
+ struct stat *buf, int flag); }
+553 AUE_FHSTAT STD { int fhstat(const struct fhandle *u_fhp, \
+ struct stat *sb); }
+554 AUE_GETDIRENTRIES STD { ssize_t getdirentries(int fd, char *buf, \
+ size_t count, off_t *basep); }
+555 AUE_STATFS STD { int statfs(char *path, struct statfs *buf); }
+556 AUE_FSTATFS STD { int fstatfs(int fd, struct statfs *buf); }
+557 AUE_GETFSSTAT STD { int getfsstat(struct statfs *buf, \
+ long bufsize, int mode); }
+558 AUE_FHSTATFS STD { int fhstatfs(const struct fhandle *u_fhp, \
+ struct statfs *buf); }
+559 AUE_MKNODAT STD { int mknodat(int fd, char *path, mode_t mode, \
+ dev_t dev); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index b0a535cb67e3..63e195945d89 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -1205,7 +1205,7 @@ tty_to_xtty(struct tty *tp, struct xtty *xt)
xt->xt_pgid = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
xt->xt_sid = tp->t_session ? tp->t_session->s_sid : 0;
xt->xt_flags = tp->t_flags;
- xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : NODEV;
+ xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : (uint32_t)NODEV;
}
static int
diff --git a/sys/kern/tty_pts.c b/sys/kern/tty_pts.c
index a4c3dbb3cc22..b9a888c5a124 100644
--- a/sys/kern/tty_pts.c
+++ b/sys/kern/tty_pts.c
@@ -592,6 +592,8 @@ ptsdev_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
kif->kf_type = KF_TYPE_PTS;
tp = fp->f_data;
kif->kf_un.kf_pts.kf_pts_dev = tty_udev(tp);
+ kif->kf_un.kf_pts.kf_pts_dev_freebsd11 =
+ kif->kf_un.kf_pts.kf_pts_dev; /* truncate */
strlcpy(kif->kf_path, tty_devname(tp), sizeof(kif->kf_path));
return (0);
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 7671e1b84ac2..27b2635030d3 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -525,7 +525,7 @@ restart:
/*
* Get old format filesystem statistics.
*/
-static void cvtstatfs(struct statfs *, struct ostatfs *);
+static void freebsd4_cvtstatfs(struct statfs *, struct ostatfs *);
#ifndef _SYS_SYSPROTO_H_
struct freebsd4_statfs_args {
@@ -543,7 +543,7 @@ freebsd4_statfs(struct thread *td, struct freebsd4_statfs_args *uap)
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp);
if (error == 0) {
- cvtstatfs(sfp, &osb);
+ freebsd4_cvtstatfs(sfp, &osb);
error = copyout(&osb, uap->buf, sizeof(osb));
}
free(sfp, M_STATFS);
@@ -569,7 +569,7 @@ freebsd4_fstatfs(struct thread *td, struct freebsd4_fstatfs_args *uap)
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fstatfs(td, uap->fd, sfp);
if (error == 0) {
- cvtstatfs(sfp, &osb);
+ freebsd4_cvtstatfs(sfp, &osb);
error = copyout(&osb, uap->buf, sizeof(osb));
}
free(sfp, M_STATFS);
@@ -602,11 +602,12 @@ freebsd4_getfsstat(struct thread *td, struct freebsd4_getfsstat_args *uap)
size = count * sizeof(struct statfs);
error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE,
uap->mode);
- td->td_retval[0] = count;
+ if (error == 0)
+ td->td_retval[0] = count;
if (size != 0) {
sp = buf;
while (count != 0 && error == 0) {
- cvtstatfs(sp, &osb);
+ freebsd4_cvtstatfs(sp, &osb);
error = copyout(&osb, uap->buf, sizeof(osb));
sp++;
uap->buf++;
@@ -640,7 +641,7 @@ freebsd4_fhstatfs(struct thread *td, struct freebsd4_fhstatfs_args *uap)
sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
error = kern_fhstatfs(td, fh, sfp);
if (error == 0) {
- cvtstatfs(sfp, &osb);
+ freebsd4_cvtstatfs(sfp, &osb);
error = copyout(&osb, uap->buf, sizeof(osb));
}
free(sfp, M_STATFS);
@@ -651,7 +652,7 @@ freebsd4_fhstatfs(struct thread *td, struct freebsd4_fhstatfs_args *uap)
* Convert a new format statfs structure to an old format statfs structure.
*/
static void
-cvtstatfs(struct statfs *nsp, struct ostatfs *osp)
+freebsd4_cvtstatfs(struct statfs *nsp, struct ostatfs *osp)
{
statfs_scale_blocks(nsp, LONG_MAX);
@@ -680,6 +681,138 @@ cvtstatfs(struct statfs *nsp, struct ostatfs *osp)
}
#endif /* COMPAT_FREEBSD4 */
+#if defined(COMPAT_FREEBSD11)
+/*
+ * Get old format filesystem statistics.
+ */
+static void freebsd11_cvtstatfs(struct statfs *, struct freebsd11_statfs *);
+
+int
+freebsd11_statfs(struct thread *td, struct freebsd11_statfs_args *uap)
+{
+ struct freebsd11_statfs osb;
+ struct statfs *sfp;
+ int error;
+
+ sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
+ error = kern_statfs(td, uap->path, UIO_USERSPACE, sfp);
+ if (error == 0) {
+ freebsd11_cvtstatfs(sfp, &osb);
+ error = copyout(&osb, uap->buf, sizeof(osb));
+ }
+ free(sfp, M_STATFS);
+ return (error);
+}
+
+/*
+ * Get filesystem statistics.
+ */
+int
+freebsd11_fstatfs(struct thread *td, struct freebsd11_fstatfs_args *uap)
+{
+ struct freebsd11_statfs osb;
+ struct statfs *sfp;
+ int error;
+
+ sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
+ error = kern_fstatfs(td, uap->fd, sfp);
+ if (error == 0) {
+ freebsd11_cvtstatfs(sfp, &osb);
+ error = copyout(&osb, uap->buf, sizeof(osb));
+ }
+ free(sfp, M_STATFS);
+ return (error);
+}
+
+/*
+ * Get statistics on all filesystems.
+ */
+int
+freebsd11_getfsstat(struct thread *td, struct freebsd11_getfsstat_args *uap)
+{
+ struct freebsd11_statfs osb;
+ struct statfs *buf, *sp;
+ size_t count, size;
+ int error;
+
+ count = uap->bufsize / sizeof(struct ostatfs);
+ size = count * sizeof(struct statfs);
+ error = kern_getfsstat(td, &buf, size, &count, UIO_SYSSPACE,
+ uap->mode);
+ if (error == 0)
+ td->td_retval[0] = count;
+ if (size > 0) {
+ sp = buf;
+ while (count > 0 && error == 0) {
+ freebsd11_cvtstatfs(sp, &osb);
+ error = copyout(&osb, uap->buf, sizeof(osb));
+ sp++;
+ uap->buf++;
+ count--;
+ }
+ free(buf, M_STATFS);
+ }
+ return (error);
+}
+
+/*
+ * Implement fstatfs() for (NFS) file handles.
+ */
+int
+freebsd11_fhstatfs(struct thread *td, struct freebsd11_fhstatfs_args *uap)
+{
+ struct freebsd11_statfs osb;
+ struct statfs *sfp;
+ fhandle_t fh;
+ int error;
+
+ error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
+ if (error)
+ return (error);
+ sfp = malloc(sizeof(struct statfs), M_STATFS, M_WAITOK);
+ error = kern_fhstatfs(td, fh, sfp);
+ if (error == 0) {
+ freebsd11_cvtstatfs(sfp, &osb);
+ error = copyout(&osb, uap->buf, sizeof(osb));
+ }
+ free(sfp, M_STATFS);
+ return (error);
+}
+
+/*
+ * Convert a new format statfs structure to an old format statfs structure.
+ */
+static void
+freebsd11_cvtstatfs(struct statfs *nsp, struct freebsd11_statfs *osp)
+{
+
+ bzero(osp, sizeof(*osp));
+ osp->f_version = FREEBSD11_STATFS_VERSION;
+ osp->f_type = nsp->f_type;
+ osp->f_flags = nsp->f_flags;
+ osp->f_bsize = nsp->f_bsize;
+ osp->f_iosize = nsp->f_iosize;
+ osp->f_blocks = nsp->f_blocks;
+ osp->f_bfree = nsp->f_bfree;
+ osp->f_bavail = nsp->f_bavail;
+ osp->f_files = nsp->f_files;
+ osp->f_ffree = nsp->f_ffree;
+ osp->f_syncwrites = nsp->f_syncwrites;
+ osp->f_asyncwrites = nsp->f_asyncwrites;
+ osp->f_syncreads = nsp->f_syncreads;
+ osp->f_asyncreads = nsp->f_asyncreads;
+ osp->f_namemax = nsp->f_namemax;
+ osp->f_owner = nsp->f_owner;
+ osp->f_fsid = nsp->f_fsid;
+ strlcpy(osp->f_fstypename, nsp->f_fstypename,
+ MIN(MFSNAMELEN, sizeof(osp->f_fstypename)));
+ strlcpy(osp->f_mntonname, nsp->f_mntonname,
+ MIN(MNAMELEN, sizeof(osp->f_mntonname)));
+ strlcpy(osp->f_mntfromname, nsp->f_mntfromname,
+ MIN(MNAMELEN, sizeof(osp->f_mntfromname)));
+}
+#endif /* COMPAT_FREEBSD11 */
+
/*
* Change current working directory to a given file descriptor.
*/
@@ -1060,39 +1193,44 @@ ocreat(struct thread *td, struct ocreat_args *uap)
* Create a special file.
*/
#ifndef _SYS_SYSPROTO_H_
-struct mknod_args {
+struct mknodat_args {
+ int fd;
char *path;
- int mode;
- int dev;
+ mode_t mode;
+ dev_t dev;
};
#endif
int
-sys_mknod(struct thread *td, struct mknod_args *uap)
+sys_mknodat(struct thread *td, struct mknodat_args *uap)
+{
+
+ return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode,
+ uap->dev));
+}
+
+#if defined(COMPAT_FREEBSD11)
+int
+freebsd11_mknod(struct thread *td,
+ struct freebsd11_mknod_args *uap)
{
return (kern_mknodat(td, AT_FDCWD, uap->path, UIO_USERSPACE,
uap->mode, uap->dev));
}
-#ifndef _SYS_SYSPROTO_H_
-struct mknodat_args {
- int fd;
- char *path;
- mode_t mode;
- dev_t dev;
-};
-#endif
int
-sys_mknodat(struct thread *td, struct mknodat_args *uap)
+freebsd11_mknodat(struct thread *td,
+ struct freebsd11_mknodat_args *uap)
{
return (kern_mknodat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode,
uap->dev));
}
+#endif /* COMPAT_FREEBSD11 */
int
kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
- int mode, int dev)
+ int mode, dev_t dev)
{
struct vnode *vp;
struct mount *mp;
@@ -1968,28 +2106,104 @@ cvtstat(struct stat *st, struct ostat *ost)
}
#endif /* COMPAT_43 */
-/*
- * Get file status; this version follows links.
- */
-#ifndef _SYS_SYSPROTO_H_
-struct stat_args {
- char *path;
- struct stat *ub;
-};
-#endif
+#if defined(COMPAT_FREEBSD11)
+void
+freebsd11_cvtstat(struct stat *st, struct freebsd11_stat *ost)
+{
+
+ ost->st_dev = st->st_dev;
+ ost->st_ino = st->st_ino; /* truncate */
+ ost->st_mode = st->st_mode;
+ ost->st_nlink = st->st_nlink; /* truncate */
+ ost->st_uid = st->st_uid;
+ ost->st_gid = st->st_gid;
+ ost->st_rdev = st->st_rdev;
+ ost->st_atim = st->st_atim;
+ ost->st_mtim = st->st_mtim;
+ ost->st_ctim = st->st_ctim;
+ ost->st_size = st->st_size;
+ ost->st_blocks = st->st_blocks;
+ ost->st_blksize = st->st_blksize;
+ ost->st_flags = st->st_flags;
+ ost->st_gen = st->st_gen;
+ ost->st_lspare = 0;
+ ost->st_birthtim = st->st_birthtim;
+ bzero((char *)&ost->st_birthtim + sizeof(ost->st_birthtim),
+ sizeof(*ost) - offsetof(struct freebsd11_stat,
+ st_birthtim) - sizeof(ost->st_birthtim));
+}
+
int
-sys_stat(struct thread *td, struct stat_args *uap)
+freebsd11_stat(struct thread *td, struct freebsd11_stat_args* uap)
{
struct stat sb;
+ struct freebsd11_stat osb;
int error;
error = kern_statat(td, 0, AT_FDCWD, uap->path, UIO_USERSPACE,
&sb, NULL);
- if (error == 0)
- error = copyout(&sb, uap->ub, sizeof (sb));
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat(&sb, &osb);
+ error = copyout(&osb, uap->ub, sizeof(osb));
+ return (error);
+}
+
+int
+freebsd11_lstat(struct thread *td, struct freebsd11_lstat_args* uap)
+{
+ struct stat sb;
+ struct freebsd11_stat osb;
+ int error;
+
+ error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
+ UIO_USERSPACE, &sb, NULL);
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat(&sb, &osb);
+ error = copyout(&osb, uap->ub, sizeof(osb));
+ return (error);
+}
+
+int
+freebsd11_fhstat(struct thread *td, struct freebsd11_fhstat_args* uap)
+{
+ struct fhandle fh;
+ struct stat sb;
+ struct freebsd11_stat osb;
+ int error;
+
+ error = copyin(uap->u_fhp, &fh, sizeof(fhandle_t));
+ if (error != 0)
+ return (error);
+ error = kern_fhstat(td, fh, &sb);
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat(&sb, &osb);
+ error = copyout(&osb, uap->sb, sizeof(osb));
+ return (error);
+}
+
+int
+freebsd11_fstatat(struct thread *td, struct freebsd11_fstatat_args* uap)
+{
+ struct stat sb;
+ struct freebsd11_stat osb;
+ int error;
+
+ error = kern_statat(td, uap->flag, uap->fd, uap->path,
+ UIO_USERSPACE, &sb, NULL);
+ if (error != 0)
+ return (error);
+ freebsd11_cvtstat(&sb, &osb);
+ error = copyout(&osb, uap->buf, sizeof(osb));
return (error);
}
+#endif /* COMPAT_FREEBSD11 */
+/*
+ * Get file status
+ */
#ifndef _SYS_SYSPROTO_H_
struct fstatat_args {
int fd;
@@ -2042,6 +2256,12 @@ kern_statat(struct thread *td, int flag, int fd, char *path,
vput(nd.ni_vp);
if (error != 0)
return (error);
+#ifdef __STAT_TIME_T_EXT
+ sb.st_atim_ext = 0;
+ sb.st_mtim_ext = 0;
+ sb.st_ctim_ext = 0;
+ sb.st_btim_ext = 0;
+#endif
*sbp = sb;
#ifdef KTRACE
if (KTRPOINT(td, KTR_STRUCT))
@@ -2050,36 +2270,15 @@ kern_statat(struct thread *td, int flag, int fd, char *path,
return (0);
}
-/*
- * Get file status; this version does not follow links.
- */
-#ifndef _SYS_SYSPROTO_H_
-struct lstat_args {
- char *path;
- struct stat *ub;
-};
-#endif
-int
-sys_lstat(struct thread *td, struct lstat_args *uap)
-{
- struct stat sb;
- int error;
-
- error = kern_statat(td, AT_SYMLINK_NOFOLLOW, AT_FDCWD, uap->path,
- UIO_USERSPACE, &sb, NULL);
- if (error == 0)
- error = copyout(&sb, uap->ub, sizeof (sb));
- return (error);
-}
-
+#if defined(COMPAT_FREEBSD11)
/*
* Implementation of the NetBSD [l]stat() functions.
*/
void
-cvtnstat( struct stat *sb, struct nstat *nsb)
+freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb)
{
- bzero(nsb, sizeof *nsb);
+ bzero(nsb, sizeof(*nsb));
nsb->st_dev = sb->st_dev;
nsb->st_ino = sb->st_ino;
nsb->st_mode = sb->st_mode;
@@ -2099,13 +2298,13 @@ cvtnstat( struct stat *sb, struct nstat *nsb)
}
#ifndef _SYS_SYSPROTO_H_
-struct nstat_args {
+struct freebsd11_nstat_args {
char *path;
struct nstat *ub;
};
#endif
int
-sys_nstat(struct thread *td, struct nstat_args *uap)
+freebsd11_nstat(struct thread *td, struct freebsd11_nstat_args *uap)
{
struct stat sb;
struct nstat nsb;
@@ -2115,7 +2314,7 @@ sys_nstat(struct thread *td, struct nstat_args *uap)
&sb, NULL);
if (error != 0)
return (error);
- cvtnstat(&sb, &nsb);
+ freebsd11_cvtnstat(&sb, &nsb);
return (copyout(&nsb, uap->ub, sizeof (nsb)));
}
@@ -2123,13 +2322,13 @@ sys_nstat(struct thread *td, struct nstat_args *uap)
* NetBSD lstat. Get file status; this version does not follow links.
*/
#ifndef _SYS_SYSPROTO_H_
-struct lstat_args {
+struct freebsd11_nlstat_args {
char *path;
- struct stat *ub;
+ struct nstat *ub;
};
#endif
int
-sys_nlstat(struct thread *td, struct nlstat_args *uap)
+freebsd11_nlstat(struct thread *td, struct freebsd11_nlstat_args *uap)
{
struct stat sb;
struct nstat nsb;
@@ -2139,9 +2338,10 @@ sys_nlstat(struct thread *td, struct nlstat_args *uap)
UIO_USERSPACE, &sb, NULL);
if (error != 0)
return (error);
- cvtnstat(&sb, &nsb);
+ freebsd11_cvtnstat(&sb, &nsb);
return (copyout(&nsb, uap->ub, sizeof (nsb)));
}
+#endif /* COMPAT_FREEBSD11 */
/*
* Get configurable pathname variables.
@@ -3502,7 +3702,87 @@ out:
return (error);
}
+#if defined(COMPAT_43) || defined(COMPAT_FREEBSD11)
+int
+freebsd11_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int count,
+ long *basep, void (*func)(struct freebsd11_dirent *))
+{
+ struct freebsd11_dirent dstdp;
+ struct dirent *dp, *edp;
+ char *dirbuf;
+ off_t base;
+ ssize_t resid, ucount;
+ int error;
+
+ /* XXX arbitrary sanity limit on `count'. */
+ count = min(count, 64 * 1024);
+
+ dirbuf = malloc(count, M_TEMP, M_WAITOK);
+
+ error = kern_getdirentries(td, fd, dirbuf, count, &base, &resid,
+ UIO_SYSSPACE);
+ if (error != 0)
+ goto done;
+ if (basep != NULL)
+ *basep = base;
+
+ ucount = 0;
+ for (dp = (struct dirent *)dirbuf,
+ edp = (struct dirent *)&dirbuf[count - resid];
+ ucount < count && dp < edp; ) {
+ if (dp->d_reclen == 0)
+ break;
+ MPASS(dp->d_reclen >= _GENERIC_DIRLEN(0));
+ if (dp->d_namlen >= sizeof(dstdp.d_name))
+ continue;
+ dstdp.d_type = dp->d_type;
+ dstdp.d_namlen = dp->d_namlen;
+ dstdp.d_fileno = dp->d_fileno; /* truncate */
+ dstdp.d_reclen = sizeof(dstdp) - sizeof(dstdp.d_name) +
+ ((dp->d_namlen + 1 + 3) &~ 3);
+ bcopy(dp->d_name, dstdp.d_name, dstdp.d_namlen);
+ bzero(dstdp.d_name + dstdp.d_namlen,
+ dstdp.d_reclen - offsetof(struct freebsd11_dirent, d_name) -
+ dstdp.d_namlen);
+ MPASS(dstdp.d_reclen <= dp->d_reclen);
+ MPASS(ucount + dstdp.d_reclen <= count);
+ if (func != NULL)
+ func(&dstdp);
+ error = copyout(&dstdp, ubuf + ucount, dstdp.d_reclen);
+ if (error != 0)
+ break;
+ dp = (struct dirent *)((char *)dp + dp->d_reclen);
+ ucount += dstdp.d_reclen;
+ }
+
+done:
+ free(dirbuf, M_TEMP);
+ if (error == 0)
+ td->td_retval[0] = ucount;
+ return (error);
+}
+#endif /* COMPAT */
+
#ifdef COMPAT_43
+static void
+ogetdirentries_cvt(struct freebsd11_dirent *dp)
+{
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+ /*
+ * The expected low byte of dp->d_namlen is our dp->d_type.
+ * The high MBZ byte of dp->d_namlen is our dp->d_namlen.
+ */
+ dp->d_type = dp->d_namlen;
+ dp->d_namlen = 0;
+#else
+ /*
+ * The dp->d_type is the high byte of the expected dp->d_namlen,
+ * so must be zero'ed.
+ */
+ dp->d_type = 0;
+#endif
+}
+
/*
* Read a block of directory entries in a filesystem independent format.
*/
@@ -3530,138 +3810,26 @@ int
kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap,
long *ploff)
{
- struct vnode *vp;
- struct file *fp;
- struct uio auio, kuio;
- struct iovec aiov, kiov;
- struct dirent *dp, *edp;
- cap_rights_t rights;
- caddr_t dirbuf;
- int error, eofflag, readcnt;
- long loff;
- off_t foffset;
+ long base;
+ int error;
/* XXX arbitrary sanity limit on `count'. */
if (uap->count > 64 * 1024)
return (EINVAL);
- error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp);
- if (error != 0)
- return (error);
- if ((fp->f_flag & FREAD) == 0) {
- fdrop(fp, td);
- return (EBADF);
- }
- vp = fp->f_vnode;
- foffset = foffset_lock(fp, 0);
-unionread:
- if (vp->v_type != VDIR) {
- foffset_unlock(fp, foffset, 0);
- fdrop(fp, td);
- return (EINVAL);
- }
- aiov.iov_base = uap->buf;
- aiov.iov_len = uap->count;
- auio.uio_iov = &aiov;
- auio.uio_iovcnt = 1;
- auio.uio_rw = UIO_READ;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_td = td;
- auio.uio_resid = uap->count;
- vn_lock(vp, LK_SHARED | LK_RETRY);
- loff = auio.uio_offset = foffset;
-#ifdef MAC
- error = mac_vnode_check_readdir(td->td_ucred, vp);
- if (error != 0) {
- VOP_UNLOCK(vp, 0);
- foffset_unlock(fp, foffset, FOF_NOUPDATE);
- fdrop(fp, td);
- return (error);
- }
-#endif
-# if (BYTE_ORDER != LITTLE_ENDIAN)
- if (vp->v_mount->mnt_maxsymlinklen <= 0) {
- error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag,
- NULL, NULL);
- foffset = auio.uio_offset;
- } else
-# endif
- {
- kuio = auio;
- kuio.uio_iov = &kiov;
- kuio.uio_segflg = UIO_SYSSPACE;
- kiov.iov_len = uap->count;
- dirbuf = malloc(uap->count, M_TEMP, M_WAITOK);
- kiov.iov_base = dirbuf;
- error = VOP_READDIR(vp, &kuio, fp->f_cred, &eofflag,
- NULL, NULL);
- foffset = kuio.uio_offset;
- if (error == 0) {
- readcnt = uap->count - kuio.uio_resid;
- edp = (struct dirent *)&dirbuf[readcnt];
- for (dp = (struct dirent *)dirbuf; dp < edp; ) {
-# if (BYTE_ORDER == LITTLE_ENDIAN)
- /*
- * The expected low byte of
- * dp->d_namlen is our dp->d_type.
- * The high MBZ byte of dp->d_namlen
- * is our dp->d_namlen.
- */
- dp->d_type = dp->d_namlen;
- dp->d_namlen = 0;
-# else
- /*
- * The dp->d_type is the high byte
- * of the expected dp->d_namlen,
- * so must be zero'ed.
- */
- dp->d_type = 0;
-# endif
- if (dp->d_reclen > 0) {
- dp = (struct dirent *)
- ((char *)dp + dp->d_reclen);
- } else {
- error = EIO;
- break;
- }
- }
- if (dp >= edp)
- error = uiomove(dirbuf, readcnt, &auio);
- }
- free(dirbuf, M_TEMP);
- }
- if (error != 0) {
- VOP_UNLOCK(vp, 0);
- foffset_unlock(fp, foffset, 0);
- fdrop(fp, td);
- return (error);
- }
- if (uap->count == auio.uio_resid &&
- (vp->v_vflag & VV_ROOT) &&
- (vp->v_mount->mnt_flag & MNT_UNION)) {
- struct vnode *tvp = vp;
- vp = vp->v_mount->mnt_vnodecovered;
- VREF(vp);
- fp->f_vnode = vp;
- fp->f_data = vp;
- foffset = 0;
- vput(tvp);
- goto unionread;
- }
- VOP_UNLOCK(vp, 0);
- foffset_unlock(fp, foffset, 0);
- fdrop(fp, td);
- td->td_retval[0] = uap->count - auio.uio_resid;
- if (error == 0)
- *ploff = loff;
+
+ error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
+ &base, ogetdirentries_cvt);
+
+ if (error == 0 && uap->basep != NULL)
+ error = copyout(&base, uap->basep, sizeof(long));
+
return (error);
}
#endif /* COMPAT_43 */
-/*
- * Read a block of directory entries in a filesystem independent format.
- */
+#if defined(COMPAT_FREEBSD11)
#ifndef _SYS_SYSPROTO_H_
-struct getdirentries_args {
+struct freebsd11_getdirentries_args {
int fd;
char *buf;
u_int count;
@@ -3669,30 +3837,61 @@ struct getdirentries_args {
};
#endif
int
-sys_getdirentries(struct thread *td, struct getdirentries_args *uap)
+freebsd11_getdirentries(struct thread *td,
+ struct freebsd11_getdirentries_args *uap)
{
long base;
int error;
+ error = freebsd11_kern_getdirentries(td, uap->fd, uap->buf, uap->count,
+ &base, NULL);
+
+ if (error == 0 && uap->basep != NULL)
+ error = copyout(&base, uap->basep, sizeof(long));
+ return (error);
+}
+
+int
+freebsd11_getdents(struct thread *td, struct freebsd11_getdents_args *uap)
+{
+ struct freebsd11_getdirentries_args ap;
+
+ ap.fd = uap->fd;
+ ap.buf = uap->buf;
+ ap.count = uap->count;
+ ap.basep = NULL;
+ return (freebsd11_getdirentries(td, &ap));
+}
+#endif /* COMPAT_FREEBSD11 */
+
+/*
+ * Read a block of directory entries in a filesystem independent format.
+ */
+int
+sys_getdirentries(struct thread *td, struct getdirentries_args *uap)
+{
+ off_t base;
+ int error;
+
error = kern_getdirentries(td, uap->fd, uap->buf, uap->count, &base,
NULL, UIO_USERSPACE);
if (error != 0)
return (error);
if (uap->basep != NULL)
- error = copyout(&base, uap->basep, sizeof(long));
+ error = copyout(&base, uap->basep, sizeof(off_t));
return (error);
}
int
-kern_getdirentries(struct thread *td, int fd, char *buf, u_int count,
- long *basep, ssize_t *residp, enum uio_seg bufseg)
+kern_getdirentries(struct thread *td, int fd, char *buf, size_t count,
+ off_t *basep, ssize_t *residp, enum uio_seg bufseg)
{
struct vnode *vp;
struct file *fp;
struct uio auio;
struct iovec aiov;
cap_rights_t rights;
- long loff;
+ off_t loff;
int error, eofflag;
off_t foffset;
@@ -3759,25 +3958,6 @@ fail:
return (error);
}
-#ifndef _SYS_SYSPROTO_H_
-struct getdents_args {
- int fd;
- char *buf;
- size_t count;
-};
-#endif
-int
-sys_getdents(struct thread *td, struct getdents_args *uap)
-{
- struct getdirentries_args ap;
-
- ap.fd = uap->fd;
- ap.buf = uap->buf;
- ap.count = uap->count;
- ap.basep = NULL;
- return (sys_getdirentries(td, &ap));
-}
-
/*
* Set the mode mask for creation of filesystem nodes.
*/
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index d041c07920de..f61531783707 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -2340,7 +2340,7 @@ vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif)
char *fullpath, *freepath;
int error;
- kif->kf_vnode_type = vntype_to_kinfo(vp->v_type);
+ kif->kf_un.kf_file.kf_file_type = vntype_to_kinfo(vp->v_type);
freepath = NULL;
fullpath = "-";
error = vn_fullpath(curthread, vp, &fullpath, &freepath);
@@ -2369,10 +2369,14 @@ vn_fill_kinfo_vnode(struct vnode *vp, struct kinfo_file *kif)
else
kif->kf_un.kf_file.kf_file_fsid =
vp->v_mount->mnt_stat.f_fsid.val[0];
+ kif->kf_un.kf_file.kf_file_fsid_freebsd11 =
+ kif->kf_un.kf_file.kf_file_fsid; /* truncate */
kif->kf_un.kf_file.kf_file_fileid = va.va_fileid;
kif->kf_un.kf_file.kf_file_mode = MAKEIMODE(va.va_type, va.va_mode);
kif->kf_un.kf_file.kf_file_size = va.va_size;
kif->kf_un.kf_file.kf_file_rdev = va.va_rdev;
+ kif->kf_un.kf_file.kf_file_rdev_freebsd11 =
+ kif->kf_un.kf_file.kf_file_rdev; /* truncate */
return (0);
}
diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c
index d6ccd2f8ef08..10b41ab0acff 100644
--- a/sys/nlm/nlm_advlock.c
+++ b/sys/nlm/nlm_advlock.c
@@ -202,7 +202,7 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
union nfsfh fh;
struct sockaddr *sa;
struct sockaddr_storage ss;
- char servername[MNAMELEN];
+ char *servername;
struct timeval timo;
int retries;
rpcvers_t vers;
@@ -218,6 +218,7 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
ASSERT_VOP_LOCKED(vp, "nlm_advlock_1");
+ servername = malloc(MNAMELEN, M_TEMP, M_WAITOK); /* XXXKIB vp locked */
nmp = VFSTONFS(vp->v_mount);
/*
* Push any pending writes to the server and flush our cache
@@ -381,7 +382,7 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
AUTH_DESTROY(auth);
nlm_host_release(host);
-
+ free(servername, M_TEMP);
return (error);
}
diff --git a/sys/security/audit/audit_private.h b/sys/security/audit/audit_private.h
index 64afa87bc45d..3d99635f7de0 100644
--- a/sys/security/audit/audit_private.h
+++ b/sys/security/audit/audit_private.h
@@ -107,9 +107,9 @@ struct vnode_au_info {
mode_t vn_mode;
uid_t vn_uid;
gid_t vn_gid;
- dev_t vn_dev;
- long vn_fsid;
- long vn_fileid;
+ u_int32_t vn_dev; /* XXX dev_t compatibility */
+ long vn_fsid; /* XXX uint64_t compatibility */
+ long vn_fileid; /* XXX ino_t compatibility */
long vn_gen;
};
@@ -210,7 +210,7 @@ struct audit_record {
int ar_arg_atfd2;
int ar_arg_fflags;
mode_t ar_arg_mode;
- int ar_arg_dev;
+ int ar_arg_dev; /* XXX dev_t compatibility */
long ar_arg_value;
void *ar_arg_addr;
int ar_arg_len;
diff --git a/sys/sys/_types.h b/sys/sys/_types.h
index 8736651ba6f0..1dd7c7df4cf7 100644
--- a/sys/sys/_types.h
+++ b/sys/sys/_types.h
@@ -43,13 +43,13 @@ typedef __uint64_t __fsblkcnt_t;
typedef __uint64_t __fsfilcnt_t;
typedef __uint32_t __gid_t;
typedef __int64_t __id_t; /* can hold a gid_t, pid_t, or uid_t */
-typedef __uint32_t __ino_t; /* inode number */
+typedef __uint64_t __ino_t; /* inode number */
typedef long __key_t; /* IPC key (for Sys V IPC) */
typedef __int32_t __lwpid_t; /* Thread ID (a.k.a. LWP) */
typedef __uint16_t __mode_t; /* permissions */
typedef int __accmode_t; /* access permissions */
typedef int __nl_item;
-typedef __uint16_t __nlink_t; /* link count */
+typedef __uint64_t __nlink_t; /* link count */
typedef __int64_t __off_t; /* file offset */
typedef __int64_t __off64_t; /* file offset (alias) */
typedef __int32_t __pid_t; /* process [group] */
@@ -105,7 +105,7 @@ typedef struct {
long double __max_align2 __aligned(_Alignof(long double));
} __max_align_t;
-typedef __uint32_t __dev_t; /* device number */
+typedef __uint64_t __dev_t; /* device number */
typedef __uint32_t __fixpt_t; /* fixed point number */
diff --git a/sys/sys/acct.h b/sys/sys/acct.h
index 759fdc6e0aa7..fc033b588124 100644
--- a/sys/sys/acct.h
+++ b/sys/sys/acct.h
@@ -45,12 +45,12 @@
#define AC_COMM_LEN 16
/*
- * Accounting structure version 2 (current).
+ * Accounting structure version 3 (current).
* The first byte is always zero.
* Time units are microseconds.
*/
-struct acctv2 {
+struct acctv3 {
uint8_t ac_zero; /* zero identifies new version */
uint8_t ac_version; /* record version number */
uint16_t ac_len; /* record length */
@@ -65,10 +65,13 @@ struct acctv2 {
float ac_mem; /* average memory usage */
float ac_io; /* count of IO blocks */
__dev_t ac_tty; /* controlling tty */
-
+ uint32_t ac_pad0;
+#if defined(__powerpc__) && !defined(_LP64)
+ uint32_t ac_pad1;
+#endif
uint16_t ac_len2; /* record length */
union {
- __dev_t ac_align; /* force v1 compatible alignment */
+ uint32_t ac_align; /* force v1 compatible alignment */
#define AFORK 0x01 /* forked but not exec'ed */
/* ASU is no longer supported */
@@ -84,6 +87,28 @@ struct acctv2 {
#define ac_flagx ac_trailer.ac_flag
};
+struct acctv2 {
+ uint8_t ac_zero; /* zero identifies new version */
+ uint8_t ac_version; /* record version number */
+ uint16_t ac_len; /* record length */
+
+ char ac_comm[AC_COMM_LEN]; /* command name */
+ float ac_utime; /* user time */
+ float ac_stime; /* system time */
+ float ac_etime; /* elapsed time */
+ time_t ac_btime; /* starting time */
+ uid_t ac_uid; /* user id */
+ gid_t ac_gid; /* group id */
+ float ac_mem; /* average memory usage */
+ float ac_io; /* count of IO blocks */
+ uint32_t ac_tty; /* controlling tty */
+
+ uint16_t ac_len2; /* record length */
+ union {
+ uint32_t ac_align; /* force v1 compatible alignment */
+ uint8_t ac_flag; /* accounting flags */
+ } ac_trailer;
+};
/*
* Legacy accounting structure (rev. 1.5-1.18).
@@ -105,7 +130,7 @@ struct acctv1 {
gid_t ac_gid; /* group id */
uint16_t ac_mem; /* average memory usage */
comp_t ac_io; /* count of IO blocks */
- __dev_t ac_tty; /* controlling tty */
+ uint32_t ac_tty; /* controlling tty */
uint8_t ac_flag; /* accounting flags */
};
diff --git a/sys/sys/dirent.h b/sys/sys/dirent.h
index ed3f6f5c7746..472142f960b4 100644
--- a/sys/sys/dirent.h
+++ b/sys/sys/dirent.h
@@ -36,22 +36,39 @@
#include <sys/cdefs.h>
#include <sys/_types.h>
+#ifndef _INO_T_DECLARED
+typedef __ino_t ino_t;
+#define _INO_T_DECLARED
+#endif
+
+#ifndef _OFF_T_DECLARED
+typedef __off_t off_t;
+#define _OFF_T_DECLARED
+#endif
+
/*
* The dirent structure defines the format of directory entries returned by
* the getdirentries(2) system call.
*
* A directory entry has a struct dirent at the front of it, containing its
* inode number, the length of the entry, and the length of the name
- * contained in the entry. These are followed by the name padded to a 4
+ * contained in the entry. These are followed by the name padded to an 8
* byte boundary with null bytes. All names are guaranteed null terminated.
* The maximum length of a name in a directory is MAXNAMLEN.
+ *
+ * Explicit padding between the last member of the header (d_namelen) and
+ * d_name avoids ABI padding at the end of dirent on LP64 architectures.
+ * There is code depending on d_name being last.
*/
struct dirent {
- __uint32_t d_fileno; /* file number of entry */
+ ino_t d_fileno; /* file number of entry */
+ off_t d_off; /* directory offset of entry */
__uint16_t d_reclen; /* length of this record */
- __uint8_t d_type; /* file type, see below */
- __uint8_t d_namlen; /* length of string in d_name */
+ __uint8_t d_type; /* file type, see below */
+ __uint8_t d_pad0;
+ __uint16_t d_namlen; /* length of string in d_name */
+ __uint16_t d_pad1;
#if __BSD_VISIBLE
#define MAXNAMLEN 255
char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */
@@ -60,7 +77,18 @@ struct dirent {
#endif
};
+#if defined(_WANT_FREEBSD11_DIRENT) || defined(_KERNEL)
+struct freebsd11_dirent {
+ __uint32_t d_fileno; /* file number of entry */
+ __uint16_t d_reclen; /* length of this record */
+ __uint8_t d_type; /* file type, see below */
+ __uint8_t d_namlen; /* length of string in d_name */
+ char d_name[255 + 1]; /* name must be no longer than this */
+};
+#endif /* _WANT_FREEBSD11_DIRENT || _KERNEL */
+
#if __BSD_VISIBLE
+
/*
* File types
*/
@@ -84,13 +112,14 @@ struct dirent {
* The _GENERIC_DIRSIZ macro gives the minimum record length which will hold
* the directory entry. This returns the amount of space in struct direct
* without the d_name field, plus enough space for the name with a terminating
- * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ * null byte (dp->d_namlen+1), rounded up to a 8 byte boundary.
*
* XXX although this macro is in the implementation namespace, it requires
* a manifest constant that is not.
*/
-#define _GENERIC_DIRSIZ(dp) \
- ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+#define _GENERIC_DIRLEN(namlen) \
+ ((__offsetof(struct dirent, d_name) + (namlen) + 1 + 7) & ~7)
+#define _GENERIC_DIRSIZ(dp) _GENERIC_DIRLEN((dp)->d_namlen)
#endif /* __BSD_VISIBLE */
#ifdef _KERNEL
diff --git a/sys/sys/mount.h b/sys/sys/mount.h
index 9800d97df27e..519b4cf94f52 100644
--- a/sys/sys/mount.h
+++ b/sys/sys/mount.h
@@ -65,8 +65,8 @@ struct fid {
* filesystem statistics
*/
#define MFSNAMELEN 16 /* length of type name including null */
-#define MNAMELEN 88 /* size of on/from name bufs */
-#define STATFS_VERSION 0x20030518 /* current version number */
+#define MNAMELEN 1024 /* size of on/from name bufs */
+#define STATFS_VERSION 0x20140518 /* current version number */
struct statfs {
uint32_t f_version; /* structure version number */
uint32_t f_type; /* type of filesystem */
@@ -92,6 +92,34 @@ struct statfs {
char f_mntonname[MNAMELEN]; /* directory on which mounted */
};
+#if defined(_WANT_FREEBSD11_STATFS) || defined(_KERNEL)
+#define FREEBSD11_STATFS_VERSION 0x20030518 /* current version number */
+struct freebsd11_statfs {
+ uint32_t f_version; /* structure version number */
+ uint32_t f_type; /* type of filesystem */
+ uint64_t f_flags; /* copy of mount exported flags */
+ uint64_t f_bsize; /* filesystem fragment size */
+ uint64_t f_iosize; /* optimal transfer block size */
+ uint64_t f_blocks; /* total data blocks in filesystem */
+ uint64_t f_bfree; /* free blocks in filesystem */
+ int64_t f_bavail; /* free blocks avail to non-superuser */
+ uint64_t f_files; /* total file nodes in filesystem */
+ int64_t f_ffree; /* free nodes avail to non-superuser */
+ uint64_t f_syncwrites; /* count of sync writes since mount */
+ uint64_t f_asyncwrites; /* count of async writes since mount */
+ uint64_t f_syncreads; /* count of sync reads since mount */
+ uint64_t f_asyncreads; /* count of async reads since mount */
+ uint64_t f_spare[10]; /* unused spare */
+ uint32_t f_namemax; /* maximum filename length */
+ uid_t f_owner; /* user that mounted the filesystem */
+ fsid_t f_fsid; /* filesystem id */
+ char f_charspare[80]; /* spare string space */
+ char f_fstypename[16]; /* filesystem type name */
+ char f_mntfromname[88]; /* mounted filesystem */
+ char f_mntonname[88]; /* directory on which mounted */
+};
+#endif /* _WANT_FREEBSD11_STATFS || _KERNEL */
+
#ifdef _KERNEL
#define OMFSNAMELEN 16 /* length of fs type name, including null */
#define OMNAMELEN (88 - 2 * sizeof(long)) /* size of on/from name bufs */
diff --git a/sys/sys/param.h b/sys/sys/param.h
index db976774c7c0..97d1d379111f 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1200030 /* Master, propagated to newvers */
+#define __FreeBSD_version 1200031 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/stat.h b/sys/sys/stat.h
index 6af909aea7c1..95a42b24716a 100644
--- a/sys/sys/stat.h
+++ b/sys/sys/stat.h
@@ -102,9 +102,9 @@ typedef __uid_t uid_t;
#ifdef _KERNEL
struct ostat {
__uint16_t st_dev; /* inode's device */
- ino_t st_ino; /* inode's number */
+ __uint32_t st_ino; /* inode's number */
mode_t st_mode; /* inode protection mode */
- nlink_t st_nlink; /* number of hard links */
+ __uint16_t st_nlink; /* number of hard links */
__uint16_t st_uid; /* user ID of the file's owner */
__uint16_t st_gid; /* group ID of the file's group */
__uint16_t st_rdev; /* device type */
@@ -119,14 +119,15 @@ struct ostat {
};
#endif
-struct stat {
- __dev_t st_dev; /* inode's device */
- ino_t st_ino; /* inode's number */
+#if defined(_WANT_FREEBSD11_STAT) || defined(_KERNEL)
+struct freebsd11_stat {
+ __uint32_t st_dev; /* inode's device */
+ __uint32_t st_ino; /* inode's number */
mode_t st_mode; /* inode protection mode */
- nlink_t st_nlink; /* number of hard links */
+ __uint16_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 */
- __dev_t st_rdev; /* device type */
+ __uint32_t st_rdev; /* device type */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last data modification */
struct timespec st_ctim; /* time of last file status change */
@@ -148,16 +149,55 @@ struct stat {
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
};
+#endif /* _WANT_FREEBSD11_STAT || _KERNEL */
+
+#if defined(__i386__)
+#define __STAT_TIME_T_EXT 1
+#endif
+
+struct stat {
+ dev_t st_dev; /* inode's device */
+ ino_t st_ino; /* inode's number */
+ nlink_t st_nlink; /* number of hard links */
+ mode_t st_mode; /* inode protection mode */
+ __int16_t st_padding0;
+ uid_t st_uid; /* user ID of the file's owner */
+ gid_t st_gid; /* group ID of the file's group */
+ __int32_t st_padding1;
+ dev_t st_rdev; /* device type */
+#ifdef __STAT_TIME_T_EXT
+ __int32_t st_atim_ext;
+#endif
+ struct timespec st_atim; /* time of last access */
+#ifdef __STAT_TIME_T_EXT
+ __int32_t st_mtim_ext;
+#endif
+ struct timespec st_mtim; /* time of last data modification */
+#ifdef __STAT_TIME_T_EXT
+ __int32_t st_ctim_ext;
+#endif
+ struct timespec st_ctim; /* time of last file status change */
+#ifdef __STAT_TIME_T_EXT
+ __int32_t st_btim_ext;
+#endif
+ struct timespec st_birthtim; /* time of file creation */
+ 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 */
+ __uint64_t st_gen; /* file generation number */
+ __uint64_t st_spare[10];
+};
#ifdef _KERNEL
struct nstat {
- __dev_t st_dev; /* inode's device */
- ino_t st_ino; /* inode's number */
+ __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 */
- __dev_t st_rdev; /* device type */
+ __uint32_t st_rdev; /* device type */
struct timespec st_atim; /* time of last access */
struct timespec st_mtim; /* time of last data modification */
struct timespec st_ctim; /* time of last file status change */
@@ -168,7 +208,8 @@ struct nstat {
__uint32_t st_gen; /* file generation number */
struct timespec st_birthtim; /* time of file creation */
/*
- * See above about the following padding.
+ * See comment in the definition of struct freebsd11_stat
+ * above about the following padding.
*/
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
unsigned int :(8 / 2) * (16 - (int)sizeof(struct timespec));
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index d4cfa26045e9..c994ee94f829 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -117,8 +117,8 @@ int kern_futimes(struct thread *td, int fd, struct timeval *tptr,
enum uio_seg tptrseg);
int kern_futimens(struct thread *td, int fd, struct timespec *tptr,
enum uio_seg tptrseg);
-int kern_getdirentries(struct thread *td, int fd, char *buf, u_int count,
- long *basep, ssize_t *residp, enum uio_seg bufseg);
+int kern_getdirentries(struct thread *td, int fd, char *buf, size_t count,
+ off_t *basep, ssize_t *residp, enum uio_seg bufseg);
int kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
size_t *countp, enum uio_seg bufseg, int mode);
int kern_getitimer(struct thread *, u_int, struct itimerval *);
@@ -158,7 +158,7 @@ int kern_mkdirat(struct thread *td, int fd, char *path,
int kern_mkfifoat(struct thread *td, int fd, char *path,
enum uio_seg pathseg, int mode);
int kern_mknodat(struct thread *td, int fd, char *path,
- enum uio_seg pathseg, int mode, int dev);
+ enum uio_seg pathseg, int mode, dev_t dev);
int kern_mlock(struct proc *proc, struct ucred *cred, uintptr_t addr,
size_t len);
int kern_mmap(struct thread *td, uintptr_t addr, size_t size, int prot,
@@ -292,4 +292,9 @@ int kern_socketpair(struct thread *td, int domain, int type, int protocol,
#define KSA_OSIGSET 0x0001 /* uses osigact_t */
#define KSA_FREEBSD4 0x0002 /* uses ucontext4 */
+struct freebsd11_dirent;
+
+int freebsd11_kern_getdirentries(struct thread *td, int fd, char *ubuf, u_int
+ count, long *basep, void (*func)(struct freebsd11_dirent *));
+
#endif /* !_SYS_SYSCALLSUBR_H_ */
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index 09e04195ae55..c37d0bf3d073 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -148,7 +148,7 @@ struct xtty {
pid_t xt_pgid; /* Foreground process group. */
pid_t xt_sid; /* Session. */
unsigned int xt_flags; /* Terminal option flags. */
- dev_t xt_dev; /* Userland device. */
+ uint32_t xt_dev; /* Userland device. XXXKIB truncated */
};
#ifdef _KERNEL
diff --git a/sys/sys/user.h b/sys/sys/user.h
index ab9cee5c8b91..ba5e43a74158 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -84,7 +84,7 @@
* it in two places: function fill_kinfo_proc in sys/kern/kern_proc.c and
* function kvm_proclist in lib/libkvm/kvm_proc.c .
*/
-#define KI_NSPARE_INT 4
+#define KI_NSPARE_INT 2
#define KI_NSPARE_LONG 12
#define KI_NSPARE_PTR 6
@@ -135,7 +135,7 @@ struct kinfo_proc {
pid_t ki_tsid; /* Terminal session ID */
short ki_jobc; /* job control counter */
short ki_spare_short1; /* unused (just here for alignment) */
- dev_t ki_tdev; /* controlling tty dev */
+ uint32_t ki_tdev_freebsd11; /* controlling tty dev */
sigset_t ki_siglist; /* Signals arrived but not delivered */
sigset_t ki_sigmask; /* Current signal mask */
sigset_t ki_sigignore; /* Signals being ignored */
@@ -188,6 +188,7 @@ struct kinfo_proc {
*/
char ki_sparestrings[46]; /* spare string space */
int ki_spareints[KI_NSPARE_INT]; /* spare room for growth */
+ uint64_t ki_tdev; /* controlling tty dev */
int ki_oncpu; /* Which cpu we are on */
int ki_lastcpu; /* Last cpu we were on */
int ki_tracer; /* Pid of tracing process */
@@ -341,14 +342,19 @@ struct kinfo_file {
int kf_flags; /* Flags. */
int kf_pad0; /* Round to 64 bit alignment. */
int64_t kf_offset; /* Seek location. */
- int kf_vnode_type; /* Vnode type. */
- int kf_sock_domain; /* Socket domain. */
- int kf_sock_type; /* Socket type. */
- int kf_sock_protocol; /* Socket protocol. */
- struct sockaddr_storage kf_sa_local; /* Socket address. */
- struct sockaddr_storage kf_sa_peer; /* Peer address. */
union {
struct {
+ uint32_t kf_spareint;
+ /* Socket domain. */
+ int kf_sock_domain0;
+ /* Socket type. */
+ int kf_sock_type0;
+ /* Socket protocol. */
+ int kf_sock_protocol0;
+ /* Socket address. */
+ struct sockaddr_storage kf_sa_local;
+ /* Peer address. */
+ struct sockaddr_storage kf_sa_peer;
/* Address of so_pcb. */
uint64_t kf_sock_pcb;
/* Address of inp_ppcb. */
@@ -363,14 +369,23 @@ struct kinfo_file {
uint32_t kf_sock_pad0;
} kf_sock;
struct {
+ /* Vnode type. */
+ int kf_file_type;
+ /* Space for future use */
+ int kf_spareint[3];
+ uint64_t kf_spareint64[30];
+ /* Vnode filesystem id. */
+ uint64_t kf_file_fsid;
+ /* File device. */
+ uint64_t kf_file_rdev;
/* Global file id. */
uint64_t kf_file_fileid;
/* File size. */
uint64_t kf_file_size;
- /* Vnode filesystem id. */
- uint32_t kf_file_fsid;
- /* File device. */
- uint32_t kf_file_rdev;
+ /* Vnode filesystem id, FreeBSD 11 compat. */
+ uint32_t kf_file_fsid_freebsd11;
+ /* File device, FreeBSD 11 compat. */
+ uint32_t kf_file_rdev_freebsd11;
/* File mode. */
uint16_t kf_file_mode;
/* Round to 64 bit alignment. */
@@ -378,10 +393,14 @@ struct kinfo_file {
uint32_t kf_file_pad1;
} kf_file;
struct {
+ uint32_t kf_spareint[4];
+ uint64_t kf_spareint64[32];
uint32_t kf_sem_value;
uint16_t kf_sem_mode;
} kf_sem;
struct {
+ uint32_t kf_spareint[4];
+ uint64_t kf_spareint64[32];
uint64_t kf_pipe_addr;
uint64_t kf_pipe_peer;
uint32_t kf_pipe_buffer_cnt;
@@ -389,11 +408,17 @@ struct kinfo_file {
uint32_t kf_pipe_pad0[3];
} kf_pipe;
struct {
- uint32_t kf_pts_dev;
+ uint32_t kf_spareint[4];
+ uint64_t kf_spareint64[32];
+ uint32_t kf_pts_dev_freebsd11;
+ uint32_t kf_pts_pad0;
+ uint64_t kf_pts_dev;
/* Round to 64 bit alignment. */
- uint32_t kf_pts_pad0[7];
+ uint32_t kf_pts_pad1[4];
} kf_pts;
struct {
+ uint32_t kf_spareint[4];
+ uint64_t kf_spareint64[32];
pid_t kf_pid;
} kf_proc;
} kf_un;
@@ -405,6 +430,12 @@ struct kinfo_file {
/* Truncated before copyout in sysctl */
char kf_path[PATH_MAX]; /* Path to file, if any. */
};
+#ifndef _KERNEL
+#define kf_vnode_type kf_un.kf_file.kf_file_type
+#define kf_sock_domain kf_un.kf_sock.kf_sock_domain0
+#define kf_sock_type kf_un.kf_sock.kf_sock_type0
+#define kf_sock_protocol kf_un.kf_sock.kf_sock_protocol0
+#endif
/*
* The KERN_PROC_VMMAP sysctl allows a process to dump the VM layout of
@@ -454,7 +485,7 @@ struct kinfo_ovmentry {
void *_kve_pspare[8]; /* Space for more stuff. */
off_t kve_offset; /* Mapping offset in object */
uint64_t kve_fileid; /* inode number if vnode */
- dev_t kve_fsid; /* dev_t of vnode location */
+ uint32_t kve_fsid; /* dev_t of vnode location */
int _kve_ispare[3]; /* Space for more stuff. */
};
@@ -469,7 +500,7 @@ struct kinfo_vmentry {
uint64_t kve_end; /* Finishing address. */
uint64_t kve_offset; /* Mapping offset in object */
uint64_t kve_vn_fileid; /* inode number if vnode */
- uint32_t kve_vn_fsid; /* dev_t of vnode location */
+ uint32_t kve_vn_fsid_freebsd11; /* dev_t of vnode location */
int kve_flags; /* Flags on map entry. */
int kve_resident; /* Number of resident pages. */
int kve_private_resident; /* Number of private pages. */
@@ -478,10 +509,12 @@ struct kinfo_vmentry {
int kve_shadow_count; /* VM obj shadow count. */
int kve_vn_type; /* Vnode type. */
uint64_t kve_vn_size; /* File size. */
- uint32_t kve_vn_rdev; /* Device id if device. */
+ uint32_t kve_vn_rdev_freebsd11; /* Device id if device. */
uint16_t kve_vn_mode; /* File mode. */
uint16_t kve_status; /* Status flags. */
- int _kve_ispare[12]; /* Space for more stuff. */
+ uint64_t kve_vn_fsid; /* dev_t of vnode location */
+ uint64_t kve_vn_rdev; /* Device id if device. */
+ int _kve_ispare[8]; /* Space for more stuff. */
/* Truncated before copyout in sysctl */
char kve_path[PATH_MAX]; /* Path to VM obj, if any. */
};
@@ -495,14 +528,15 @@ struct kinfo_vmobject {
int kvo_type; /* Object type: KVME_TYPE_*. */
uint64_t kvo_size; /* Object size in pages. */
uint64_t kvo_vn_fileid; /* inode number if vnode. */
- uint32_t kvo_vn_fsid; /* dev_t of vnode location. */
+ uint32_t kvo_vn_fsid_freebsd11; /* dev_t of vnode location. */
int kvo_ref_count; /* Reference count. */
int kvo_shadow_count; /* Shadow count. */
int kvo_memattr; /* Memory attribute. */
uint64_t kvo_resident; /* Number of resident pages. */
uint64_t kvo_active; /* Number of active pages. */
uint64_t kvo_inactive; /* Number of inactive pages. */
- uint64_t _kvo_qspare[8];
+ uint64_t kvo_vn_fsid;
+ uint64_t _kvo_qspare[7];
uint32_t _kvo_ispare[8];
char kvo_path[PATH_MAX]; /* Pathname, if any. */
};
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index b688bfd143d2..8bfe851c55e6 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -266,11 +266,12 @@ struct xvnode {
struct vattr {
enum vtype va_type; /* vnode type (for create) */
u_short va_mode; /* files access mode and type */
- short va_nlink; /* number of references to file */
+ u_short va_padding0;
uid_t va_uid; /* owner user id */
gid_t va_gid; /* owner group id */
+ nlink_t va_nlink; /* number of references to file */
dev_t va_fsid; /* filesystem id */
- long va_fileid; /* file id */
+ ino_t va_fileid; /* file id */
u_quad_t va_size; /* file size in bytes */
long va_blocksize; /* blocksize preferred for i/o */
struct timespec va_atime; /* time of last access */
@@ -585,6 +586,7 @@ struct file;
struct mount;
struct nameidata;
struct ostat;
+struct freebsd11_stat;
struct thread;
struct proc;
struct stat;
@@ -613,7 +615,8 @@ void cache_purge_negative(struct vnode *vp);
void cache_purgevfs(struct mount *mp, bool force);
int change_dir(struct vnode *vp, struct thread *td);
void cvtstat(struct stat *st, struct ostat *ost);
-void cvtnstat(struct stat *sb, struct nstat *nsb);
+void freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb);
+void freebsd11_cvtstat(struct stat *st, struct freebsd11_stat *ost);
int getnewvnode(const char *tag, struct mount *mp, struct vop_vector *vops,
struct vnode **vpp);
void getnewvnode_reserve(u_int count);
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 76b69e5053e9..2a73acaad666 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -69,6 +69,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_compat.h"
#include "opt_swap.h"
#include "opt_vm.h"
@@ -2417,10 +2418,24 @@ swap_dev_info(int name, struct xswdev *xs, char *devname, size_t len)
return (error);
}
+#if defined(COMPAT_FREEBSD11)
+#define XSWDEV_VERSION_11 1
+struct xswdev11 {
+ u_int xsw_version;
+ uint32_t xsw_dev;
+ int xsw_flags;
+ int xsw_nblks;
+ int xsw_used;
+};
+#endif
+
static int
sysctl_vm_swap_info(SYSCTL_HANDLER_ARGS)
{
struct xswdev xs;
+#if defined(COMPAT_FREEBSD11)
+ struct xswdev11 xs11;
+#endif
int error;
if (arg2 != 1) /* name length */
@@ -2428,7 +2443,17 @@ sysctl_vm_swap_info(SYSCTL_HANDLER_ARGS)
error = swap_dev_info(*(int *)arg1, &xs, NULL, 0);
if (error != 0)
return (error);
- error = SYSCTL_OUT(req, &xs, sizeof(xs));
+#if defined(COMPAT_FREEBSD11)
+ if (req->oldlen == sizeof(xs11)) {
+ xs11.xsw_version = XSWDEV_VERSION_11;
+ xs11.xsw_dev = xs.xsw_dev; /* truncation */
+ xs11.xsw_flags = xs.xsw_flags;
+ xs11.xsw_nblks = xs.xsw_nblks;
+ xs11.xsw_used = xs.xsw_used;
+ error = SYSCTL_OUT(req, &xs11, sizeof(xs11));
+ } else
+#endif
+ error = SYSCTL_OUT(req, &xs, sizeof(xs));
return (error);
}
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 022fbd57c882..a751ac6ea2ff 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -2342,6 +2342,7 @@ sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
kvo.kvo_vn_fileid = 0;
kvo.kvo_vn_fsid = 0;
+ kvo.kvo_vn_fsid_freebsd11 = 0;
freepath = NULL;
fullpath = "";
vp = NULL;
@@ -2383,6 +2384,8 @@ sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
if (VOP_GETATTR(vp, &va, curthread->td_ucred) == 0) {
kvo.kvo_vn_fileid = va.va_fileid;
kvo.kvo_vn_fsid = va.va_fsid;
+ kvo.kvo_vn_fsid_freebsd11 = va.va_fsid;
+ /* truncate */
}
vput(vp);
}
diff --git a/sys/vm/vm_param.h b/sys/vm/vm_param.h
index c4d72237fd40..8ca83bf18ddf 100644
--- a/sys/vm/vm_param.h
+++ b/sys/vm/vm_param.h
@@ -89,7 +89,7 @@
/*
* Structure for swap device statistics
*/
-#define XSWDEV_VERSION 1
+#define XSWDEV_VERSION 2
struct xswdev {
u_int xsw_version;
dev_t xsw_dev;