summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2005-12-29 22:52:09 +0000
committerpjd <pjd@FreeBSD.org>2005-12-29 22:52:09 +0000
commit2cf01da41229a069a9e67de3d163a840b308d5da (patch)
treebd60923f0c4067d2de8522bd27858857ca48de5b
parentb7ab8cfc237720c0f9cf4674ef393acbf70a65bf (diff)
downloadFreeBSD-src-2cf01da41229a069a9e67de3d163a840b308d5da.zip
FreeBSD-src-2cf01da41229a069a9e67de3d163a840b308d5da.tar.gz
Print a warning when we miss vinactive() call, because of race in vget().
The race is very real, but conditions needed for triggering it are rather hard to meet now. When gjournal will be committed (where it is quite easy to trigger) we need to fix it. For now, verify if it is really hard to trigger. Discussed with: kan
-rw-r--r--sys/kern/vfs_subr.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 6f5f375..a57b2ba 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -1928,6 +1928,7 @@ vget(vp, flags, td)
{
int oweinact;
int oldflags;
+ int usecount;
int error;
error = 0;
@@ -1949,6 +1950,7 @@ vget(vp, flags, td)
flags |= LK_EXCLUSIVE;
oweinact = 1;
}
+ usecount = vp->v_usecount;
v_incr_usecount(vp);
if ((error = vn_lock(vp, flags | LK_INTERLOCK, td)) != 0) {
VI_LOCK(vp);
@@ -1959,6 +1961,24 @@ vget(vp, flags, td)
* active.
*/
v_decr_usecount(vp);
+ /*
+ * Print warning when race below occur:
+ *
+ * thread1 thread2
+ * ------- -------
+ * v_usecount=0
+ * vref(vp) v_usecount=1
+ * vget(vp)
+ * v_incr_usecount(vp) v_usecount=2
+ * vn_lock(vp)
+ * vrele(vp) v_usecount=1
+ * v_decr_usecount(vp) v_usecount=0
+ *
+ * In such situation VOP_INACTIVE() will not be called for
+ * the vnode vp.
+ */
+ if (usecount > 0 && vp->v_usecount == 0)
+ printf("vinactive() won't be called for vp=%p\n", vp);
return (error);
}
if (vp->v_iflag & VI_DOOMED && (flags & LK_RETRY) == 0)
OpenPOWER on IntegriCloud