diff options
-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 | 6 |
3 files changed, 16 insertions, 2 deletions
diff --git a/sys/fs/devfs/devfs.h b/sys/fs/devfs/devfs.h index 5f64a2672799..121d6eb6f0b5 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 *); +bool 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..5df21a3712d0 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); } +bool +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 5bd12708b0df..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); |