diff options
author | kib <kib@FreeBSD.org> | 2016-11-27 09:10:33 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-11-27 09:10:33 +0000 |
commit | d6471013890dc459dd941fa7871c1c0893df21e9 (patch) | |
tree | 984af61cd17ae369bf7736ecb5c60112edb90148 /sys/ufs | |
parent | 593ac3706b39851cbc3bd96af1f392264c03be3c (diff) | |
download | FreeBSD-src-d6471013890dc459dd941fa7871c1c0893df21e9.zip FreeBSD-src-d6471013890dc459dd941fa7871c1c0893df21e9.tar.gz |
MFC r308618:
Provide simple mutual exclusion between mount point update and unmount.
In the update path in ffs_mount(), drop vfs_busy() reference around namei().
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ffs/ffs_vfsops.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 47137ac..3760e8f 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -147,7 +147,7 @@ ffs_mount(struct mount *mp) struct ufsmount *ump = NULL; struct fs *fs; pid_t fsckpid = 0; - int error, flags; + int error, error1, flags; uint64_t mntorflags; accmode_t accmode; struct nameidata ndp; @@ -453,6 +453,11 @@ ffs_mount(struct mount *mp) */ if (mp->mnt_flag & MNT_SNAPSHOT) return (ffs_snapshot(mp, fspec)); + + /* + * Must not call namei() while owning busy ref. + */ + vfs_unbusy(mp); } /* @@ -460,7 +465,18 @@ ffs_mount(struct mount *mp) * and verify that it refers to a sensible disk device. */ NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td); - if ((error = namei(&ndp)) != 0) + error = namei(&ndp); + if ((mp->mnt_flag & MNT_UPDATE) != 0) { + /* + * Unmount does not start if MNT_UPDATE is set. Mount + * update busies mp before setting MNT_UPDATE. We + * must be able to retain our busy ref succesfully, + * without sleep. + */ + error1 = vfs_busy(mp, MBF_NOWAIT); + MPASS(error1 == 0); + } + if (error != 0) return (error); NDFREE(&ndp, NDF_ONLY_PNBUF); devvp = ndp.ni_vp; |