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: