kernel - Fix improper mplock in mount path
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 8 Jan 2017 08:33:11 +0000 (00:33 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 8 Jan 2017 08:33:11 +0000 (00:33 -0800)
* VFS_MOUNT() was being called before MNTK_ALL_MPSAFE could be set by
  the filesystem, causing the operation to run with the MP token held.

* Add VFCF_MPSAFE to the vfsconf flags and specify it for MPSAFE filesystems
  in their VFS_SET() specification.  This flag causes MNTK_ALL_MPSAFE to
  be set in mount->mnt_kern_flags prior to the VFS_MOUNT() call.  Set this
  flag for devfs, procfs, tmpfs, nullfs, hammer, and hammer2.

* Primarily effects synth or other bulk-builds which do a lot of mounting.

sys/kern/vfs_syscalls.c
sys/kern/vfs_vfsops.c
sys/sys/mount.h
sys/vfs/devfs/devfs_vfsops.c
sys/vfs/hammer/hammer_vfsops.c
sys/vfs/hammer2/hammer2_vfsops.c
sys/vfs/nfs/nfs_vfsops.c
sys/vfs/nullfs/null_vfsops.c
sys/vfs/procfs/procfs_vfsops.c
sys/vfs/tmpfs/tmpfs_vfsops.c

index e445ad7..ec62e12 100644 (file)
@@ -260,6 +260,7 @@ sys_mount(struct mount_args *uap)
                    uap->flags & (MNT_RELOAD | MNT_FORCE | MNT_UPDATE);
                lwkt_gettoken(&mp->mnt_token);
                vn_unlock(vp);
+               vfsp = mp->mnt_vfc;
                goto update;
        }
 
@@ -364,6 +365,14 @@ update:
            MNT_NOSYMFOLLOW | MNT_IGNORE | MNT_TRIM |
            MNT_NOATIME | MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR |
            MNT_AUTOMOUNTED);
+
+       /*
+        * Pre-set the mount's ALL_MPSAFE flags if specified in the vfsconf.
+        * This way the initial VFS_MOUNT() call will also be MPSAFE.
+        */
+       if (vfsp->vfc_flags & VFCF_MPSAFE)
+               mp->mnt_kern_flag |= MNTK_ALL_MPSAFE;
+
        /*
         * Mount the filesystem.
         * XXX The final recipients of VFS_MOUNT just overwrite the ndp they
index aa1300b..9ca0332 100644 (file)
@@ -284,9 +284,7 @@ vfs_init(struct vfsconf *vfc)
 {
        int error;
 
-       get_mplock();
        error = (vfc->vfc_vfsops->vfs_init)(vfc);
-       rel_mplock();
 
        return (error);
 }
@@ -299,9 +297,7 @@ vfs_uninit(struct vfsconf *vfc, struct vfsconf *vfsp)
 {
        int error;
 
-       get_mplock();
        error = (vfc->vfc_vfsops->vfs_uninit)(vfsp);
-       rel_mplock();
 
        return (error);
 }
index 8072c7f..318a935 100644 (file)
@@ -199,6 +199,12 @@ struct vfs_acct {
  *              mnt_token interlocks operations which adjust the mount
  *              structure and will also be held through VFS operations
  *              for VFSes not flagged MPSAFE.
+ *
+ *              The VFS should pre-set VFCF_MPSAFE in the VFS_SET() to
+ *              avoid use of the mplock during mounting.  This will also
+ *              cause MNTK_ALL_MPSAFE to be set in mnt_kern_flags.  If the
+ *              VFS does not set VFCF_MPSAFE then it can set individual
+ *              MNTK_*_MPSAFE flags in mnt_kern_flags.
  */
 TAILQ_HEAD(vnodelst, vnode);
 TAILQ_HEAD(journallst, journal);
@@ -484,6 +490,7 @@ struct ovfsconf {
 #define VFCF_SYNTHETIC 0x00080000      /* data does not represent real files */
 #define        VFCF_LOOPBACK   0x00100000      /* aliases some other mounted FS */
 #define        VFCF_UNICODE    0x00200000      /* stores file names as Unicode*/
+#define VFCF_MPSAFE    0x00400000      /* VFS is fully MPSAFE */
 
 /* vfsquery flags */
 #define VQ_NOTRESP     0x0001  /* server down */
index 0e26409..da3486d 100644 (file)
@@ -277,5 +277,5 @@ static struct vfsops devfs_vfsops = {
        .vfs_ncpgen_test        = devfs_vfs_ncpgen_test
 };
 
-VFS_SET(devfs_vfsops, devfs, VFCF_SYNTHETIC);
+VFS_SET(devfs_vfsops, devfs, VFCF_SYNTHETIC | VFCF_MPSAFE);
 MODULE_VERSION(devfs, 1);
index 9d9e6b2..9ed3e4a 100644 (file)
@@ -302,7 +302,7 @@ static struct vfsops hammer_vfsops = {
 
 MALLOC_DEFINE(M_HAMMER, "HAMMER-mount", "");
 
-VFS_SET(hammer_vfsops, hammer, 0);
+VFS_SET(hammer_vfsops, hammer, VFCF_MPSAFE);
 MODULE_VERSION(hammer, 1);
 
 static int
index eb37602..6b76200 100644 (file)
@@ -224,7 +224,7 @@ static struct vfsops hammer2_vfsops = {
 
 MALLOC_DEFINE(M_HAMMER2, "HAMMER2-mount", "");
 
-VFS_SET(hammer2_vfsops, hammer2, 0);
+VFS_SET(hammer2_vfsops, hammer2, VFCF_MPSAFE);
 MODULE_VERSION(hammer2, 1);
 
 static
index 89e4400..8c5fd01 100644 (file)
@@ -135,7 +135,7 @@ static struct vfsops nfs_vfsops = {
        .vfs_init =             nfs_init,
        .vfs_uninit =           nfs_uninit
 };
-VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK);
+VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK | VFCF_MPSAFE);
 MODULE_VERSION(nfs, 1);
 
 /*
index 00e0ac7..ee3a5bd 100644 (file)
@@ -406,5 +406,5 @@ static struct vfsops null_vfsops = {
        .vfs_checkexp =         nullfs_checkexp
 };
 
-VFS_SET(null_vfsops, null, VFCF_LOOPBACK);
+VFS_SET(null_vfsops, null, VFCF_LOOPBACK | VFCF_MPSAFE);
 MODULE_VERSION(null, 1);
index 9737a7d..81453b6 100644 (file)
@@ -150,5 +150,5 @@ static struct vfsops procfs_vfsops = {
        .vfs_statfs =           procfs_statfs,
 };
 
-VFS_SET(procfs_vfsops, procfs, VFCF_SYNTHETIC);
+VFS_SET(procfs_vfsops, procfs, VFCF_SYNTHETIC | VFCF_MPSAFE);
 MODULE_VERSION(procfs, 1);
index d81ebfa..ef08a28 100644 (file)
@@ -596,5 +596,5 @@ static struct vfsops tmpfs_vfsops = {
        .vfs_checkexp =                 tmpfs_checkexp,
 };
 
-VFS_SET(tmpfs_vfsops, tmpfs, 0);
+VFS_SET(tmpfs_vfsops, tmpfs, VFCF_MPSAFE);
 MODULE_VERSION(tmpfs, 1);