kernel - Rejigger mount code to add vfs_flags in struct vfsops
authorMatthew Dillon <dillon@apollo.backplane.com>
Fri, 14 Feb 2020 23:58:22 +0000 (15:58 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Fri, 14 Feb 2020 23:58:22 +0000 (15:58 -0800)
* Rejigger the mount code so we can add a vfs_flags field to vfsops,
  which mount_init() has visibility to.

* Allows nullfs to flag that its mounts do not need a syncer thread.
  Previously nullfs would destroy the syncer thread after the
  fact.

* Improves dsynth performance (it does lots of nullfs mounts).

25 files changed:
sys/gnu/vfs/ext2fs/ext2_vfsops.c
sys/kern/vfs_conf.c
sys/kern/vfs_mount.c
sys/kern/vfs_sync.c
sys/kern/vfs_syscalls.c
sys/sys/mount.h
sys/sys/vnode.h
sys/vfs/autofs/autofs_vfsops.c
sys/vfs/devfs/devfs_vfsops.c
sys/vfs/dirfs/dirfs_vfsops.c
sys/vfs/fuse/fuse_vfsops.c
sys/vfs/hammer/hammer_vfsops.c
sys/vfs/hammer2/hammer2_vfsops.c
sys/vfs/hpfs/hpfs_vfsops.c
sys/vfs/isofs/cd9660/cd9660_vfsops.c
sys/vfs/mfs/mfs_vfsops.c
sys/vfs/msdosfs/msdosfs_vfsops.c
sys/vfs/nfs/nfs_vfsops.c
sys/vfs/ntfs/ntfs_vfsops.c
sys/vfs/nullfs/null_vfsops.c
sys/vfs/procfs/procfs_vfsops.c
sys/vfs/smbfs/smbfs_vfsops.c
sys/vfs/tmpfs/tmpfs_vfsops.c
sys/vfs/udf/udf_vfsops.c
sys/vfs/ufs/ffs_vfsops.c

index f063f48..f82fc17 100644 (file)
@@ -89,6 +89,7 @@ static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
 MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
 
 static struct vfsops ext2fs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            ext2_mount,
        .vfs_unmount =          ext2_unmount,
        .vfs_root =             ext2_root,      /* root inode via vget */
index 3666d1e..777380a 100644 (file)
@@ -303,9 +303,8 @@ vfs_mountroot_devfs(void)
         * Allocate and initialize the filesystem.
         */
        mp = kmalloc(sizeof(struct mount), M_MOUNT, M_ZERO|M_WAITOK);
-       mount_init(mp);
+       mount_init(mp, vfsp->vfc_vfsops);
        vfs_busy(mp, LK_NOWAIT);
-       mp->mnt_op = vfsp->vfc_vfsops;
        mp->mnt_vfc = vfsp;
        mp->mnt_pbuf_count = nswbuf_kva / NSWBUF_SPLIT;
        vfsp->vfc_refcount++;
index b3e833d..f9e1363 100644 (file)
@@ -160,7 +160,7 @@ vfs_mount_init(void)
        lwkt_token_init(&mountlist_token, "mntlist");
        lwkt_token_init(&mntid_token, "mntid");
        TAILQ_INIT(&mountscan_list);
-       mount_init(&dummymount);
+       mount_init(&dummymount, NULL);
        dummymount.mnt_flag |= MNT_RDONLY;
        dummymount.mnt_kern_flag |= MNTK_ALL_MPSAFE;
 }
@@ -343,12 +343,11 @@ vfs_rootmountalloc(char *fstypename, char *devname, struct mount **mpp)
        if (vfsp == NULL)
                return (ENODEV);
        mp = kmalloc(sizeof(struct mount), M_MOUNT, M_WAITOK | M_ZERO);
-       mount_init(mp);
+       mount_init(mp, vfsp->vfc_vfsops);
        lockinit(&mp->mnt_lock, "vfslock", VLKTIMEOUT, 0);
 
        vfs_busy(mp, 0);
        mp->mnt_vfc = vfsp;
-       mp->mnt_op = vfsp->vfc_vfsops;
        mp->mnt_pbuf_count = nswbuf_kva / NSWBUF_SPLIT;
        vfsp->vfc_refcount++;
        mp->mnt_stat.f_type = vfsp->vfc_typenum;
@@ -372,7 +371,7 @@ vfs_rootmountalloc(char *fstypename, char *devname, struct mount **mpp)
  * Basic mount structure initialization
  */
 void
-mount_init(struct mount *mp)
+mount_init(struct mount *mp, struct vfsops *ops)
 {
        lockinit(&mp->mnt_lock, "vfslock", hz*5, 0);
        lwkt_token_init(&mp->mnt_token, "permnt");
@@ -385,7 +384,9 @@ mount_init(struct mount *mp)
        mp->mnt_flag = 0;
        mp->mnt_hold = 1;               /* hold for umount last drop */
        mp->mnt_iosize_max = MAXPHYS;
-       vn_syncer_thr_create(mp);
+       mp->mnt_op = ops;
+       if (ops == NULL || (ops->vfs_flags & VFSOPSF_NOSYNCERTHR) == 0)
+               vn_syncer_thr_create(mp);
 }
 
 void
@@ -720,6 +721,7 @@ mountlist_exists(struct mount *mp)
  * MNTSCAN_REVERSE     - the mountlist is scanned in reverse
  * MNTSCAN_NOBUSY      - the scanner will make the callback without busying
  *                       the mount node.
+ * MNTSCAN_NOUNLOCK    - Do not unlock mountlist_token across callback
  *
  * NOTE: mountlist_token is not held across the callback.
  */
@@ -730,6 +732,7 @@ mountlist_scan(int (*callback)(struct mount *, void *), void *data, int how)
        struct mount *mp;
        int count;
        int res;
+       int dounlock = ((how & MNTSCAN_NOUNLOCK) == 0);
 
        lwkt_gettoken(&mountlist_token);
        info.msi_how = how;
@@ -745,13 +748,17 @@ mountlist_scan(int (*callback)(struct mount *, void *), void *data, int how)
                while ((mp = info.msi_node) != NULL) {
                        mount_hold(mp);
                        if (how & MNTSCAN_NOBUSY) {
-                               lwkt_reltoken(&mountlist_token);
+                               if (dounlock)
+                                       lwkt_reltoken(&mountlist_token);
                                count = callback(mp, data);
-                               lwkt_gettoken_shared(&mountlist_token);
+                               if (dounlock)
+                                       lwkt_gettoken_shared(&mountlist_token);
                        } else if (vfs_busy(mp, LK_NOWAIT) == 0) {
-                               lwkt_reltoken(&mountlist_token);
+                               if (dounlock)
+                                       lwkt_reltoken(&mountlist_token);
                                count = callback(mp, data);
-                               lwkt_gettoken_shared(&mountlist_token);
+                               if (dounlock)
+                                       lwkt_gettoken_shared(&mountlist_token);
                                if (mp == info.msi_node)
                                        vfs_unbusy(mp);
                        } else {
@@ -769,13 +776,17 @@ mountlist_scan(int (*callback)(struct mount *, void *), void *data, int how)
                while ((mp = info.msi_node) != NULL) {
                        mount_hold(mp);
                        if (how & MNTSCAN_NOBUSY) {
-                               lwkt_reltoken(&mountlist_token);
+                               if (dounlock)
+                                       lwkt_reltoken(&mountlist_token);
                                count = callback(mp, data);
-                               lwkt_gettoken_shared(&mountlist_token);
+                               if (dounlock)
+                                       lwkt_gettoken_shared(&mountlist_token);
                        } else if (vfs_busy(mp, LK_NOWAIT) == 0) {
-                               lwkt_reltoken(&mountlist_token);
+                               if (dounlock)
+                                       lwkt_reltoken(&mountlist_token);
                                count = callback(mp, data);
-                               lwkt_gettoken_shared(&mountlist_token);
+                               if (dounlock)
+                                       lwkt_gettoken_shared(&mountlist_token);
                                if (mp == info.msi_node)
                                        vfs_unbusy(mp);
                        } else {
index 235d703..ac29a66 100644 (file)
@@ -343,8 +343,12 @@ vn_syncer_thr_stop(struct mount *mp)
        wakeup(ctx);
        
        /* Wait till syncer process exits */
-       while ((ctx->sc_flags & SC_FLAG_DONE) == 0) 
-               tsleep(&ctx->sc_flags, 0, "syncexit", hz);
+       while ((ctx->sc_flags & SC_FLAG_DONE) == 0) {
+               tsleep_interlock(&ctx->sc_flags, 0);
+               lwkt_reltoken(&ctx->sc_token);
+               tsleep(&ctx->sc_flags, PINTERLOCKED, "syncexit", hz);
+               lwkt_gettoken(&ctx->sc_token);
+       }
 
        mp->mnt_syncer_ctx = NULL;
        lwkt_reltoken(&ctx->sc_token);
@@ -478,7 +482,8 @@ syncer_thread(void *_ctx)
                    ctx->syncer_trigger == 0) {
                        tsleep_interlock(ctx, 0);
                        if (time_uptime == starttime &&
-                           ctx->syncer_trigger == 0) {
+                           ctx->syncer_trigger == 0 &&
+                           (ctx->sc_flags & SC_FLAG_EXIT) == 0) {
                                tsleep(ctx, PINTERLOCKED, "syncer", hz);
                        }
                }
index d114f77..fc63031 100644 (file)
@@ -342,9 +342,8 @@ sys_mount(struct mount_args *uap)
         * Allocate and initialize the filesystem.
         */
        mp = kmalloc(sizeof(struct mount), M_MOUNT, M_ZERO|M_WAITOK);
-       mount_init(mp);
+       mount_init(mp, vfsp->vfc_vfsops);
        vfs_busy(mp, LK_NOWAIT);
-       mp->mnt_op = vfsp->vfc_vfsops;
        mp->mnt_vfc = vfsp;
        mp->mnt_pbuf_count = nswbuf_kva / NSWBUF_SPLIT;
        vfsp->vfc_refcount++;
index c8327a4..0fc7dbb 100644 (file)
@@ -368,6 +368,7 @@ struct mount {
 #define MNTSCAN_FORWARD                0x0001
 #define MNTSCAN_REVERSE                0x0002
 #define MNTSCAN_NOBUSY         0x0004
+#define MNTSCAN_NOUNLOCK       0x0008
 
 #define MNTINS_FIRST           0x0001
 #define MNTINS_LAST            0x0002
@@ -598,6 +599,7 @@ int vfs_extattrctl(struct mount *mp, int cmd, struct vnode *vp,
 int vfs_modifying(struct mount *mp);
 
 struct vfsops {
+       long            vfs_flags;
        vfs_mount_t     *vfs_mount;
        vfs_start_t     *vfs_start;
        vfs_unmount_t   *vfs_unmount;
@@ -621,6 +623,8 @@ struct vfsops {
        vfs_modifying_t *vfs_modifying;
 };
 
+#define VFSOPSF_NOSYNCERTHR    0x00000001
+
 #define VFS_MOUNT(MP, PATH, DATA, CRED)                \
        vfs_mount(MP, PATH, DATA, CRED)
 #define VFS_START(MP, FLAGS)                   \
index 217380a..e55fb4f 100644 (file)
@@ -422,6 +422,7 @@ struct uio;
 struct vattr;
 struct vnode;
 struct syncer_ctx;
+struct vfsops;
 
 struct vnode *getsynthvnode(const char *devname);
 void   addaliasu (struct vnode *vp, int x, int y);
@@ -572,7 +573,7 @@ void        debug_vput (struct vnode *vp, const char *filename, int line);
 void   vfs_subr_init(void);
 void   vfs_mount_init(void);
 void   vfs_lock_init(void);
-void   mount_init(struct mount *mp);
+void   mount_init(struct mount *mp, struct vfsops *ops);
 void   synchronizevnodecount(void);
 int    countcachedvnodes(void);
 int    countcachedandinactivevnodes(void);
index cf8e0be..6a7c8a1 100644 (file)
@@ -305,6 +305,7 @@ autofs_statvfs(struct mount *mp, struct statvfs *sbp, struct ucred *cred)
 }
 
 static struct vfsops autofs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            autofs_mount,
        .vfs_unmount =          autofs_unmount,
        .vfs_root =             autofs_root,
index 3b158ae..592d7bb 100644 (file)
@@ -268,6 +268,7 @@ devfs_vfs_ncpgen_test(struct mount *mp, struct namecache *ncp)
 }
 
 static struct vfsops devfs_vfsops = {
+       .vfs_flags      = 0,
        .vfs_mount      = devfs_vfs_mount,
        .vfs_unmount    = devfs_vfs_unmount,
        .vfs_root       = devfs_vfs_root,
index f42c784..2485191 100644 (file)
@@ -343,6 +343,7 @@ dirfs_checkexp(struct mount *mp, struct sockaddr *nam, int *exflagsp,
 }
 
 static struct vfsops dirfs_vfsops = {
+       .vfs_flags =                    0,
        .vfs_mount =                    dirfs_mount,
        .vfs_unmount =                  dirfs_unmount,
        .vfs_root =                     dirfs_root,
index 1d039fe..b4a3e8b 100644 (file)
@@ -391,6 +391,7 @@ fuse_uninit(struct vfsconf *vfsp)
 }
 
 static struct vfsops fuse_vfsops = {
+       .vfs_flags = 0,
        .vfs_init = fuse_init,
        .vfs_uninit = fuse_uninit,
        .vfs_mount = fuse_mount,
index 229a797..f31cdf9 100644 (file)
@@ -252,6 +252,7 @@ static int  hammer_vfs_checkexp(struct mount *mp, struct sockaddr *nam,
 
 
 static struct vfsops hammer_vfsops = {
+       .vfs_flags      = 0,
        .vfs_mount      = hammer_vfs_mount,
        .vfs_unmount    = hammer_vfs_unmount,
        .vfs_root       = hammer_vfs_root,
index 730fce5..6e97640 100644 (file)
@@ -242,6 +242,7 @@ static int hammer2_fixup_pfses(hammer2_dev_t *hmp);
  * HAMMER2 vfs operations.
  */
 static struct vfsops hammer2_vfsops = {
+       .vfs_flags      = 0,
        .vfs_init       = hammer2_vfs_init,
        .vfs_uninit     = hammer2_vfs_uninit,
        .vfs_sync       = hammer2_vfs_sync,
index 0aed00a..242c255 100644 (file)
@@ -551,6 +551,7 @@ hpfs_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
 }
 
 static struct vfsops hpfs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            hpfs_mount,
        .vfs_unmount =          hpfs_unmount,
        .vfs_root =             hpfs_root,
index c6d8d20..a91553b 100644 (file)
@@ -82,6 +82,7 @@ static int cd9660_checkexp(struct mount *, struct sockaddr *,
 static int cd9660_vptofh (struct vnode *, struct fid *);
 
 static struct vfsops cd9660_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            cd9660_mount,
        .vfs_unmount =          cd9660_unmount,
        .vfs_root =             cd9660_root,
index bf8c02b..5513436 100644 (file)
@@ -98,6 +98,7 @@ static struct dev_ops mfs_ops = {
  * mfs vfs operations.
  */
 static struct vfsops mfs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            mfs_mount,
        .vfs_start =            mfs_start,
        .vfs_unmount =          ffs_unmount,
index f248656..03240ff 100644 (file)
@@ -867,6 +867,7 @@ msdosfs_vptofh(struct vnode *vp, struct fid *fhp)
 }
 
 static struct vfsops msdosfs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            msdosfs_mount,
        .vfs_root =             msdosfs_root,
        .vfs_statfs =           msdosfs_statfs,
index 6d0f949..237470a 100644 (file)
@@ -127,6 +127,7 @@ static int  nfs_sync ( struct mount *mp, int waitfor);
  * nfs vfs operations.
  */
 static struct vfsops nfs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            nfs_mount,
        .vfs_unmount =          nfs_unmount,
        .vfs_root =             nfs_root,
index f89f072..2bc6b09 100644 (file)
@@ -797,6 +797,7 @@ ntfs_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
 }
 
 static struct vfsops ntfs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            ntfs_mount,
        .vfs_unmount =          ntfs_unmount,
        .vfs_root =             ntfs_root,
index 45ba32b..a09c313 100644 (file)
@@ -206,13 +206,11 @@ nullfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
         *
         * All NULLFS operations are MPSAFE, though it will be short-lived
         * if the underlying filesystem is not.
+        *
+        * NOTE: There is no syncer thread for nullfs (flagged in vfsops)
         */
        mp->mnt_kern_flag |= MNTK_NCALIASED | MNTK_ALL_MPSAFE;
 
-       /*
-        * And we don't need a syncer thread
-        */
-       vn_syncer_thr_stop(mp);
        return (0);
 fail2:
        nlookup_done(&nd);
@@ -410,6 +408,7 @@ nullfs_modifying(struct mount *mp)
 }
 
 static struct vfsops null_vfsops = {
+       .vfs_flags =            VFSOPSF_NOSYNCERTHR,
        .vfs_mount =            nullfs_mount,
        .vfs_unmount =          nullfs_unmount,
        .vfs_root =             nullfs_root,
index 3372680..4724749 100644 (file)
@@ -145,6 +145,7 @@ procfs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
 }
 
 static struct vfsops procfs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            procfs_mount,
        .vfs_unmount =          procfs_unmount,
        .vfs_root =             procfs_root,
index c24dc4f..593428d 100644 (file)
@@ -84,6 +84,7 @@ static int smbfs_init(struct vfsconf *vfsp);
 static int smbfs_uninit(struct vfsconf *vfsp);
 
 static struct vfsops smbfs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            smbfs_mount,
        .vfs_unmount =          smbfs_unmount,
        .vfs_root =             smbfs_root,
index c039b4c..f53b4ee 100644 (file)
@@ -590,6 +590,7 @@ tmpfs_checkexp(struct mount *mp, struct sockaddr *nam, int *exflagsp,
  */
 
 static struct vfsops tmpfs_vfsops = {
+       .vfs_flags =                    0,
        .vfs_mount =                    tmpfs_mount,
        .vfs_unmount =                  tmpfs_unmount,
        .vfs_root =                     tmpfs_root,
index f05e0e3..641c317 100644 (file)
@@ -112,6 +112,7 @@ static int udf_vptofh(struct vnode *, struct fid *);
 static int udf_find_partmaps(struct udf_mnt *, struct logvol_desc *);
 
 static struct vfsops udf_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            udf_mount,
        .vfs_unmount =          udf_unmount,
        .vfs_root =             udf_root,
index fd10d02..3042bfa 100644 (file)
@@ -69,6 +69,7 @@ static int    ffs_mount (struct mount *, char *, caddr_t, struct ucred *);
 static int     ffs_init (struct vfsconf *);
 
 static struct vfsops ufs_vfsops = {
+       .vfs_flags =            0,
        .vfs_mount =            ffs_mount,
        .vfs_unmount =          ffs_unmount,
        .vfs_root =             ufs_root,