Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 12 Mar 2000 21:03:18 +0000 (GMT)
From:      iedowse@maths.tcd.ie
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   kern/17347: msdosfs_rename and 'vrele: negative ref count'
Message-ID:  <200003122103.aa08098@walton.maths.tcd.ie>

next in thread | raw e-mail | index | archive | help

>Number:         17347
>Category:       kern
>Synopsis:       msdosfs_rename and 'vrele: negative ref count'
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Mar 12 13:10:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Ian Dowse
>Release:        FreeBSD 3.4-STABLE i386
>Organization:
		School of Mathematics
		Trinity College Dublin
>Environment:

	FreeBSD -current or -stable.

>Description:

	Certain error contitions cause msdosfs_rename() to decrement the
	vnode reference count on 'fdvp' more times than it should.

	In particular, an attempt to replace a non-empty directory
	vrele()'s 'fdvp' twice instead of once.

>How-To-Repeat:

	In an msdosfs directory type:

		mkdir -p a/a/b
		mv a/a .

	(the second line may need to be repeated a few times)

>Fix:
	The following patch appears to correct the problem, but it should
	be checked over by some filesystem guru. The idea of the change
	is to keep exactly one reference to 'fdvp' at all times. This
	allows the error backout code to to the right thing.

--- msdosfs_vnops.c.orig	Sun Mar 12 20:32:47 2000
+++ msdosfs_vnops.c	Sun Mar 12 20:33:49 2000
@@ -1098,7 +1098,6 @@
 	VOP_UNLOCK(fvp, 0, p);
 	if (VTODE(fdvp)->de_StartCluster != VTODE(tdvp)->de_StartCluster)
 		newparent = 1;
-	vrele(fdvp);
 	if (doingdirectory && newparent) {
 		if (error)	/* write access check above */
 			goto bad;
@@ -1166,7 +1165,8 @@
 		panic("msdosfs_rename: lost from startdir");
 	if (!newparent)
 		VOP_UNLOCK(tdvp, 0, p);
-	(void) relookup(fdvp, &fvp, fcnp);
+	if (relookup(fdvp, &fvp, fcnp) == 0)
+		vrele(fdvp);
 	if (fvp == NULL) {
 		/*
 		 * From name has disappeared.


>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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