summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_mount.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2006-10-03 10:47:04 +0000
committerkib <kib@FreeBSD.org>2006-10-03 10:47:04 +0000
commit38b2c3b26ff71791f1be25e408220f04e61ea61f (patch)
treef208ea8fc9e93064439efb11864fcf850ffb9750 /sys/kern/vfs_mount.c
parentb2a6f9f628bc2678bab67e0a00ff7be2dcce38da (diff)
downloadFreeBSD-src-38b2c3b26ff71791f1be25e408220f04e61ea61f.zip
FreeBSD-src-38b2c3b26ff71791f1be25e408220f04e61ea61f.tar.gz
Fix the remaining race in the revs. 1.232, 1,233 that could occur during
unmount when mp structure is reused while waiting for coveredvp lock. Introduce struct mount generation count, increment it on each reuse and compare the generations before and after obtaining the coveredvp lock. Reviewed by: tegge, pjd Approved by: pjd (mentor) MFC after: 2 weeks
Diffstat (limited to 'sys/kern/vfs_mount.c')
-rw-r--r--sys/kern/vfs_mount.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index c89a5fa..0598905 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -475,6 +475,7 @@ vfs_mount_alloc(struct vnode *vp, struct vfsconf *vfsp,
MNT_ILOCK(mp);
mp->mnt_flag |= vfsp->vfc_flags & MNT_VISFLAGMASK;
MNT_IUNLOCK(mp);
+ mp->mnt_gen++;
strlcpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
mp->mnt_vnodecovered = vp;
mp->mnt_cred = crdup(td->td_ucred);
@@ -1148,10 +1149,12 @@ dounmount(mp, flags, td)
struct vnode *coveredvp, *fsrootvp;
int error;
int async_flag;
+ int mnt_gen_r;
mtx_assert(&Giant, MA_OWNED);
if ((coveredvp = mp->mnt_vnodecovered) != NULL) {
+ mnt_gen_r = mp->mnt_gen;
VI_LOCK(coveredvp);
vholdl(coveredvp);
error = vn_lock(coveredvp, LK_EXCLUSIVE | LK_INTERLOCK, td);
@@ -1162,7 +1165,8 @@ dounmount(mp, flags, td)
*/
if (error)
return (error);
- if (coveredvp->v_mountedhere != mp) {
+ if (coveredvp->v_mountedhere != mp ||
+ coveredvp->v_mountedhere->mnt_gen != mnt_gen_r) {
VOP_UNLOCK(coveredvp, 0, td);
return (EBUSY);
}
OpenPOWER on IntegriCloud