Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Mar 1996 18:50:15 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        jhay@mikom.csir.co.za
Cc:        freebsd-current@FreeBSD.ORG
Subject:   fixes for rename panic (round 1)
Message-ID:  <199603060750.SAA09666@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
The main cause of the panic is broken reference counting in certain
error cases.  relookup() calls vput(fdvp) when it fails, so callers
must increment the reference count before calling relookup() and
decrement it if relookup() doesn't fail.  Not doing this caused
v_usecount for the test directory to eventually become negative.

relookup() fails when the `from' file went away.  Different bad things
happen if it went away and came back.  Then relookup doesn't fail, but
the wrong file or directory is removed.  If a regular file went away
and came back as a directory, then the file system is corrupted.

Bruce

*** ufs_vnops.c~	Sat Jan 20 06:57:41 1996
--- ufs_vnops.c	Wed Mar  6 17:23:23 1996
***************
*** 866,870 ****
  			panic("ufs_rename: lost from startdir");
  		fcnp->cn_nameiop = DELETE;
! 		(void) relookup(fdvp, &fvp, fcnp);
  		return (VOP_REMOVE(fdvp, fvp, fcnp));
  	}
--- 904,911 ----
  			panic("ufs_rename: lost from startdir");
  		fcnp->cn_nameiop = DELETE;
! 		VREF(fdvp);
! 		error = relookup(fdvp, &fvp, fcnp);
! 		if (error == 0)
! 			vrele(fdvp);
  		return (VOP_REMOVE(fdvp, fvp, fcnp));
  	}
***************
*** 953,958 ****
--- 1005,1012 ----
  			panic("ufs_rename: lost to startdir");
  		error = relookup(tdvp, &tvp, tcnp);
+ 		VREF(tdvp);
  		if (error)
  			goto out;
+ 		vrele(tdvp);
  		dp = VTOI(tdvp);
  		xp = NULL;
***************
*** 1101,1105 ****
  	if ((fcnp->cn_flags & SAVESTART) == 0)
  		panic("ufs_rename: lost from startdir");
! 	(void) relookup(fdvp, &fvp, fcnp);
  	if (fvp != NULL) {
  		xp = VTOI(fvp);
--- 1155,1162 ----
  	if ((fcnp->cn_flags & SAVESTART) == 0)
  		panic("ufs_rename: lost from startdir");
! 	VREF(fdvp);
! 	error = relookup(fdvp, &fvp, fcnp);
! 	if (error == 0)
! 		vrele(fdvp);
  	if (fvp != NULL) {
  		xp = VTOI(fvp);



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