diff options
Diffstat (limited to 'sys')
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; |
