diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-08-10 16:58:05 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-08-10 16:58:05 +0000 |
commit | 8460d7540b226f37a2f58b9f652e34e2fb6df3a7 (patch) | |
tree | e19dfd882b1142baacd65f31a263846ff3c4e360 /sys/fs | |
parent | a3030502fbf3e24c62ec77360e0ec63ef6dcf673 (diff) | |
parent | a08d04f4e47535b9db81062d020d10b10e9a4e9d (diff) | |
download | src-8460d7540b226f37a2f58b9f652e34e2fb6df3a7.tar.gz src-8460d7540b226f37a2f58b9f652e34e2fb6df3a7.zip |
Merge ^/head r364051 through r364081.
Notes
Notes:
svn path=/projects/clang1100-import/; revision=364082
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/devfs/devfs.h | 1 | ||||
-rw-r--r-- | sys/fs/devfs/devfs_devs.c | 11 | ||||
-rw-r--r-- | sys/fs/devfs/devfs_vnops.c | 27 | ||||
-rw-r--r-- | sys/fs/nullfs/null_vnops.c | 16 | ||||
-rw-r--r-- | sys/fs/tmpfs/tmpfs_vfsops.c | 9 |
5 files changed, 53 insertions, 11 deletions
diff --git a/sys/fs/devfs/devfs.h b/sys/fs/devfs/devfs.h index 5f64a2672799..673d94999169 100644 --- a/sys/fs/devfs/devfs.h +++ b/sys/fs/devfs/devfs.h @@ -192,6 +192,7 @@ char *devfs_fqpn(char *, struct devfs_mount *, struct devfs_dirent *, struct componentname *); void devfs_delete(struct devfs_mount *, struct devfs_dirent *, int); void devfs_dirent_free(struct devfs_dirent *); +int devfs_populate_needed(struct devfs_mount *dm); void devfs_populate(struct devfs_mount *); void devfs_cleanup(struct devfs_mount *); void devfs_unmount_final(struct devfs_mount *); diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index 417e13e2757a..3929cc8b1e80 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -659,6 +659,13 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup) return (0); } +int +devfs_populate_needed(struct devfs_mount *dm) +{ + + return (dm->dm_generation != devfs_generation); +} + /* * The caller needs to hold the dm for the duration of the call. */ @@ -668,9 +675,9 @@ devfs_populate(struct devfs_mount *dm) unsigned gen; sx_assert(&dm->dm_lock, SX_XLOCKED); - gen = devfs_generation; - if (dm->dm_generation == gen) + if (!devfs_populate_needed(dm)) return; + gen = devfs_generation; while (devfs_populate_loop(dm, 0)) continue; dm->dm_generation = gen; diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 0605fad13cf5..f9e29e0b1c74 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -235,6 +235,11 @@ devfs_populate_vp(struct vnode *vp) ASSERT_VOP_LOCKED(vp, "devfs_populate_vp"); dmp = VFSTODEVFS(vp->v_mount); + if (!devfs_populate_needed(dmp)) { + sx_xlock(&dmp->dm_lock); + goto out_nopopulate; + } + locked = VOP_ISLOCKED(vp); sx_xlock(&dmp->dm_lock); @@ -252,6 +257,7 @@ devfs_populate_vp(struct vnode *vp) devfs_unmount_final(dmp); return (ERESTART); } +out_nopopulate: if (VN_IS_DOOMED(vp)) { sx_xunlock(&dmp->dm_lock); return (ERESTART); @@ -420,6 +426,7 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, int lockmode, struct cdev *dev; struct devfs_mount *dmp; struct cdevsw *dsw; + enum vgetstate vs; dmp = VFSTODEVFS(mp); if (de->de_flags & DE_DOOMED) { @@ -432,10 +439,10 @@ loop: mtx_lock(&devfs_de_interlock); vp = de->de_vnode; if (vp != NULL) { - VI_LOCK(vp); + vs = vget_prep(vp); mtx_unlock(&devfs_de_interlock); sx_xunlock(&dmp->dm_lock); - vget(vp, lockmode | LK_INTERLOCK | LK_RETRY, curthread); + vget_finish(vp, lockmode | LK_RETRY, vs); sx_xlock(&dmp->dm_lock); if (devfs_allocv_drop_refs(0, dmp, de)) { vput(vp); @@ -1492,13 +1499,14 @@ devfs_revoke(struct vop_revoke_args *ap) struct cdev *dev; struct cdev_priv *cdp; struct devfs_dirent *de; + enum vgetstate vs; u_int i; KASSERT((ap->a_flags & REVOKEALL) != 0, ("devfs_revoke !REVOKEALL")); dev = vp->v_rdev; cdp = cdev2priv(dev); - + dev_lock(); cdp->cdp_inuse++; dev_unlock(); @@ -1521,17 +1529,16 @@ devfs_revoke(struct vop_revoke_args *ap) vp2 = de->de_vnode; if (vp2 != NULL) { dev_unlock(); - VI_LOCK(vp2); + vs = vget_prep(vp2); mtx_unlock(&devfs_de_interlock); - if (vget(vp2, LK_EXCLUSIVE | LK_INTERLOCK, - curthread)) + if (vget_finish(vp2, LK_EXCLUSIVE, vs) != 0) goto loop; vhold(vp2); vgone(vp2); vdrop(vp2); vput(vp2); break; - } + } } if (vp2 != NULL) { continue; @@ -1927,6 +1934,9 @@ static struct vop_vector devfs_vnodeops = { #endif .vop_symlink = devfs_symlink, .vop_vptocnp = devfs_vptocnp, + .vop_lock1 = vop_lock, + .vop_unlock = vop_unlock, + .vop_islocked = vop_islocked, }; VFS_VOP_VECTOR_REGISTER(devfs_vnodeops); @@ -1965,6 +1975,9 @@ static struct vop_vector devfs_specops = { .vop_symlink = VOP_PANIC, .vop_vptocnp = devfs_vptocnp, .vop_write = dead_write, + .vop_lock1 = vop_lock, + .vop_unlock = vop_unlock, + .vop_islocked = vop_islocked, }; VFS_VOP_VECTOR_REGISTER(devfs_specops); diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c index 4dd555a18dbe..60fd2a2c3660 100644 --- a/sys/fs/nullfs/null_vnops.c +++ b/sys/fs/nullfs/null_vnops.c @@ -182,6 +182,7 @@ #include <sys/namei.h> #include <sys/sysctl.h> #include <sys/vnode.h> +#include <sys/stat.h> #include <fs/nullfs/null.h> @@ -484,9 +485,21 @@ null_setattr(struct vop_setattr_args *ap) } /* - * We handle getattr only to change the fsid. + * We handle stat and getattr only to change the fsid. */ static int +null_stat(struct vop_stat_args *ap) +{ + int error; + + if ((error = null_bypass((struct vop_generic_args *)ap)) != 0) + return (error); + + ap->a_sb->st_dev = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0]; + return (0); +} + +static int null_getattr(struct vop_getattr_args *ap) { int error; @@ -918,6 +931,7 @@ struct vop_vector null_vnodeops = { .vop_accessx = null_accessx, .vop_advlockpurge = vop_stdadvlockpurge, .vop_bmap = VOP_EOPNOTSUPP, + .vop_stat = null_stat, .vop_getattr = null_getattr, .vop_getwritemount = null_getwritemount, .vop_inactive = null_inactive, diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index fee923e61328..bb2ae154af93 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -372,6 +372,13 @@ tmpfs_mount(struct mount *mp) } tmp->tm_nomtime = vfs_getopt(mp->mnt_optnew, "nomtime", NULL, 0) == 0; + MNT_ILOCK(mp); + if ((mp->mnt_flag & MNT_UNION) == 0) { + mp->mnt_kern_flag |= MNTK_FPLOOKUP; + } else { + mp->mnt_kern_flag &= ~MNTK_FPLOOKUP; + } + MNT_IUNLOCK(mp); return (0); } @@ -462,7 +469,7 @@ tmpfs_mount(struct mount *mp) mp->mnt_flag |= MNT_LOCAL; mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED | MNTK_TEXT_REFS | MNTK_NOMSYNC; - if (!nonc) + if (!nonc && (mp->mnt_flag & MNT_UNION) == 0) mp->mnt_kern_flag |= MNTK_FPLOOKUP; MNT_IUNLOCK(mp); |