PR kern/41147: race between nfsd and local rm
Note that the race also exists between 2 nfs client, one of them doing the rm. In ufs_ihashget(), vget() can return a vnode that has been vclean'ed because vget() can sleep. After vget returns, check that vp is still connected with ip, and that ip still points to the inode we want. This fix the NULL pointer dereference in ufs_fhtovp() I've been seeing on a NFS server. XXX I have no idea why using vput() instead of vlockmgr(vp->v_vnlock, LK_RELEASE); vrele(vp); does not work.
This commit is contained in:
parent
5a6dad0a4b
commit
7de71fb523
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ufs_ihash.c,v 1.26 2008/05/05 17:11:17 ad Exp $ */
|
||||
/* $NetBSD: ufs_ihash.c,v 1.27 2009/09/20 14:00:24 bouyer Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1991, 1993
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ufs_ihash.c,v 1.26 2008/05/05 17:11:17 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ufs_ihash.c,v 1.27 2009/09/20 14:00:24 bouyer Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -152,6 +152,15 @@ ufs_ihashget(dev_t dev, ino_t inum, int flags)
|
|||
mutex_exit(&ufs_ihash_lock);
|
||||
if (vget(vp, flags | LK_INTERLOCK))
|
||||
goto loop;
|
||||
if (VTOI(vp) != ip ||
|
||||
ip->i_number != inum || ip->i_dev != dev) {
|
||||
/* lost race against vclean() */
|
||||
if (vlockmgr(vp->v_vnlock, LK_RELEASE))
|
||||
printf("can't release lock\n");
|
||||
vrele(vp);
|
||||
vp = NULL;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
return (vp);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue