Hi,
here is a patch I must have written after fixing the bugs in mount one or
two years ago. It changes do_sys_mount() so that it only takes as argument
the type of the drive instead of its associated vfsops.

It does change the behavior for the compat layers: now that the associated
vfsops is retrieved via mount_get_vfsops(), the MODULE_CLASS_VFS modules
are autoloaded when a compat binary wants to mount something. Curiously, it
hasn't been the case so far.

Tested quickly on amd64. Ok?


Index: kern/vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.500
diff -u -r1.500 vfs_syscalls.c
--- kern/vfs_syscalls.c 24 Jul 2015 13:02:52 -0000      1.500
+++ kern/vfs_syscalls.c 21 Oct 2015 10:49:53 -0000
@@ -360,13 +360,20 @@
 }
 
 static int
-mount_get_vfsops(const char *fstype, struct vfsops **vfsops)
+mount_get_vfsops(const char *fstype, enum uio_seg type_seg,
+    struct vfsops **vfsops)
 {
        char fstypename[sizeof(((struct statvfs *)NULL)->f_fstypename)];
        int error;
 
-       /* Copy file-system type from userspace.  */
-       error = copyinstr(fstype, fstypename, sizeof(fstypename), NULL);
+       if (type_seg == UIO_USERSPACE) {
+               /* Copy file-system type from userspace.  */
+               error = copyinstr(fstype, fstypename, sizeof(fstypename), NULL);
+       } else {
+               error = copystr(fstype, fstypename, sizeof(fstypename), NULL);
+               KASSERT(error != 0);
+       }
+
        if (error) {
                /*
                 * Historically, filesystem types were identified by numbers.
@@ -445,26 +452,23 @@
                syscallarg(size_t) data_len;
        } */
 
-       return do_sys_mount(l, NULL, SCARG(uap, type), SCARG(uap, path),
+       return do_sys_mount(l, SCARG(uap, type), UIO_USERSPACE, SCARG(uap, 
path),
            SCARG(uap, flags), SCARG(uap, data), UIO_USERSPACE,
            SCARG(uap, data_len), retval);
 }
 
 int
-do_sys_mount(struct lwp *l, struct vfsops *vfsops, const char *type,
+do_sys_mount(struct lwp *l, const char *type, enum uio_seg type_seg,
     const char *path, int flags, void *data, enum uio_seg data_seg,
     size_t data_len, register_t *retval)
 {
+       struct vfsops *vfsops;
        struct vnode *vp;
        void *data_buf = data;
        bool vfsopsrele = false;
        size_t alloc_sz = 0;
        int error;
 
-       /* XXX: The calling convention of this routine is totally bizarre */
-       if (vfsops)
-               vfsopsrele = true;
-
        /*
         * Get vnode to be covered
         */
@@ -474,16 +478,14 @@
                goto done;
        }
 
-       if (vfsops == NULL) {
-               if (flags & (MNT_GETARGS | MNT_UPDATE)) {
-                       vfsops = vp->v_mount->mnt_op;
-               } else {
-                       /* 'type' is userspace */
-                       error = mount_get_vfsops(type, &vfsops);
-                       if (error != 0)
-                               goto done;
-                       vfsopsrele = true;
-               }
+       if (flags & (MNT_GETARGS | MNT_UPDATE)) {
+               vfsops = vp->v_mount->mnt_op;
+       } else {
+               /* 'type' is userspace */
+               error = mount_get_vfsops(type, type_seg, &vfsops);
+               if (error != 0)
+                       goto done;
+               vfsopsrele = true;
        }
 
        /*
Index: sys/mount.h
===================================================================
RCS file: /cvsroot/src/sys/sys/mount.h,v
retrieving revision 1.217
diff -u -r1.217 mount.h
--- sys/mount.h 6 May 2015 15:57:08 -0000       1.217
+++ sys/mount.h 21 Oct 2015 10:49:53 -0000
@@ -475,7 +475,7 @@
 int    mount_domount(struct lwp *, struct vnode **, struct vfsops *,
            const char *, int, void *, size_t *);
 int    dounmount(struct mount *, int, struct lwp *);
-int    do_sys_mount(struct lwp *, struct vfsops *, const char *, const char *,
+int    do_sys_mount(struct lwp *, const char *, enum uio_seg, const char *,
            int, void *, enum uio_seg, size_t, register_t *);
 void   vfsinit(void);
 void   vfs_opv_init(const struct vnodeopv_desc * const *);
Index: compat/common/vfs_syscalls_40.c
===================================================================
RCS file: /cvsroot/src/sys/compat/common/vfs_syscalls_40.c,v
retrieving revision 1.3
diff -u -r1.3 vfs_syscalls_40.c
--- compat/common/vfs_syscalls_40.c     19 Jan 2011 10:21:16 -0000      1.3
+++ compat/common/vfs_syscalls_40.c     21 Oct 2015 10:49:53 -0000
@@ -81,6 +81,6 @@
        } */
        register_t dummy;
 
-       return do_sys_mount(l, NULL, SCARG(uap, type), SCARG(uap, path),
+       return do_sys_mount(l, SCARG(uap, type), UIO_USERSPACE, SCARG(uap, 
path),
            SCARG(uap, flags), SCARG(uap, data), UIO_USERSPACE, 0, &dummy);
 }
Index: compat/freebsd/freebsd_file.c
===================================================================
RCS file: /cvsroot/src/sys/compat/freebsd/freebsd_file.c,v
retrieving revision 1.33
diff -u -r1.33 freebsd_file.c
--- compat/freebsd/freebsd_file.c       9 Nov 2014 18:30:38 -0000       1.33
+++ compat/freebsd/freebsd_file.c       21 Oct 2015 10:49:53 -0000
@@ -98,16 +98,12 @@
                syscallarg(void *) data;
        } */
        const char *type;
-       struct vfsops *vfsops;
        register_t dummy;
 
        if ((type = convert_from_freebsd_mount_type(SCARG(uap, type))) == NULL)
                return ENODEV;
-       vfsops = vfs_getopsbyname(type);
-       if (vfsops == NULL)
-               return ENODEV;
 
-       return do_sys_mount(l, vfsops, NULL, SCARG(uap, path),
+       return do_sys_mount(l, type, UIO_SYSSPACE, SCARG(uap, path),
            SCARG(uap, flags), SCARG(uap, data), UIO_USERSPACE, 0, &dummy);
 }
 
Index: compat/netbsd32/netbsd32_fs.c
===================================================================
RCS file: /cvsroot/src/sys/compat/netbsd32/netbsd32_fs.c,v
retrieving revision 1.72
diff -u -r1.72 netbsd32_fs.c
--- compat/netbsd32/netbsd32_fs.c       5 Oct 2014 20:17:28 -0000       1.72
+++ compat/netbsd32/netbsd32_fs.c       21 Oct 2015 10:49:54 -0000
@@ -958,7 +958,7 @@
        } else {
                data_seg = UIO_USERSPACE;
        }
-       error = do_sys_mount(l, NULL, type, path, flags, data, data_seg,
+       error = do_sys_mount(l, mtype, UIO_SYSSPACE, path, flags, data, 
data_seg,
            data_len, retval);
        if (error)
                return error;
Index: compat/osf1/osf1_mount.c
===================================================================
RCS file: /cvsroot/src/sys/compat/osf1/osf1_mount.c,v
retrieving revision 1.52
diff -u -r1.52 osf1_mount.c
--- compat/osf1/osf1_mount.c    5 Sep 2014 09:21:54 -0000       1.52
+++ compat/osf1/osf1_mount.c    21 Oct 2015 10:49:54 -0000
@@ -261,7 +261,7 @@
        bsd_ma.base = osf_ma.base;
        bsd_ma.size = osf_ma.size;
 
-       return do_sys_mount(l, vfs_getopsbyname("mfs"), NULL, SCARG(uap, path),
+       return do_sys_mount(l, "mfs", UIO_SYSSPACE, SCARG(uap, path),
            SCARG(uap, flags), &bsd_ma, UIO_SYSSPACE, sizeof bsd_ma, &dummy);
 }
 
@@ -312,6 +312,6 @@
        if (bsd_na.flags & NFSMNT_RETRANS)
                bsd_na.retrans = osf_na.retrans;
 
-       return do_sys_mount(l, vfs_getopsbyname("nfs"), NULL, SCARG(uap, path),
+       return do_sys_mount(l, "nfs", UIO_SYSSPACE, SCARG(uap, path),
            SCARG(uap, flags), &bsd_na, UIO_SYSSPACE, sizeof bsd_na, &dummy);
 }
Index: compat/sunos/sunos_misc.c
===================================================================
RCS file: /cvsroot/src/sys/compat/sunos/sunos_misc.c,v
retrieving revision 1.169
diff -u -r1.169 sunos_misc.c
--- compat/sunos/sunos_misc.c   5 Sep 2014 09:21:55 -0000       1.169
+++ compat/sunos/sunos_misc.c   21 Oct 2015 10:49:54 -0000
@@ -279,7 +279,7 @@
                na.retrans = sna.retrans;
                na.hostname = /* (char *)(u_long) */ sna.hostname;
 
-               return do_sys_mount(l, vfs_getopsbyname("nfs"), NULL,
+               return do_sys_mount(l, "nfs", UIO_SYSSPACE,
                    SCARG(uap, dir), nflags, &na,
                    UIO_SYSSPACE, sizeof na, &dummy);
        }
@@ -287,7 +287,7 @@
        if (strcmp(fsname, "4.2") == 0)
                strcpy(fsname, "ffs");
 
-       return do_sys_mount(l, vfs_getopsbyname(fsname), NULL,
+       return do_sys_mount(l, fsname, UIO_SYSSPACE,
            SCARG(uap, dir), nflags, SCARG(uap, data),
            UIO_USERSPACE, 0, &dummy);
 }
Index: compat/sunos32/sunos32_misc.c
===================================================================
RCS file: /cvsroot/src/sys/compat/sunos32/sunos32_misc.c,v
retrieving revision 1.75
diff -u -r1.75 sunos32_misc.c
--- compat/sunos32/sunos32_misc.c       5 Sep 2014 09:21:55 -0000       1.75
+++ compat/sunos32/sunos32_misc.c       21 Oct 2015 10:49:54 -0000
@@ -522,7 +522,7 @@
                na.retrans = sna.retrans;
                na.hostname = (char *)(u_long)sna.hostname;
 
-               return do_sys_mount(l, vfs_getopsbyname("nfs"), NULL,
+               return do_sys_mount(l, "nfs", UIO_SYSSPACE,
                    SCARG_P32(uap, path), nflags, &na, UIO_SYSSPACE, sizeof na,
                    &dummy);
        }
@@ -530,7 +530,7 @@
        if (strcmp(fsname, "4.2") == 0)
                strcpy(fsname, "ffs");
 
-       return do_sys_mount(l, vfs_getopsbyname(fsname), NULL,
+       return do_sys_mount(l, fsname, UIO_SYSSPACE,
            SCARG_P32(uap, path), nflags, SCARG_P32(uap, data), UIO_USERSPACE,
            0, &dummy);
 }
Index: compat/ultrix/ultrix_fs.c
===================================================================
RCS file: /cvsroot/src/sys/compat/ultrix/ultrix_fs.c,v
retrieving revision 1.55
diff -u -r1.55 ultrix_fs.c
--- compat/ultrix/ultrix_fs.c   24 Jul 2015 13:02:52 -0000      1.55
+++ compat/ultrix/ultrix_fs.c   21 Oct 2015 10:49:54 -0000
@@ -401,7 +401,7 @@
                na.timeo = una.timeo;
                na.retrans = una.retrans;
                na.hostname = una.hostname;
-               return do_sys_mount(l, vfs_getopsbyname("nfs"), NULL,
+               return do_sys_mount(l, "nfs", UIO_SYSSPACE,
                    SCARG(uap, special), nflags, &na, UIO_SYSSPACE,
                    sizeof na, &dummy);
        }
@@ -431,7 +431,7 @@
                        printf("COMPAT_ULTRIX: mount with MNT_UPDATE on %s\n",
                            fsname);
                }
-               return do_sys_mount(l, vfs_getopsbyname("ffs"), NULL,
+               return do_sys_mount(l, "ffs", UIO_SYSSPACE,
                    SCARG(uap, dir), nflags, &ua, UIO_SYSSPACE, sizeof ua,
                    &dummy);
        }

Reply via email to