Subject: kern/5272: hard link cannot be made on union filesystems.
To: None <gnats-bugs@gnats.netbsd.org>
From: MINOURA Makoto <minoura@kw.netlaputa.ne.jp>
List: netbsd-bugs
Date: 04/09/1998 23:02:37
>Number: 5272
>Category: kern
>Synopsis: hard link cannot be made on union filesystems.
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Apr 9 07:35:01 1998
>Last-Modified:
>Originator: MINOURA Makoto
>Organization:
MINOURA, Makoto <minoura@kw.netlaputa.ne.jp> or <minoura@kyogoku.com>
Nakahara-ku Kawasaki-Shi, JAPAN
>Release: NetBSD-current supped at Apr.8 16:18 GMT.
>Environment:
System: NetBSD daisy 1.3E NetBSD 1.3E (DAISY) #48: Sat Apr 4 13:59:12 JST 1998 root@daisy:/usr/src/sys/arch/i386/compile/DAISY i386
>Description:
There are two bug in union_link().
First one is at line 1152. un_un_uppervp is *always* NULLVP :-).
(something like typo)
Second, union_copyup returns a locked vnode, so it is
unlocked before relookup().
>How-To-Repeat:
# mkdir /tmp/lower /tmp/higher
# touch /tmp/lower/file1
# mount -t union /tmp/higher /tmp/lower
# cd /tmp/lower
# ln file1 file2
panic: kernel fault
>Fix:
*** /export/NetBSD-current/src/sys/miscfs/union/union_vnops.c Tue Mar 17 21:13:17 1998
--- /sys/miscfs/union/union_vnops.c Thu Apr 9 22:46:34 1998
***************
*** 1149,1155 ****
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
if (dun->un_uppervp == un->un_dirvp) {
dun->un_flags &= ~UN_ULOCK;
! VOP_UNLOCK(un->un_uppervp, 0);
}
error = union_copyup(un, 1, cnp->cn_cred, p);
if (dun->un_uppervp == un->un_dirvp) {
--- 1149,1155 ----
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
if (dun->un_uppervp == un->un_dirvp) {
dun->un_flags &= ~UN_ULOCK;
! VOP_UNLOCK(dun->un_uppervp, 0);
}
error = union_copyup(un, 1, cnp->cn_cred, p);
if (dun->un_uppervp == un->un_dirvp) {
***************
*** 1171,1176 ****
--- 1171,1177 ----
* and since LOCKPARENT is set returns
* the starting directory locked.
*/
+ VOP_UNLOCK(ap->a_dvp, 0);
error = relookup(ap->a_dvp, &vp, ap->a_cnp);
if (error) {
vrele(ap->a_dvp);
>Audit-Trail:
>Unformatted: