summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjeff <jeff@FreeBSD.org>2005-03-14 07:11:19 +0000
committerjeff <jeff@FreeBSD.org>2005-03-14 07:11:19 +0000
commita307ec6ef809153ac619d169f0bf6680db24e4ea (patch)
treecd2381096953823b903e035b7f9a09bfeb84cb00
parent466fb85e71ac2e01a727b9dbbfd530093479f4d2 (diff)
downloadFreeBSD-src-a307ec6ef809153ac619d169f0bf6680db24e4ea.zip
FreeBSD-src-a307ec6ef809153ac619d169f0bf6680db24e4ea.tar.gz
- Rework vget() so we drop the usecount in two failure cases that were
missed by my last commit. Sponsored by: Isilon Systems, Inc.
-rw-r--r--sys/kern/vfs_subr.c48
1 files changed, 24 insertions, 24 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index a5d92d1..94dee20 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1814,43 +1814,43 @@ vget(vp, flags, td)
* the VI_DOOMED flag is set.
*/
if (vp->v_iflag & VI_DOOMED && vp->v_vxthread != td &&
- (flags & LK_NOWAIT)) {
+ ((flags & LK_NOWAIT) || (flags & LK_TYPE_MASK) == 0)) {
VI_UNLOCK(vp);
return (EBUSY);
}
v_incr_usecount(vp, 1);
-
if (VSHOULDBUSY(vp))
vbusy(vp);
if ((flags & LK_TYPE_MASK) == 0) {
- if (vp->v_iflag & VI_DOOMED)
- error = ENOENT;
VI_UNLOCK(vp);
- return (error);
- }
- if ((error = vn_lock(vp, flags | LK_INTERLOCK, td)) != 0) {
- /*
- * must expand vrele here because we do not want
- * to call VOP_INACTIVE if the reference count
- * drops back to zero since it was never really
- * active. We must remove it from the free list
- * before sleeping so that multiple processes do
- * not try to recycle it.
- */
- VI_LOCK(vp);
- v_incr_usecount(vp, -1);
- if (VSHOULDFREE(vp))
- vfree(vp);
- else
- vlruvp(vp);
- VI_UNLOCK(vp);
- return (error);
+ return (0);
}
+ if ((error = vn_lock(vp, flags | LK_INTERLOCK, td)) != 0)
+ goto drop;
if (vp->v_iflag & VI_DOOMED && vp->v_vxthread != td) {
VOP_UNLOCK(vp, 0, td);
- return (ENOENT);
+ error = ENOENT;
+ goto drop;
}
return (0);
+
+drop:
+ /*
+ * must expand vrele here because we do not want
+ * to call VOP_INACTIVE if the reference count
+ * drops back to zero since it was never really
+ * active. We must remove it from the free list
+ * before sleeping so that multiple processes do
+ * not try to recycle it.
+ */
+ VI_LOCK(vp);
+ v_incr_usecount(vp, -1);
+ if (VSHOULDFREE(vp))
+ vfree(vp);
+ else
+ vlruvp(vp);
+ VI_UNLOCK(vp);
+ return (error);
}
/*
OpenPOWER on IntegriCloud