Fix locking disorder in ntfs_vgetex(), which resulted in deadlock
under heavy vnode usage - vget() must be called with unlocked ntnode! Actually check the vget() return value and DTRT if it fails (i.e. when the vnode has been recycled for other use).
This commit is contained in:
parent
ec6b53c217
commit
a0e44b481b
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ntfs_vfsops.c,v 1.35 2001/05/15 22:38:40 jdolecek Exp $ */
|
||||
/* $NetBSD: ntfs_vfsops.c,v 1.36 2001/06/19 22:14:14 jdolecek Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 Semen Ustimenko
|
||||
|
@ -954,12 +954,22 @@ ntfs_vgetex(
|
|||
fp->f_flag |= FN_VALID;
|
||||
}
|
||||
|
||||
if (FTOV(fp)) {
|
||||
VGET(FTOV(fp), lkflags, p);
|
||||
*vpp = FTOV(fp);
|
||||
/*
|
||||
* We may be calling vget() now. To avoid potential deadlock, we need
|
||||
* to release ntnode lock, since due to locking order vnode
|
||||
* lock has to be acquired first.
|
||||
* ntfs_fget() bumped ntnode usecount, so ntnode won't be recycled
|
||||
* prematurely.
|
||||
*/
|
||||
ntfs_ntput(ip);
|
||||
|
||||
if (FTOV(fp)) {
|
||||
/* vget() returns error if the vnode has been recycled */
|
||||
if (VGET(FTOV(fp), lkflags, p) == 0) {
|
||||
*vpp = FTOV(fp);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
error = getnewvnode(VT_NTFS, ntmp->ntm_mountp, ntfs_vnodeop_p, &vp);
|
||||
if(error) {
|
||||
|
@ -979,8 +989,6 @@ ntfs_vgetex(
|
|||
if (ino == NTFS_ROOTINO)
|
||||
vp->v_flag |= VROOT;
|
||||
|
||||
ntfs_ntput(ip);
|
||||
|
||||
if (lkflags & LK_TYPE_MASK) {
|
||||
error = VN_LOCK(vp, lkflags, p);
|
||||
if (error) {
|
||||
|
|
Loading…
Reference in New Issue