Yes, this is known and here is the work in progress to fix it.
There are one or two problem cases still in softraid and wdc.


Index: arch/alpha/alpha/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/alpha/alpha/machdep.c,v
retrieving revision 1.181
diff -u -p -u -r1.181 machdep.c
--- arch/alpha/alpha/machdep.c  29 May 2017 14:19:49 -0000      1.181
+++ arch/alpha/alpha/machdep.c  1 Dec 2017 22:40:09 -0000
@@ -977,7 +977,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v
retrieving revision 1.235
diff -u -p -u -r1.235 machdep.c
--- arch/amd64/amd64/machdep.c  27 Oct 2017 06:48:13 -0000      1.235
+++ arch/amd64/amd64/machdep.c  1 Dec 2017 22:40:05 -0000
@@ -725,7 +725,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/arm/arm/arm32_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/arm/arm/arm32_machdep.c,v
retrieving revision 1.54
diff -u -p -u -r1.54 arm32_machdep.c
--- arch/arm/arm/arm32_machdep.c        12 Aug 2017 13:18:48 -0000      1.54
+++ arch/arm/arm/arm32_machdep.c        1 Dec 2017 22:40:02 -0000
@@ -206,7 +206,7 @@ bootsync(int howto)
                printf("Warning IRQ's disabled during boot()\n");
        }
 
-       vfs_shutdown();
+       vfs_shutdown(curproc);
 
        if ((howto & RB_TIMEBAD) == 0) {
                resettodr();
Index: arch/arm64/arm64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v
retrieving revision 1.22
diff -u -p -u -r1.22 machdep.c
--- arch/arm64/arm64/machdep.c  8 Sep 2017 05:36:51 -0000       1.22
+++ arch/arm64/arm64/machdep.c  1 Dec 2017 22:39:59 -0000
@@ -336,7 +336,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/hppa/hppa/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/hppa/hppa/machdep.c,v
retrieving revision 1.248
diff -u -p -u -r1.248 machdep.c
--- arch/hppa/hppa/machdep.c    18 May 2017 15:41:59 -0000      1.248
+++ arch/hppa/hppa/machdep.c    1 Dec 2017 22:39:55 -0000
@@ -902,7 +902,7 @@ boot(int howto)
 
        if ((howto & RB_NOSYNC) == 0) {
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/i386/i386/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.606
diff -u -p -u -r1.606 machdep.c
--- arch/i386/i386/machdep.c    3 Sep 2017 07:00:53 -0000       1.606
+++ arch/i386/i386/machdep.c    1 Dec 2017 22:39:53 -0000
@@ -2641,7 +2641,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/landisk/landisk/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/landisk/landisk/machdep.c,v
retrieving revision 1.45
diff -u -p -u -r1.45 machdep.c
--- arch/landisk/landisk/machdep.c      30 Apr 2017 16:45:45 -0000      1.45
+++ arch/landisk/landisk/machdep.c      1 Dec 2017 22:39:49 -0000
@@ -202,7 +202,7 @@ boot(int howto)
 
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0) {
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/loongson/loongson/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/loongson/loongson/machdep.c,v
retrieving revision 1.80
diff -u -p -u -r1.80 machdep.c
--- arch/loongson/loongson/machdep.c    26 Aug 2017 13:53:46 -0000      1.80
+++ arch/loongson/loongson/machdep.c    1 Dec 2017 22:39:46 -0000
@@ -1061,7 +1061,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/luna88k/luna88k/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/luna88k/luna88k/machdep.c,v
retrieving revision 1.126
diff -u -p -u -r1.126 machdep.c
--- arch/luna88k/luna88k/machdep.c      3 Nov 2017 09:07:54 -0000       1.126
+++ arch/luna88k/luna88k/machdep.c      1 Dec 2017 22:39:42 -0000
@@ -429,7 +429,7 @@ boot(int howto)
 
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0) {
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/macppc/macppc/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/macppc/macppc/machdep.c,v
retrieving revision 1.181
diff -u -p -u -r1.181 machdep.c
--- arch/macppc/macppc/machdep.c        13 Jun 2017 01:42:12 -0000      1.181
+++ arch/macppc/macppc/machdep.c        1 Dec 2017 22:39:39 -0000
@@ -743,7 +743,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && !syncing) {
                syncing = 1;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/octeon/octeon/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/octeon/octeon/machdep.c,v
retrieving revision 1.101
diff -u -p -u -r1.101 machdep.c
--- arch/octeon/octeon/machdep.c        1 Nov 2017 14:43:01 -0000       1.101
+++ arch/octeon/octeon/machdep.c        1 Dec 2017 22:39:33 -0000
@@ -760,7 +760,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/sgi/sgi/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sgi/sgi/machdep.c,v
retrieving revision 1.156
diff -u -p -u -r1.156 machdep.c
--- arch/sgi/sgi/machdep.c      30 Apr 2017 16:45:45 -0000      1.156
+++ arch/sgi/sgi/machdep.c      1 Dec 2017 22:39:30 -0000
@@ -835,7 +835,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && waittime < 0) {
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/socppc/socppc/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/socppc/socppc/machdep.c,v
retrieving revision 1.72
diff -u -p -u -r1.72 machdep.c
--- arch/socppc/socppc/machdep.c        30 Apr 2017 16:45:45 -0000      1.72
+++ arch/socppc/socppc/machdep.c        1 Dec 2017 22:39:25 -0000
@@ -658,7 +658,7 @@ boot(int howto)
        boothowto = howto;
        if ((howto & RB_NOSYNC) == 0 && !syncing) {
                syncing = 1;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                if ((howto & RB_TIMEBAD) == 0) {
                        resettodr();
Index: arch/sparc64/sparc64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/machdep.c,v
retrieving revision 1.185
diff -u -p -u -r1.185 machdep.c
--- arch/sparc64/sparc64/machdep.c      23 Oct 2017 18:38:33 -0000      1.185
+++ arch/sparc64/sparc64/machdep.c      1 Dec 2017 22:39:20 -0000
@@ -626,7 +626,7 @@ boot(int howto)
                extern int sparc_clock_time_is_ok;
 
                waittime = 0;
-               vfs_shutdown();
+               vfs_shutdown(curproc);
 
                /*
                 * XXX
Index: ddb/db_command.c
===================================================================
RCS file: /cvs/src/sys/ddb/db_command.c,v
retrieving revision 1.80
diff -u -p -u -r1.80 db_command.c
--- ddb/db_command.c    27 Nov 2017 09:23:44 -0000      1.80
+++ ddb/db_command.c    29 Nov 2017 18:36:03 -0000
@@ -770,39 +770,48 @@ db_fncall(db_expr_t addr, int have_addr,
 }
 
 void
+db_reboot(int howto)
+{
+       spl0();
+       if (!curproc)
+               curproc = &proc0;
+       reboot(howto);
+}
+
+void
 db_boot_sync_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
 {
-       reboot(RB_AUTOBOOT | RB_TIMEBAD | RB_USERREQ);
+       db_reboot(RB_AUTOBOOT | RB_TIMEBAD | RB_USERREQ);
 }
 
 void
 db_boot_crash_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
 {
-       reboot(RB_NOSYNC | RB_DUMP | RB_TIMEBAD | RB_USERREQ);
+       db_reboot(RB_NOSYNC | RB_DUMP | RB_TIMEBAD | RB_USERREQ);
 }
 
 void
 db_boot_dump_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
 {
-       reboot(RB_DUMP | RB_TIMEBAD | RB_USERREQ);
+       db_reboot(RB_DUMP | RB_TIMEBAD | RB_USERREQ);
 }
 
 void
 db_boot_halt_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
 {
-       reboot(RB_NOSYNC | RB_HALT | RB_TIMEBAD | RB_USERREQ);
+       db_reboot(RB_NOSYNC | RB_HALT | RB_TIMEBAD | RB_USERREQ);
 }
 
 void
 db_boot_reboot_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
 {
-       reboot(RB_AUTOBOOT | RB_NOSYNC | RB_TIMEBAD | RB_USERREQ);
+       db_reboot(RB_AUTOBOOT | RB_NOSYNC | RB_TIMEBAD | RB_USERREQ);
 }
 
 void
 db_boot_poweroff_cmd(db_expr_t addr, int haddr, db_expr_t count, char *modif)
 {
-       reboot(RB_NOSYNC | RB_HALT | RB_POWERDOWN | RB_TIMEBAD | RB_USERREQ);
+       db_reboot(RB_NOSYNC | RB_HALT | RB_POWERDOWN | RB_TIMEBAD | RB_USERREQ);
 }
 
 void
Index: isofs/cd9660/cd9660_vfsops.c
===================================================================
RCS file: /cvs/src/sys/isofs/cd9660/cd9660_vfsops.c,v
retrieving revision 1.84
diff -u -p -u -r1.84 cd9660_vfsops.c
--- isofs/cd9660/cd9660_vfsops.c        20 Apr 2017 14:13:00 -0000      1.84
+++ isofs/cd9660/cd9660_vfsops.c        29 Nov 2017 15:55:34 -0000
@@ -135,7 +135,7 @@ cd9660_mount(mp, path, data, ndp, p)
        struct proc *p;
 {
        struct iso_mnt *imp = NULL;
-       struct iso_args args;
+       struct iso_args *args = data;
        struct vnode *devvp;
        char fspec[MNAMELEN];
        int error;
@@ -143,26 +143,23 @@ cd9660_mount(mp, path, data, ndp, p)
        if ((mp->mnt_flag & MNT_RDONLY) == 0)
                return (EROFS);
 
-       error = copyin(data, &args, sizeof(struct iso_args));
-       if (error)
-               return (error);
-
        /*
         * If updating, check whether changing from read-only to
         * read/write; if there is no device name, that's all we do.
         */
        if (mp->mnt_flag & MNT_UPDATE) {
                imp = VFSTOISOFS(mp);
-               if (args.fspec == NULL)
+               if (args && args->fspec == NULL)
                        return (vfs_export(mp, &imp->im_export,
-                           &args.export_info));
+                           &args->export_info));
+               return (0);
        }
 
        /*
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
+       error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
        if (error)
                return (error);
        NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fspec, p);
@@ -180,7 +177,7 @@ cd9660_mount(mp, path, data, ndp, p)
        }
 
        if ((mp->mnt_flag & MNT_UPDATE) == 0)
-               error = iso_mountfs(devvp, mp, p, &args);
+               error = iso_mountfs(devvp, mp, p, args);
        else {
                if (devvp != imp->im_devvp)
                        error = EINVAL; /* needs translation */
@@ -198,7 +195,7 @@ cd9660_mount(mp, path, data, ndp, p)
        strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN);
        bzero(mp->mnt_stat.f_mntfromspec, MNAMELEN);
        strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
-       bcopy(&args, &mp->mnt_stat.mount_info.iso_args, sizeof(args));
+       bcopy(args, &mp->mnt_stat.mount_info.iso_args, sizeof(*args));
 
        cd9660_statfs(mp, &mp->mnt_stat, p);
 
Index: isofs/udf/udf_vfsops.c
===================================================================
RCS file: /cvs/src/sys/isofs/udf/udf_vfsops.c,v
retrieving revision 1.60
diff -u -p -u -r1.60 udf_vfsops.c
--- isofs/udf/udf_vfsops.c      8 Sep 2017 05:36:53 -0000       1.60
+++ isofs/udf/udf_vfsops.c      29 Nov 2017 15:55:27 -0000
@@ -122,7 +122,7 @@ udf_mount(struct mount *mp, const char *
     struct nameidata *ndp,  struct proc *p)
 {
        struct vnode *devvp;    /* vnode of the mount device */
-       struct udf_args args;
+       struct udf_args *args = data;
        char fspec[MNAMELEN];
        int error;
 
@@ -140,14 +140,15 @@ udf_mount(struct mount *mp, const char *
        if (mp->mnt_flag & MNT_ROOTFS)
                return (EOPNOTSUPP);
 
-       error = copyin(data, &args, sizeof(struct udf_args));
-       if (error)
-               return (error);
-
-       if (args.fspec == NULL)
-               return (EINVAL);
+       /*
+        * If updating, check whether changing from read-only to
+        * read/write; if there is no device name, that's all we do.
+        */
+       if (mp->mnt_flag & MNT_UPDATE) {
+               return (0);
+       }
 
-       error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
+       error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
        if (error)
                return (error);
 
@@ -166,7 +167,7 @@ udf_mount(struct mount *mp, const char *
                return (ENXIO);
        }
 
-       if ((error = udf_mountfs(devvp, mp, args.lastblock, p))) {
+       if ((error = udf_mountfs(devvp, mp, args->lastblock, p))) {
                vrele(devvp);
                return (error);
        }
Index: miscfs/fuse/fuse_vfsops.c
===================================================================
RCS file: /cvs/src/sys/miscfs/fuse/fuse_vfsops.c,v
retrieving revision 1.29
diff -u -p -u -r1.29 fuse_vfsops.c
--- miscfs/fuse/fuse_vfsops.c   20 Apr 2017 14:13:00 -0000      1.29
+++ miscfs/fuse/fuse_vfsops.c   29 Nov 2017 15:56:20 -0000
@@ -74,19 +74,14 @@ fusefs_mount(struct mount *mp, const cha
 {
        struct fusefs_mnt *fmp;
        struct fusebuf *fbuf;
-       struct fusefs_args args;
+       struct fusefs_args *args = data;
        struct vnode *vp;
        struct file *fp;
-       int error;
 
        if (mp->mnt_flag & MNT_UPDATE)
                return (EOPNOTSUPP);
 
-       error = copyin(data, &args, sizeof(struct fusefs_args));
-       if (error)
-               return (error);
-
-       if ((fp = fd_getfile(p->p_fd, args.fd)) == NULL)
+       if ((fp = fd_getfile(p->p_fd, args->fd)) == NULL)
                return (EBADF);
 
        if (fp->f_type != DTYPE_VNODE)
@@ -100,8 +95,8 @@ fusefs_mount(struct mount *mp, const cha
        fmp->mp = mp;
        fmp->sess_init = 0;
        fmp->dev = vp->v_rdev;
-       if (args.max_read > 0)
-               fmp->max_read = MIN(args.max_read, FUSEBUFMAXSIZE);
+       if (args->max_read > 0)
+               fmp->max_read = MIN(args->max_read, FUSEBUFMAXSIZE);
        else
                fmp->max_read = FUSEBUFMAXSIZE;
 
Index: msdosfs/msdosfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.84
diff -u -p -u -r1.84 msdosfs_vfsops.c
--- msdosfs/msdosfs_vfsops.c    29 May 2017 14:07:16 -0000      1.84
+++ msdosfs/msdosfs_vfsops.c    29 Nov 2017 16:05:20 -0000
@@ -101,17 +101,13 @@ msdosfs_mount(struct mount *mp, const ch
     struct nameidata *ndp, struct proc *p)
 {
        struct vnode *devvp;      /* vnode for blk device to mount */
-       struct msdosfs_args args; /* will hold data from mount request */
+       struct msdosfs_args *args = data; /* will hold data from mount request 
*/
        /* msdosfs specific mount control block */
        struct msdosfsmount *pmp = NULL;
        char fname[MNAMELEN];
        char fspec[MNAMELEN];
        int error, flags;
 
-       error = copyin(data, &args, sizeof(struct msdosfs_args));
-       if (error)
-               return (error);
-
        /*
         * If updating, check whether changing from read-only to
         * read/write; if there is no device name, that's all we do.
@@ -147,11 +143,11 @@ msdosfs_mount(struct mount *mp, const ch
                    (mp->mnt_flag & MNT_WANTRDWR))
                        pmp->pm_flags &= ~MSDOSFSMNT_RONLY;
 
-               if (args.fspec == NULL) {
+               if (args && args->fspec == NULL) {
 #ifdef __notyet__              /* doesn't work correctly with current mountd   
XXX */
-                       if (args.flags & MSDOSFSMNT_MNTOPT) {
+                       if (args->flags & MSDOSFSMNT_MNTOPT) {
                                pmp->pm_flags &= ~MSDOSFSMNT_MNTOPT;
-                               pmp->pm_flags |= args.flags & MSDOSFSMNT_MNTOPT;
+                               pmp->pm_flags |= args->flags & 
MSDOSFSMNT_MNTOPT;
                                if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
                                        pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;
                        }
@@ -160,15 +156,17 @@ msdosfs_mount(struct mount *mp, const ch
                         * Process export requests.
                         */
                        return (vfs_export(mp, &pmp->pm_export,
-                           &args.export_info));
+                           &args->export_info));
                }
+               if (args == NULL)
+                       return (0);
        }
 
        /*
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
+       error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
        if (error)
                goto error;
 
@@ -191,7 +189,7 @@ msdosfs_mount(struct mount *mp, const ch
        }
 
        if ((mp->mnt_flag & MNT_UPDATE) == 0)
-               error = msdosfs_mountfs(devvp, mp, p, &args);
+               error = msdosfs_mountfs(devvp, mp, p, args);
        else {
                if (devvp != pmp->pm_devvp)
                        error = EINVAL; /* XXX needs translation */
@@ -202,10 +200,10 @@ msdosfs_mount(struct mount *mp, const ch
                goto error_devvp;
 
        pmp = VFSTOMSDOSFS(mp);
-       pmp->pm_gid = args.gid;
-       pmp->pm_uid = args.uid;
-       pmp->pm_mask = args.mask;
-       pmp->pm_flags |= args.flags & MSDOSFSMNT_MNTOPT;
+       pmp->pm_gid = args->gid;
+       pmp->pm_uid = args->uid;
+       pmp->pm_mask = args->mask;
+       pmp->pm_flags |= args->flags & MSDOSFSMNT_MNTOPT;
 
        if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
                pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;
@@ -241,7 +239,7 @@ msdosfs_mount(struct mount *mp, const ch
        strlcpy(mp->mnt_stat.f_mntfromname, fname, MNAMELEN);
        bzero(mp->mnt_stat.f_mntfromspec, MNAMELEN);
        strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
-       bcopy(&args, &mp->mnt_stat.mount_info.msdosfs_args, sizeof(args));
+       bcopy(args, &mp->mnt_stat.mount_info.msdosfs_args, sizeof(*args));
 
 #ifdef MSDOSFS_DEBUG
        printf("msdosfs_mount(): mp %p, pmp %p, inusemap %p\n", mp,
Index: nfs/nfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/nfs/nfs_vfsops.c,v
retrieving revision 1.114
diff -u -p -u -r1.114 nfs_vfsops.c
--- nfs/nfs_vfsops.c    17 May 2017 08:59:05 -0000      1.114
+++ nfs/nfs_vfsops.c    29 Nov 2017 16:52:08 -0000
@@ -554,27 +554,14 @@ nfs_mount(struct mount *mp, const char *
     struct nameidata *ndp, struct proc *p)
 {
        int error;
-       struct nfs_args args;
+       struct nfs_args *args = data;
        struct mbuf *nam;
        char hst[MNAMELEN];
        size_t len;
        u_char nfh[NFSX_V3FHMAX];
 
-       error = copyin(data, &args, sizeof(args.version));
-       if (error)
-               return (error);
-       if (args.version == 3) {
-               error = copyin(data, &args, sizeof(struct nfs_args3));
-               args.flags &= ~(NFSMNT_INTERNAL|NFSMNT_NOAC);
-       } else if (args.version == NFS_ARGSVERSION) {
-               error = copyin(data, &args, sizeof(struct nfs_args));
-               args.flags &= ~NFSMNT_NOAC; /* XXX - compatibility */
-       } else
-               return (EPROGMISMATCH);
-       if (error)
-               return (error);
-
-       if ((args.flags & (NFSMNT_NFSV3|NFSMNT_RDIRPLUS)) == NFSMNT_RDIRPLUS)
+       if (args &&
+           (args->flags & (NFSMNT_NFSV3|NFSMNT_RDIRPLUS)) == NFSMNT_RDIRPLUS)
                return (EINVAL);
 
        if (nfs_niothreads < 0) {
@@ -591,26 +578,28 @@ nfs_mount(struct mount *mp, const char *
                 * When doing an update, we can't change from or to
                 * v3.
                 */
-               args.flags = (args.flags & ~(NFSMNT_NFSV3)) |
-                   (nmp->nm_flag & (NFSMNT_NFSV3));
-               nfs_decode_args(nmp, &args, &mp->mnt_stat.mount_info.nfs_args);
+               if (args) {
+                       args->flags = (args->flags & ~(NFSMNT_NFSV3)) |
+                           (nmp->nm_flag & (NFSMNT_NFSV3));
+                       nfs_decode_args(nmp, args, 
&mp->mnt_stat.mount_info.nfs_args);
+               }
                return (0);
        }
-       if (args.fhsize < 0 || args.fhsize > NFSX_V3FHMAX)
+       if (args->fhsize < 0 || args->fhsize > NFSX_V3FHMAX)
                return (EINVAL);
-       error = copyin(args.fh, nfh, args.fhsize);
+       error = copyin(args->fh, nfh, args->fhsize);
        if (error)
                return (error);
-       error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
+       error = copyinstr(args->hostname, hst, MNAMELEN-1, &len);
        if (error)
                return (error);
        memset(&hst[len], 0, MNAMELEN - len);
        /* sockargs() call must be after above copyin() calls */
-       error = sockargs(&nam, args.addr, args.addrlen, MT_SONAME);
+       error = sockargs(&nam, args->addr, args->addrlen, MT_SONAME);
        if (error)
                return (error);
-       args.fh = nfh;
-       error = mountnfs(&args, mp, nam, path, hst);
+       args->fh = nfh;
+       error = mountnfs(args, mp, nam, path, hst);
        return (error);
 }
 
Index: ntfs/ntfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/ntfs/ntfs_vfsops.c,v
retrieving revision 1.56
diff -u -p -u -r1.56 ntfs_vfsops.c
--- ntfs/ntfs_vfsops.c  20 Mar 2017 16:44:03 -0000      1.56
+++ ntfs/ntfs_vfsops.c  29 Nov 2017 16:06:07 -0000
@@ -119,7 +119,7 @@ ntfs_mount(struct mount *mp, const char 
 {
        int             err = 0;
        struct vnode    *devvp;
-       struct ntfs_args args;
+       struct ntfs_args *args = data;
        char fname[MNAMELEN];
        char fspec[MNAMELEN];
 
@@ -131,24 +131,19 @@ ntfs_mount(struct mount *mp, const char 
         ***
         */
 
-       /* copy in user arguments*/
-       err = copyin(data, (caddr_t)&args, sizeof (struct ntfs_args));
-       if (err)
-               goto error_1;           /* can't get arguments*/
-
        /*
         * If updating, check whether changing from read-only to
         * read/write; if there is no device name, that's all we do.
         */
        if (mp->mnt_flag & MNT_UPDATE) {
                /* if not updating name...*/
-               if (args.fspec == NULL) {
+               if (args && args->fspec == NULL) {
                        /*
                         * Process export requests.  Jumping to "success"
                         * will return the vfs_export() error code.
                         */
                        struct ntfsmount *ntm = VFSTONTFS(mp);
-                       err = vfs_export(mp, &ntm->ntm_export, 
&args.export_info);
+                       err = vfs_export(mp, &ntm->ntm_export, 
&args->export_info);
                        goto success;
                }
 
@@ -161,7 +156,7 @@ ntfs_mount(struct mount *mp, const char 
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       err = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
+       err = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
        if (err)
                goto error_1;
 
@@ -203,7 +198,7 @@ ntfs_mount(struct mount *mp, const char 
                 * Update device name only on success
                 */
                if( !err) {
-                       err = set_statfs_info(NULL, UIO_USERSPACE, args.fspec,
+                       err = set_statfs_info(NULL, UIO_USERSPACE, args->fspec,
                            UIO_USERSPACE, mp, p);
                }
 #endif
@@ -227,9 +222,9 @@ ntfs_mount(struct mount *mp, const char 
                strlcpy(mp->mnt_stat.f_mntfromname, fname, MNAMELEN);
                bzero(mp->mnt_stat.f_mntfromspec, MNAMELEN);
                strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
-               bcopy(&args, &mp->mnt_stat.mount_info.ntfs_args, sizeof(args));
+               bcopy(args, &mp->mnt_stat.mount_info.ntfs_args, sizeof(*args));
                if ( !err) {
-                       err = ntfs_mountfs(devvp, mp, &args, p);
+                       err = ntfs_mountfs(devvp, mp, args, p);
                }
        }
        if (err) {
Index: tmpfs/tmpfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/tmpfs/tmpfs_vfsops.c,v
retrieving revision 1.13
diff -u -p -u -r1.13 tmpfs_vfsops.c
--- tmpfs/tmpfs_vfsops.c        8 Sep 2017 05:36:53 -0000       1.13
+++ tmpfs/tmpfs_vfsops.c        29 Nov 2017 15:51:08 -0000
@@ -84,7 +84,7 @@ int
 tmpfs_mount(struct mount *mp, const char *path, void *data,
     struct nameidata *ndp, struct proc *p)
 {
-       struct tmpfs_args args;
+       struct tmpfs_args *args = data;
        tmpfs_mount_t *tmp;
        tmpfs_node_t *root;
        uint64_t memlimit;
@@ -121,25 +121,25 @@ tmpfs_mount(struct mount *mp, const char
        if (tmpfs_mem_info(1) < TMPFS_PAGES_RESERVED)
                return EINVAL;
 
-       error = copyin(data, &args, sizeof(struct tmpfs_args));
+       error = copyin(data, args, sizeof(struct tmpfs_args));
        if (error)
                return error;
-       if (args.ta_root_uid == VNOVAL || args.ta_root_gid == VNOVAL ||
-           args.ta_root_mode == VNOVAL)
+       if (args->ta_root_uid == VNOVAL || args->ta_root_gid == VNOVAL ||
+           args->ta_root_mode == VNOVAL)
                return EINVAL;
 
        /* Get the memory usage limit for this file-system. */
-       if (args.ta_size_max < PAGE_SIZE) {
+       if (args->ta_size_max < PAGE_SIZE) {
                memlimit = UINT64_MAX;
        } else {
-               memlimit = args.ta_size_max;
+               memlimit = args->ta_size_max;
        }
        KASSERT(memlimit > 0);
 
-       if (args.ta_nodes_max <= 3) {
+       if (args->ta_nodes_max <= 3) {
                nodes = 3 + (memlimit / 1024);
        } else {
-               nodes = args.ta_nodes_max;
+               nodes = args->ta_nodes_max;
        }
        nodes = MIN(nodes, INT_MAX);
        KASSERT(nodes >= 3);
@@ -156,8 +156,8 @@ tmpfs_mount(struct mount *mp, const char
        tmpfs_mntmem_init(tmp, memlimit);
 
        /* Allocate the root node. */
-       error = tmpfs_alloc_node(tmp, VDIR, args.ta_root_uid,
-           args.ta_root_gid, args.ta_root_mode & ALLPERMS, NULL,
+       error = tmpfs_alloc_node(tmp, VDIR, args->ta_root_uid,
+           args->ta_root_gid, args->ta_root_mode & ALLPERMS, NULL,
            VNOVAL, &root);
        KASSERT(error == 0 && root != NULL);
 
@@ -180,7 +180,7 @@ tmpfs_mount(struct mount *mp, const char
 #endif
        vfs_getnewfsid(mp);
 
-       mp->mnt_stat.mount_info.tmpfs_args = args;
+       mp->mnt_stat.mount_info.tmpfs_args = *args;
 
        bzero(&mp->mnt_stat.f_mntonname, sizeof(mp->mnt_stat.f_mntonname));
        bzero(&mp->mnt_stat.f_mntfromname, sizeof(mp->mnt_stat.f_mntfromname));
Index: ufs/ext2fs/ext2fs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.99
diff -u -p -u -r1.99 ext2fs_vfsops.c
--- ufs/ext2fs/ext2fs_vfsops.c  30 May 2017 10:32:53 -0000      1.99
+++ ufs/ext2fs/ext2fs_vfsops.c  29 Nov 2017 16:06:55 -0000
@@ -162,17 +162,13 @@ ext2fs_mount(struct mount *mp, const cha
     struct nameidata *ndp, struct proc *p)
 {
        struct vnode *devvp;
-       struct ufs_args args;
+       struct ufs_args *args = data;
        struct ufsmount *ump = NULL;
        struct m_ext2fs *fs;
        char fname[MNAMELEN];
        char fspec[MNAMELEN];
        int error, flags;
 
-       error = copyin(data, &args, sizeof(struct ufs_args));
-       if (error)
-               return (error);
-
        /*
         * If updating, check whether changing from read-only to
         * read/write; if there is no device name, that's all we do.
@@ -208,19 +204,21 @@ ext2fs_mount(struct mount *mp, const cha
                                fs->e2fs.e2fs_state = E2FS_ERRORS;
                        fs->e2fs_fmod = 1;
                }
-               if (args.fspec == NULL) {
+               if (args && args->fspec == NULL) {
                        /*
                         * Process export requests.
                         */
                        return (vfs_export(mp, &ump->um_export,
-                           &args.export_info));
+                           &args->export_info));
                }
+               if (args == NULL)
+                       goto success;
        }
        /*
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
+       error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
        if (error)
                goto error;
 
@@ -265,7 +263,7 @@ ext2fs_mount(struct mount *mp, const cha
        strlcpy(mp->mnt_stat.f_mntfromname, fname, MNAMELEN);
        memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN);
        strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
-       memcpy(&mp->mnt_stat.mount_info.ufs_args, &args, sizeof(args));
+       memcpy(&mp->mnt_stat.mount_info.ufs_args, args, sizeof(*args));
 
        if (fs->e2fs_fmod != 0) {       /* XXX */
                fs->e2fs_fmod = 0;
Index: ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.166
diff -u -p -u -r1.166 ffs_vfsops.c
--- ufs/ffs/ffs_vfsops.c        29 May 2017 14:07:16 -0000      1.166
+++ ufs/ffs/ffs_vfsops.c        3 Dec 2017 01:40:51 -0000
@@ -206,7 +206,7 @@ ffs_mount(struct mount *mp, const char *
     struct nameidata *ndp, struct proc *p)
 {
        struct vnode *devvp;
-       struct ufs_args args;
+       struct ufs_args *args = data;
        struct ufsmount *ump = NULL;
        struct fs *fs;
        char fname[MNAMELEN];
@@ -214,10 +214,6 @@ ffs_mount(struct mount *mp, const char *
        int error = 0, flags;
        int ronly;
 
-       error = copyin(data, &args, sizeof(struct ufs_args));
-       if (error)
-               return (error);
-
 #ifndef FFS_SOFTUPDATES
        if (mp->mnt_flag & MNT_SOFTDEP) {
                printf("WARNING: soft updates isn't compiled in\n");
@@ -255,6 +251,8 @@ ffs_mount(struct mount *mp, const char *
                         * Get rid of files open for writing.
                         */
                        flags = WRITECLOSE;
+                       if (args == NULL)
+                               flags |= WRITEDEMOTE;
                        if (mp->mnt_flag & MNT_FORCE)
                                flags |= FORCECLOSE;
                        if (fs->fs_flags & FS_DOSOFTDEP) {
@@ -342,12 +340,14 @@ ffs_mount(struct mount *mp, const char *
 
                        ronly = 0;
                }
-               if (args.fspec == NULL) {
+               if (args == NULL)
+                       goto success;
+               if (args->fspec == NULL) {
                        /*
                         * Process export requests.
                         */
                        error = vfs_export(mp, &ump->um_export, 
-                           &args.export_info);
+                           &args->export_info);
                        if (error)
                                goto error_1;
                        else
@@ -359,7 +359,7 @@ ffs_mount(struct mount *mp, const char *
         * Not an update, or updating the name: look up the name
         * and verify that it refers to a sensible block device.
         */
-       error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
+       error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
        if (error)
                goto error_1;
 
@@ -435,7 +435,8 @@ ffs_mount(struct mount *mp, const char *
         *
         * This code is common to root and non-root mounts
         */
-       memcpy(&mp->mnt_stat.mount_info.ufs_args, &args, sizeof(args));
+       if (args)
+               memcpy(&mp->mnt_stat.mount_info.ufs_args, args, sizeof(*args));
        VFS_STATFS(mp, &mp->mnt_stat, p);
 
 success:
Index: ufs/mfs/mfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/ufs/mfs/mfs_vfsops.c,v
retrieving revision 1.54
diff -u -p -u -r1.54 mfs_vfsops.c
--- ufs/mfs/mfs_vfsops.c        10 Jan 2017 19:48:32 -0000      1.54
+++ ufs/mfs/mfs_vfsops.c        29 Nov 2017 16:00:27 -0000
@@ -85,17 +85,13 @@ mfs_mount(struct mount *mp, const char *
     struct nameidata *ndp, struct proc *p)
 {
        struct vnode *devvp;
-       struct mfs_args args;
+       struct mfs_args *args = data;
        struct ufsmount *ump;
        struct fs *fs;
        struct mfsnode *mfsp;
        char fspec[MNAMELEN];
        int flags, error;
 
-       error = copyin(data, &args, sizeof(struct mfs_args));
-       if (error)
-               return (error);
-
        /*
         * If updating, check whether changing from read-only to
         * read/write; if there is no device name, that's all we do.
@@ -114,13 +110,13 @@ mfs_mount(struct mount *mp, const char *
                if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR))
                        fs->fs_ronly = 0;
 #ifdef EXPORTMFS
-               if (args.fspec == NULL)
+               if (args && args->fspec == NULL)
                        return (vfs_export(mp, &ump->um_export, 
-                           &args.export_info));
+                           &args->export_info));
 #endif
                return (0);
        }
-       error = copyinstr(args.fspec, fspec, sizeof(fspec), NULL);
+       error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
        if (error)
                return (error);
        error = getnewvnode(VT_MFS, NULL, &mfs_vops, &devvp);
@@ -132,8 +128,8 @@ mfs_mount(struct mount *mp, const char *
        mfs_minor++;
        mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK | M_ZERO);
        devvp->v_data = mfsp;
-       mfsp->mfs_baseoff = args.base;
-       mfsp->mfs_size = args.size;
+       mfsp->mfs_baseoff = args->base;
+       mfsp->mfs_size = args->size;
        mfsp->mfs_vnode = devvp;
        mfsp->mfs_tid = p->p_tid;
        bufq_init(&mfsp->mfs_bufq, BUFQ_FIFO);
@@ -152,7 +148,7 @@ mfs_mount(struct mount *mp, const char *
        strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN);
        memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN);
        strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
-       memcpy(&mp->mnt_stat.mount_info.mfs_args, &args, sizeof(args));
+       memcpy(&mp->mnt_stat.mount_info.mfs_args, args, sizeof(*args));
 
        return (0);
 }
Index: kern/vfs_init.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_init.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 vfs_init.c
--- kern/vfs_init.c     15 Sep 2016 02:00:16 -0000      1.38
+++ kern/vfs_init.c     29 Nov 2017 16:48:30 -0000
@@ -92,43 +92,53 @@ extern  const struct vfsops tmpfs_vfsops
 /* Set up the filesystem operations for vnodes. */
 static struct vfsconf vfsconflist[] = {
 #ifdef FFS
-        { &ffs_vfsops, MOUNT_FFS, 1, 0, MNT_LOCAL, NULL },
+        { &ffs_vfsops, MOUNT_FFS, 1, 0, MNT_LOCAL, NULL,
+           sizeof(struct ufs_args) },
 #endif
 
 #ifdef MFS
-        { &mfs_vfsops, MOUNT_MFS, 3, 0, MNT_LOCAL, NULL },
+        { &mfs_vfsops, MOUNT_MFS, 3, 0, MNT_LOCAL, NULL,
+           sizeof(struct mfs_args) },
 #endif
 
 #ifdef EXT2FS
-       { &ext2fs_vfsops, MOUNT_EXT2FS, 17, 0, MNT_LOCAL, NULL },
+       { &ext2fs_vfsops, MOUNT_EXT2FS, 17, 0, MNT_LOCAL, NULL,
+           sizeof(struct ufs_args) },
 #endif
 
 #ifdef CD9660
-        { &cd9660_vfsops, MOUNT_CD9660, 14, 0, MNT_LOCAL, NULL },
+        { &cd9660_vfsops, MOUNT_CD9660, 14, 0, MNT_LOCAL, NULL,
+           sizeof(struct iso_args) },
 #endif
 
 #ifdef MSDOSFS
-        { &msdosfs_vfsops, MOUNT_MSDOS, 4, 0, MNT_LOCAL, NULL },
+        { &msdosfs_vfsops, MOUNT_MSDOS, 4, 0, MNT_LOCAL, NULL,
+           sizeof(struct msdosfs_args) },
 #endif
 
 #ifdef NFSCLIENT
-        { &nfs_vfsops, MOUNT_NFS, 2, 0, 0, NULL },
+        { &nfs_vfsops, MOUNT_NFS, 2, 0, 0, NULL,
+           sizeof(struct nfs_args) },
 #endif
 
 #ifdef NTFS
-       { &ntfs_vfsops, MOUNT_NTFS, 6, 0, MNT_LOCAL, NULL },
+       { &ntfs_vfsops, MOUNT_NTFS, 6, 0, MNT_LOCAL, NULL,
+           sizeof(struct ntfs_args) },
 #endif
 
 #ifdef UDF
-       { &udf_vfsops, MOUNT_UDF, 13, 0, MNT_LOCAL, NULL },
+       { &udf_vfsops, MOUNT_UDF, 13, 0, MNT_LOCAL, NULL,
+           sizeof(struct iso_args) },
 #endif
 
 #ifdef FUSE
-       { &fusefs_vfsops, MOUNT_FUSEFS, 18, 0, MNT_LOCAL, NULL },
+       { &fusefs_vfsops, MOUNT_FUSEFS, 18, 0, MNT_LOCAL, NULL,
+           sizeof(struct fusefs_args) },
 #endif
 
 #ifdef TMPFS
-       { &tmpfs_vfsops, MOUNT_TMPFS, 19, 0, MNT_LOCAL, NULL },
+       { &tmpfs_vfsops, MOUNT_TMPFS, 19, 0, MNT_LOCAL, NULL,
+           sizeof(struct tmpfs_args) },
 #endif
 };
 
Index: kern/vfs_subr.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_subr.c,v
retrieving revision 1.261
diff -u -p -u -r1.261 vfs_subr.c
--- kern/vfs_subr.c     4 Dec 2017 09:38:20 -0000       1.261
+++ kern/vfs_subr.c     5 Dec 2017 03:35:40 -0000
@@ -857,7 +857,8 @@ struct vflush_args {
 };
 
 int
-vflush_vnode(struct vnode *vp, void *arg) {
+vflush_vnode(struct vnode *vp, void *arg)
+{
        struct vflush_args *va = arg;
        struct proc *p = curproc;
 
@@ -903,6 +904,12 @@ vflush_vnode(struct vnode *vp, void *arg
                return (0);
        }
 
+       if (va->flags & WRITEDEMOTE) {
+               vp->v_op = &dead_vops;
+               vp->v_tag = VT_NON;
+               return (0);
+       }
+
 #ifdef DEBUG
        if (busyprt)
                vprint("vflush: busy vnode", vp);
@@ -1572,37 +1579,52 @@ vaccess(enum vtype type, mode_t file_mod
        return (file_mode & mask) == mask ? 0 : EACCES;
 }
 
+int
+vfs_readonly(struct mount *mp, struct proc *p)
+{
+       int error;
+
+       error = vfs_busy(mp, VB_WRITE|VB_WAIT);
+       if (error) {
+               printf("%s: busy\n", mp->mnt_stat.f_mntonname);
+               return (error);
+       }
+       uvm_vnp_sync(mp);
+       error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p);
+       if (error) {
+               printf("%s: failed to sync\n", mp->mnt_stat.f_mntonname);
+               vfs_unbusy(mp);
+               return (error);
+       }
+
+       mp->mnt_flag |= MNT_UPDATE | MNT_RDONLY;
+       error = VFS_MOUNT(mp, mp->mnt_stat.f_mntonname, NULL, NULL, curproc);
+       if (error) {
+               printf("%s: failed to remount rdonly, error %d\n",
+                   mp->mnt_stat.f_mntonname, error);
+               vfs_unbusy(mp);
+               return (error);
+       }
+       if (mp->mnt_syncer != NULL)
+               vgone(mp->mnt_syncer);
+       mp->mnt_syncer = NULL;
+       vfs_unbusy(mp);
+       return (error);
+}
+
 /*
- * Unmount all file systems.
+ * Read-only all file systems.
  * We traverse the list in reverse order under the assumption that doing so
  * will avoid needing to worry about dependencies.
  */
 void
-vfs_unmountall(void)
+vfs_rofs(struct proc *p)
 {
        struct mount *mp, *nmp;
-       int allerror, error, again = 1;
 
- retry:
-       allerror = 0;
        TAILQ_FOREACH_REVERSE_SAFE(mp, &mountlist, mntlist, mnt_list, nmp) {
-               if (vfs_busy(mp, VB_WRITE|VB_NOWAIT))
-                       continue;
                /* XXX Here is a race, the next pointer is not locked. */
-               if ((error = dounmount(mp, MNT_FORCE, curproc)) != 0) {
-                       printf("unmount of %s failed with error %d\n",
-                           mp->mnt_stat.f_mntonname, error);
-                       allerror = 1;
-               }
-       }
-
-       if (allerror) {
-               printf("WARNING: some file systems would not unmount\n");
-               if (again) {
-                       printf("retrying\n");
-                       again = 0;
-                       goto retry;
-               }
+               (void) vfs_readonly(mp, p);
        }
 }
 
@@ -1610,26 +1632,21 @@ vfs_unmountall(void)
  * Sync and unmount file systems before shutting down.
  */
 void
-vfs_shutdown(void)
+vfs_shutdown(struct proc *p)
 {
 #ifdef ACCOUNTING
        acct_shutdown();
 #endif
 
-       /* XXX Should suspend scheduling. */
-       (void) spl0();
-
        printf("syncing disks... ");
 
        if (panicstr == 0) {
-               /* Sync before unmount, in case we hang on something. */
-               sys_sync(&proc0, NULL, NULL);
-
-               /* Unmount file systems. */
-               vfs_unmountall();
+               /* Take all filesystems to read-only */
+               sys_sync(p, NULL, NULL);
+               vfs_rofs(p);
        }
 
-       if (vfs_syncwait(1))
+       if (vfs_syncwait(p, 1))
                printf("giving up\n");
        else
                printf("done\n");
@@ -1641,20 +1658,16 @@ vfs_shutdown(void)
 
 /*
  * perform sync() operation and wait for buffers to flush.
- * assumptions: called w/ scheduler disabled and physical io enabled
- * for now called at spl0() XXX
  */
 int
-vfs_syncwait(int verbose)
+vfs_syncwait(struct proc *p, int verbose)
 {
        struct buf *bp;
        int iter, nbusy, dcount, s;
-       struct proc *p;
 #ifdef MULTIPROCESSOR
        int hold_count;
 #endif
 
-       p = curproc? curproc : &proc0;
        sys_sync(p, NULL, NULL);
 
        /* Wait for sync to finish. */
Index: kern/vfs_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.272
diff -u -p -u -r1.272 vfs_syscalls.c
--- kern/vfs_syscalls.c 15 Apr 2017 13:56:43 -0000      1.272
+++ kern/vfs_syscalls.c 5 Dec 2017 04:00:20 -0000
@@ -114,6 +114,7 @@ sys_mount(struct proc *p, void *v, regis
        struct nameidata nd;
        struct vfsconf *vfsp;
        int flags = SCARG(uap, flags);
+       void *args = NULL;
 
        if ((error = suser(p, 0)))
                return (error);
@@ -130,15 +131,24 @@ sys_mount(struct proc *p, void *v, regis
         */
        NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspath, p);
        if ((error = namei(&nd)) != 0)
-               return (error);
+               goto fail;
        vp = nd.ni_vp;
        if (flags & MNT_UPDATE) {
                if ((vp->v_flag & VROOT) == 0) {
                        vput(vp);
-                       return (EINVAL);
+                       error = EINVAL;
+                       goto fail;
                }
                mp = vp->v_mount;
                vfsp = mp->mnt_vfc;
+
+               args = malloc(vfsp->vfc_datasize, M_TEMP, M_WAITOK | M_ZERO);
+               error = copyin(SCARG(uap, data), args, vfsp->vfc_datasize);
+               if (error) {
+                       vput(vp);
+                       goto fail;
+               }
+
                mntflag = mp->mnt_flag;
                /*
                 * We only allow the filesystem to be reloaded if it
@@ -147,12 +157,13 @@ sys_mount(struct proc *p, void *v, regis
                if ((flags & MNT_RELOAD) &&
                    ((mp->mnt_flag & MNT_RDONLY) == 0)) {
                        vput(vp);
-                       return (EOPNOTSUPP);    /* Needs translation */
+                       error = EOPNOTSUPP;     /* Needs translation */
+                       goto fail;
                }
 
                if ((error = vfs_busy(mp, VB_READ|VB_NOWAIT)) != 0) {
                        vput(vp);
-                       return (error);
+                       goto fail;
                }
                mp->mnt_flag |= flags & (MNT_RELOAD | MNT_UPDATE);
                goto update;
@@ -164,20 +175,21 @@ sys_mount(struct proc *p, void *v, regis
        if ((flags & MNT_NOPERM) &&
            (flags & (MNT_NODEV | MNT_NOEXEC)) != (MNT_NODEV | MNT_NOEXEC)) {
                vput(vp);
-               return (EPERM);
+               error = EPERM;
+               goto fail;
        }
        if ((error = vinvalbuf(vp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) {
                vput(vp);
-               return (error);
+               goto fail;
        }
        if (vp->v_type != VDIR) {
                vput(vp);
-               return (ENOTDIR);
+               goto fail;
        }
        error = copyinstr(SCARG(uap, type), fstypename, MFSNAMELEN, NULL);
        if (error) {
                vput(vp);
-               return (error);
+               goto fail;
        }
        for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
                if (!strcmp(vfsp->vfc_name, fstypename))
@@ -186,12 +198,21 @@ sys_mount(struct proc *p, void *v, regis
 
        if (vfsp == NULL) {
                vput(vp);
-               return (EOPNOTSUPP);
+               error = EOPNOTSUPP;
+               goto fail;
+       }
+
+       args = malloc(vfsp->vfc_datasize, M_TEMP, M_WAITOK | M_ZERO);
+       error = copyin(SCARG(uap, data), args, vfsp->vfc_datasize);
+       if (error) {
+               vput(vp);
+               goto fail;
        }
 
        if (vp->v_mountedhere != NULL) {
                vput(vp);
-               return (EBUSY);
+               error = EBUSY;
+               goto fail;
        }
 
        /*
@@ -218,7 +239,7 @@ update:
                        free(mp, M_MOUNT, sizeof(*mp));
                }
                vput(vp);
-               return (error);
+               goto fail;
        }
 
        /*
@@ -237,7 +258,7 @@ update:
        /*
         * Mount the filesystem.
         */
-       error = VFS_MOUNT(mp, fspath, SCARG(uap, data), &nd, p);
+       error = VFS_MOUNT(mp, fspath, args, &nd, p);
        if (!error) {
                mp->mnt_stat.f_ctime = time_second;
        }
@@ -261,7 +282,7 @@ update:
                }
 
                vfs_unbusy(mp);
-               return (error);
+               goto fail;
        }
 
        vp->v_mountedhere = mp;
@@ -289,6 +310,9 @@ update:
                vfs_unbusy(vp->v_mount);
                vput(vp);
        }
+fail:
+       if (args)
+               free(args, M_TEMP, vfsp->vfc_datasize);
        return (error);
 }
 
Index: sys/mount.h
===================================================================
RCS file: /cvs/src/sys/sys/mount.h,v
retrieving revision 1.131
diff -u -p -u -r1.131 mount.h
--- sys/mount.h 6 Oct 2017 18:44:22 -0000       1.131
+++ sys/mount.h 1 Dec 2017 22:41:13 -0000
@@ -131,27 +131,6 @@ struct nfs_args {
        int             acdirmin;       /* ac for dir recently modified */
        int             acdirmax;       /* ac for dir not recently modified */
 };
-/* NFS args version 3 (for backwards compatibility) */
-struct nfs_args3 {
-       int             version;        /* args structure version number */
-       struct sockaddr *addr;          /* file server address */
-       int             addrlen;        /* length of address */
-       int             sotype;         /* Socket type */
-       int             proto;          /* and Protocol */
-       u_char          *fh;            /* File handle to be mounted */
-       int             fhsize;         /* Size, in bytes, of fh */
-       int             flags;          /* flags */
-       int             wsize;          /* write size in bytes */
-       int             rsize;          /* read size in bytes */
-       int             readdirsize;    /* readdir size in bytes */
-       int             timeo;          /* initial timeout in .1 secs */
-       int             retrans;        /* times to retry send */
-       int             maxgrouplist;   /* Max. size of group list */
-       int             readahead;      /* # of blocks to readahead */
-       int             leaseterm;      /* Term (sec) of lease */
-       int             deadthresh;     /* Retrans threshold */
-       char            *hostname;      /* server's name */
-};
 
 /*
  * NFS mount option flags
@@ -468,6 +447,7 @@ struct vfsconf {
        int     vfc_refcount;           /* number mounted of this type */
        int     vfc_flags;              /* permanent flags */
        struct  vfsconf *vfc_next;      /* next in list */
+       size_t  vfc_datasize;           /* size of data args */
 };
 
 /* buffer cache statistics */
@@ -592,7 +572,6 @@ struct      mount *vfs_getvfs(fsid_t *);
 int    vfs_mountedon(struct vnode *);
 int    vfs_rootmountalloc(char *, char *, struct mount **);
 void   vfs_unbusy(struct mount *);
-void   vfs_unmountall(void);
 extern TAILQ_HEAD(mntlist, mount) mountlist;
 
 struct mount *getvfs(fsid_t *);            /* return vfs given fsid */
@@ -604,8 +583,8 @@ struct      netcred *vfs_export_lookup(struct
 int    vfs_allocate_syncvnode(struct mount *);
 int    speedup_syncer(void);
 
-int    vfs_syncwait(int);      /* sync and wait for complete */
-void   vfs_shutdown(void);     /* unmount and sync file systems */
+int    vfs_syncwait(struct proc *, int);   /* sync and wait for complete */
+void   vfs_shutdown(struct proc *);        /* unmount and sync file systems */
 int    dounmount(struct mount *, int, struct proc *);
 void   vfsinit(void);
 int    vfs_register(struct vfsconf *);
Index: sys/vnode.h
===================================================================
RCS file: /cvs/src/sys/sys/vnode.h,v
retrieving revision 1.140
diff -u -p -u -r1.140 vnode.h
--- sys/vnode.h 13 Aug 2017 22:02:22 -0000      1.140
+++ sys/vnode.h 30 Nov 2017 01:02:24 -0000
@@ -227,6 +227,7 @@ extern int          vttoif_tab[];
 #define        FORCECLOSE      0x0002          /* vflush: force file closeure 
*/
 #define        WRITECLOSE      0x0004          /* vflush: only close writeable 
files */
 #define        DOCLOSE         0x0008          /* vclean: close active files */
+#define WRITEDEMOTE    0x0010          /* vflush: ok if some writes remain */
 #define        V_SAVE          0x0001          /* vinvalbuf: sync file first */
 #define        V_SAVEMETA      0x0002          /* vinvalbuf: leave indirect 
blocks */
 

Reply via email to