diff options
author | kib <kib@FreeBSD.org> | 2007-04-26 08:56:56 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2007-04-26 08:56:56 +0000 |
commit | 83b7f9371b55e9dc70942dc452b4b87d5b2315d9 (patch) | |
tree | 37d6327b4b01f08cc2ec1e40bb328f146d1a065e | |
parent | 2f0b14e001cb8efebc5b89f79d0c91e3cdbc0869 (diff) | |
download | FreeBSD-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.c | 4 |
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); |