Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 May 2002 03:06:57 +0700 (NOVST)
From:      "Semen A. Ustimenko" <semenu@FreeBSD.org>
To:        Boris Popov <bp@butya.kz>
Cc:        freebsd-fs@FreeBSD.org, "Flood, Jim" <Jim.Flood@acirro.com>
Subject:   Re: NULLFS-related possible deadlock + fix proposal
Message-ID:  <20020516023242.L1992-200000@def.the.net>
In-Reply-To: <Pine.BSF.4.21.0205131728290.16895-100000@lion.butya.kz>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
Hi!

On Mon, 13 May 2002, Boris Popov wrote:

> On Sat, 11 May 2002, Semen A. Ustimenko wrote:
>
> > DEADLOCK...
>
> 	Indeed, weird situation. Nice analysis, btw :)
>
It would be weird, if it didn't happen in practice :)
Thanks are going to Jim, not me...

If you like, i can provide a small patch to help you simulate the problem,
but it's kind of hack as NULLFS looks seriously broken in -current.

> > Make vn_lock() in vrele() lock vnode only LK_THISLAYER. Obviously, the
> > NULLFS and other stacking FSes will have to deal with this in their
> > VOP_INACTIVE() handlers. This changes won't touch real FSes as they ignore
> > the LK_THISLAYER, don't they?
>
> 	Yes, you're correct in that LK_THISLAYER currently used only by
> "stacked" filesystem(s) and it used exactly for such situations to avoid
> deadlocks.  The proposed solution may even work without any additional
> code because null_inactive() performs its own management on the lower
> vnode locking.
>
Looks like we can't do this that easily, because VOP_INACTIVE is called
from different places. Most noticeable from vput(), and it's obvious that
vput() caller is responsible for vnode lock...

Any ideas?

BYe!

[-- Attachment #2 --]
Index: null_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/nullfs/null_vnops.c,v
retrieving revision 1.51
diff -c -r1.51 null_vnops.c
*** null_vnops.c	18 Mar 2002 05:39:04 -0000	1.51
--- null_vnops.c	15 May 2002 19:41:26 -0000
***************
*** 405,410 ****
--- 405,425 ----
  				*ap->a_vpp = vp;
  		}
  	}
+ 
+ 	printf("null_lookup %*s error %d\n", (int)cnp->cn_namelen, cnp->cn_nameptr, error);
+ 	if (error == 0 &&
+ 	    cnp->cn_namelen == 7 && !strncmp("foofile", cnp->cn_nameptr, 7)) {
+ 		int i;
+ 
+ 		printf("Delay...");
+ 		for (i=5; i; i--) {
+ 			printf(" %d", i);
+ 			tsleep(cnp, PPAUSE, "nullbug", hz);
+ 		}
+ 		printf("\n");
+ 	} else
+ 		printf("No delay\n");
+ 
  	return (error);
  }
  
***************
*** 712,717 ****
--- 727,734 ----
  {
  	struct vnode *vp = ap->a_vp;
  
+ 	VOP_UNLOCK(vp, 0, ap->a_td);
+ 
  	/*
  	 * If this is the last reference, then free up the vnode
  	 * so as not to tie up the lower vnodes.
***************
*** 742,759 ****
  	LIST_REMOVE(xp, null_hash);
  	lockmgr(&null_hashlock, LK_RELEASE, NULL, td);
  
- 	xp->null_lowervp = NULLVP;
- 	if (vp->v_vnlock != NULL) {
- 		vp->v_vnlock = &vp->v_lock;  /* we no longer share the lock */
- 	} else
- 		VOP_UNLOCK(vp, LK_THISLAYER, td);
- 
  	/*
  	 * Now it is safe to drop references to the lower vnode.
  	 * VOP_INACTIVE() will be called by vrele() if necessary.
  	 */
! 	vput(lowervp);
! 	vrele (lowervp);
  
  	vdata = vp->v_data;
  	vp->v_data = NULL;
--- 759,770 ----
  	LIST_REMOVE(xp, null_hash);
  	lockmgr(&null_hashlock, LK_RELEASE, NULL, td);
  
  	/*
  	 * Now it is safe to drop references to the lower vnode.
  	 * VOP_INACTIVE() will be called by vrele() if necessary.
  	 */
! 	vrele(lowervp);
! 	vrele(lowervp);
  
  	vdata = vp->v_data;
  	vp->v_data = NULL;
home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020516023242.L1992-200000>