Bug about devfs?
Kohji Okuno
okuno.kohji at jp.panasonic.com
Tue Jul 12 10:31:26 UTC 2011
Hello,
I think that devfs has a problem.
I encountered the problem that open("/dev/AAA") returned ENOENT.
Of course, /dev/AAA exists.
ENOENT was created by the point(***) in devfs_allocv().
I think that the race condition had occurred between process A and
vnlru kernel thread.
Please check the following.
If vnlru set VI_DOOMED to vp->v_iflag but vnlru didn't still execute
VOP_RECLAIM(), process A cat get valid vp from de->de_vnode.
But, vget() will return ENOENT, because vp->v_iflag has VI_DOOMED.
When I set the break point to (***), I checked that de->de_vnode and
vp->v_data were NULL.
process A: vnlru:
devfs_allocv() {
vgonel(vp) {
... ...
vp->v_iflag |= VI_DOOMED;
mtx_lock(&devfs_de_interlock); ...
vp = de->de_vnode;
if (vp != NULL) { VI_UNLOCK(vp);
_____________/ ...
VI_LOCK(vp); ____________/ if (VOP_RECLAIM(vp, td))
mtx_unlock(&devfs_de_interlock); ...
... \ devfs_reclaim(ap) {
error = vget(vp,...); \
... \______ mtx_lock(&devfs_de_interlock);
if (devfs_allocv_drop_refs(...)) { de = vp->v_data;
... if (de != NULL) {
} de->de_vnode = NULL;
else if (error) { vp->v_data = NULL;
... }
rturn (error); (***) mtx_unlock(&devfs_de_interlock);
} ...
}
I think that devfs_allocv() should be fixed as below.
How do you think?
devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp)
{
int error;
struct vnode *vp;
struct cdev *dev;
struct devfs_mount *dmp;
dmp = VFSTODEVFS(mp);
+#if 1
+ retry:
+#endif
if (de->de_flags & DE_DOOMED) {
...
mtx_lock(&devfs_de_interlock);
vp = de->de_vnode;
if (vp != NULL) {
VI_LOCK(vp);
mtx_unlock(&devfs_de_interlock);
sx_xunlock(&dmp->dm_lock);
error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread);
sx_xlock(&dmp->dm_lock);
if (devfs_allocv_drop_refs(0, dmp, de)) {
if (error == 0)
vput(vp);
return (ENOENT);
}
else if (error) {
+#if 1
+ if (error == ENOENT)
+ goto retry;
+#endif
sx_xunlock(&dmp->dm_lock);
return (error);
}
Thanks,
Kohji Okuno.
More information about the freebsd-current
mailing list