summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-04-26 08:56:56 +0000
committerkib <kib@FreeBSD.org>2007-04-26 08:56:56 +0000
commit83b7f9371b55e9dc70942dc452b4b87d5b2315d9 (patch)
tree37d6327b4b01f08cc2ec1e40bb328f146d1a065e
parent2f0b14e001cb8efebc5b89f79d0c91e3cdbc0869 (diff)
downloadFreeBSD-src-83b7f9371b55e9dc70942dc452b4b87d5b2315d9.zip
FreeBSD-src-83b7f9371b55e9dc70942dc452b4b87d5b2315d9.tar.gz
Allow the dounmount() to proceed even for doomed coveredvp.
In dounmount(), before or while vn_lock(coveredvp) is called, coveredvp vnode may be VI_DOOMED due to one of the following: - other thread finished unmount and vput()ed it, and vnode was chosen for recycling, while vn_lock() slept; - forced unmount of the coveredvp->v_mount fs. In the first case, next check for changed v_mountedhere or mnt_gen counter would be successfull. In the second case, the unmount shall be allowed. Submitted by: sobomax MFC after: 2 weeks
-rw-r--r--sys/kern/vfs_mount.c4
1 files changed, 1 insertions, 3 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 40fd361..e545a25 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1168,14 +1168,12 @@ dounmount(mp, flags, td)
mnt_gen_r = mp->mnt_gen;
VI_LOCK(coveredvp);
vholdl(coveredvp);
- error = vn_lock(coveredvp, LK_EXCLUSIVE | LK_INTERLOCK, td);
+ vn_lock(coveredvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_RETRY, td);
vdrop(coveredvp);
/*
* Check for mp being unmounted while waiting for the
* covered vnode lock.
*/
- if (error)
- return (error);
if (coveredvp->v_mountedhere != mp ||
coveredvp->v_mountedhere->mnt_gen != mnt_gen_r) {
VOP_UNLOCK(coveredvp, 0, td);
OpenPOWER on IntegriCloud