From 6e6049e9df6850341d51adcd503cfe79a4f35e86 Mon Sep 17 00:00:00 2001 From: "David E. O'Brien" Date: Fri, 19 Sep 2008 15:17:32 +0000 Subject: [PATCH] Add freebsd32 compat shim for nmount(2). (and quiet some compiler warnings for vfs_donmount) --- sys/compat/freebsd32/freebsd32_misc.c | 48 +++++++++++++++++++++++++-- sys/compat/freebsd32/syscalls.master | 2 +- sys/kern/vfs_mount.c | 10 ++---- sys/sys/mount.h | 1 + 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index b9678cb909b0..917a672f676c 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -85,6 +85,8 @@ __FBSDID("$FreeBSD$"); #include +#include + #include #include #include @@ -2552,8 +2554,51 @@ freebsd32_cpuset_setaffinity(struct thread *td, return (cpuset_setaffinity(td, &ap)); } -#if 0 +int +freebsd32_nmount(struct thread *td, + struct freebsd32_nmount_args /* { + struct iovec *iovp; + unsigned int iovcnt; + int flags; + } */ *uap) +{ + struct uio *auio; + struct iovec *iov; + int error, k; + AUDIT_ARG(fflags, uap->flags); + + /* + * Filter out MNT_ROOTFS. We do not want clients of nmount() in + * userspace to set this flag, but we must filter it out if we want + * MNT_UPDATE on the root file system to work. + * MNT_ROOTFS should only be set in the kernel in vfs_mountroot_try(). + */ + uap->flags &= ~MNT_ROOTFS; + + /* + * check that we have an even number of iovec's + * and that we have at least two options. + */ + if ((uap->iovcnt & 1) || (uap->iovcnt < 4)) + return (EINVAL); + + error = freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + for (iov = auio->uio_iov, k = 0; k < uap->iovcnt; ++k, ++iov) { + if (iov->iov_len > MMAXOPTIONLEN) { + free(auio, M_IOV); + return (EINVAL); + } + } + + error = vfs_donmount(td, uap->flags, auio); + free(auio, M_IOV); + return error; +} + +#if 0 int freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) { @@ -2578,5 +2623,4 @@ freebsd32_xxx(struct thread *td, struct freebsd32_xxx_args *uap) } return (error); } - #endif diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 4f3780fc9823..3fedb3e44102 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -651,7 +651,7 @@ 375 AUE_NULL UNIMPL nfsclnt 376 AUE_EACCESS NOPROTO { int eaccess(char *path, int flags); } 377 AUE_NULL UNIMPL afs_syscall -378 AUE_NMOUNT NOPROTO { int nmount(struct iovec *iovp, \ +378 AUE_NMOUNT STD { int freebsd32_nmount(struct iovec32 *iovp, \ unsigned int iovcnt, int flags); } 379 AUE_NULL UNIMPL kse_exit 380 AUE_NULL UNIMPL kse_wakeup diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index a3f440282755..afac5ed1e151 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -77,8 +77,6 @@ static int vfs_domount(struct thread *td, const char *fstype, char *fspath, int fsflags, void *fsdata); static int vfs_mountroot_ask(void); static int vfs_mountroot_try(const char *mountfrom); -static int vfs_donmount(struct thread *td, int fsflags, - struct uio *fsoptions); static void free_mntarg(struct mntarg *ma); static int vfs_getopt_pos(struct vfsoptlist *opts, const char *name); @@ -583,7 +581,7 @@ vfs_mount_destroy(struct mount *mp) uma_zfree(mount_zone, mp); } -static int +int vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) { struct vfsoptlist *optlist; @@ -592,11 +590,9 @@ vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions) int error, fstypelen, fspathlen, errmsg_len, errmsg_pos; int has_rw, has_noro; - errmsg = NULL; - errmsg_len = 0; + errmsg = fspath = NULL; + errmsg_len = has_noro = has_rw = fspathlen = 0; errmsg_pos = -1; - has_rw = 0; - has_noro = 0; error = vfs_buildopts(fsoptions, &optlist); if (error) diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 27a4a60fb76a..5c9a58ebf2ae 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -690,6 +690,7 @@ int vfs_busy(struct mount *, int, struct mtx *); int vfs_export /* process mount export info */ (struct mount *, struct export_args *); int vfs_allocate_syncvnode(struct mount *); +int vfs_donmount(struct thread *td, int fsflags, struct uio *fsoptions); void vfs_getnewfsid(struct mount *); struct cdev *vfs_getrootfsid(struct mount *); struct mount *vfs_getvfs(fsid_t *); /* return vfs given fsid */