From 38b2c3b26ff71791f1be25e408220f04e61ea61f Mon Sep 17 00:00:00 2001 From: kib Date: Tue, 3 Oct 2006 10:47:04 +0000 Subject: 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 --- sys/kern/vfs_mount.c | 6 +++++- sys/sys/mount.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) 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); } diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 16ea687..e67de9c 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -145,6 +145,7 @@ struct vfsopt; struct mount { struct lock mnt_lock; /* mount structure lock */ struct mtx mnt_mtx; /* mount structure interlock */ + int mnt_gen; /* struct mount generation */ #define mnt_startzero mnt_list TAILQ_ENTRY(mount) mnt_list; /* (m) mount list */ struct vfsops *mnt_op; /* operations on fs */ -- cgit v1.1