aboutsummaryrefslogtreecommitdiff
path: root/sys/fs
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-08-10 16:58:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-08-10 16:58:05 +0000
commit8460d7540b226f37a2f58b9f652e34e2fb6df3a7 (patch)
treee19dfd882b1142baacd65f31a263846ff3c4e360 /sys/fs
parenta3030502fbf3e24c62ec77360e0ec63ef6dcf673 (diff)
parenta08d04f4e47535b9db81062d020d10b10e9a4e9d (diff)
downloadsrc-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.h1
-rw-r--r--sys/fs/devfs/devfs_devs.c11
-rw-r--r--sys/fs/devfs/devfs_vnops.c27
-rw-r--r--sys/fs/nullfs/null_vnops.c16
-rw-r--r--sys/fs/tmpfs/tmpfs_vfsops.c9
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);