diff options
author | kib <kib@FreeBSD.org> | 2009-04-10 10:22:44 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-04-10 10:22:44 +0000 |
commit | a5ecda6fd6358d3ff6a18998f98482335fb6c884 (patch) | |
tree | 1d4aba80f8d00165dcc019427b677a38db46a9e7 | |
parent | 81638d98846e99a6bfcf7398057a650533aa1390 (diff) | |
download | FreeBSD-src-a5ecda6fd6358d3ff6a18998f98482335fb6c884.zip FreeBSD-src-a5ecda6fd6358d3ff6a18998f98482335fb6c884.tar.gz |
Cache_lookup() for DOTDOT drops dvp vnode lock, allowing dvp to be reclaimed.
Check the condition and return ENOENT then.
In nfs_lookup(), respect ENOENT return from cache_lookup() when it is caused
by dvp reclaim.
Reported and tested by: pho
-rw-r--r-- | sys/kern/vfs_cache.c | 9 | ||||
-rw-r--r-- | sys/nfsclient/nfs_vnops.c | 2 |
2 files changed, 10 insertions, 1 deletions
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 49eccdd..6172f5b 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -554,8 +554,15 @@ success: else CACHE_RUNLOCK(); error = vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, cnp->cn_thread); - if (cnp->cn_flags & ISDOTDOT) + if (cnp->cn_flags & ISDOTDOT) { vn_lock(dvp, ltype | LK_RETRY); + if (dvp->v_iflag & VI_DOOMED) { + if (error == 0) + vput(*vpp); + *vpp = NULL; + return (ENOENT); + } + } if (error) { *vpp = NULL; goto retry; diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index d201258..b363429 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -978,6 +978,8 @@ nfs_lookup(struct vop_lookup_args *ap) vrele(newvp); *vpp = NULLVP; } else if (error == ENOENT) { + if (dvp->v_iflag & VI_DOOMED) + return (ENOENT); /* * We only accept a negative hit in the cache if the * modification time of the parent directory matches |