mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-11-29 17:32:43 +00:00
Quick-hack to avoid `lock against myself' panic. It is not the real
fix! The ufs_link() assumes that vnode is not unlocked and tries to lock it in certain case. Because union_link calls VOP_LINK after locking vnode, vn_lock in ufs_link causes above panic. Currently, I don't know the real fix for a locking violation in union_link, but I think it is important to avoid panic. A vnode is unlocked before calling VOP_LINK and is locked after it if the vnode is not union fs. Even though panic went away, the process that access the union fs in which link was made will hang-up. Hang-up can be easily reproduced by following operation: mount -t union a b cd b ln foo bar ls
This commit is contained in:
parent
666a6cbbb1
commit
9095719e2b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=24963
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)union_vnops.c 8.32 (Berkeley) 6/23/95
|
||||
* $Id: union_vnops.c,v 1.22 1997/04/13 13:12:12 kato Exp $
|
||||
* $Id: union_vnops.c,v 1.23 1997/04/14 05:13:55 kato Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -1058,6 +1058,7 @@ union_link(ap)
|
||||
struct union_node *un;
|
||||
struct vnode *vp;
|
||||
struct vnode *tdvp;
|
||||
int isvnunlocked = 0;
|
||||
|
||||
un = VTOUNION(ap->a_tdvp);
|
||||
|
||||
@ -1096,7 +1097,19 @@ union_link(ap)
|
||||
un->un_flags |= UN_KLOCK;
|
||||
vput(ap->a_tdvp);
|
||||
|
||||
return (VOP_LINK(vp, tdvp, cnp));
|
||||
/*
|
||||
* XXX -- This is a quick-hack to avoid panic. Problem still remains!
|
||||
* The process which access the union filesystem will be hang-up after
|
||||
* making link in the union fs.
|
||||
*/
|
||||
if (VOP_ISLOCKED(tdvp) && (tdvp->v_op != union_vnodeop_p)) {
|
||||
isvnunlocked = 1;
|
||||
VOP_UNLOCK(tdvp, 0, p);
|
||||
}
|
||||
error = VOP_LINK(vp, tdvp, cnp);
|
||||
if (isvnunlocked)
|
||||
vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -35,7 +35,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)union_vnops.c 8.32 (Berkeley) 6/23/95
|
||||
* $Id: union_vnops.c,v 1.22 1997/04/13 13:12:12 kato Exp $
|
||||
* $Id: union_vnops.c,v 1.23 1997/04/14 05:13:55 kato Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -1058,6 +1058,7 @@ union_link(ap)
|
||||
struct union_node *un;
|
||||
struct vnode *vp;
|
||||
struct vnode *tdvp;
|
||||
int isvnunlocked = 0;
|
||||
|
||||
un = VTOUNION(ap->a_tdvp);
|
||||
|
||||
@ -1096,7 +1097,19 @@ union_link(ap)
|
||||
un->un_flags |= UN_KLOCK;
|
||||
vput(ap->a_tdvp);
|
||||
|
||||
return (VOP_LINK(vp, tdvp, cnp));
|
||||
/*
|
||||
* XXX -- This is a quick-hack to avoid panic. Problem still remains!
|
||||
* The process which access the union filesystem will be hang-up after
|
||||
* making link in the union fs.
|
||||
*/
|
||||
if (VOP_ISLOCKED(tdvp) && (tdvp->v_op != union_vnodeop_p)) {
|
||||
isvnunlocked = 1;
|
||||
VOP_UNLOCK(tdvp, 0, p);
|
||||
}
|
||||
error = VOP_LINK(vp, tdvp, cnp);
|
||||
if (isvnunlocked)
|
||||
vn_lock(tdvp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user