From owner-freebsd-current Tue Mar 5 23:52:34 1996 Return-Path: owner-current Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id XAA03246 for current-outgoing; Tue, 5 Mar 1996 23:52:34 -0800 (PST) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by freefall.freebsd.org (8.7.3/8.7.3) with SMTP id XAA03221 for ; Tue, 5 Mar 1996 23:52:28 -0800 (PST) Received: (from bde@localhost) by godzilla.zeta.org.au (8.6.12/8.6.9) id SAA09666; Wed, 6 Mar 1996 18:50:15 +1100 Date: Wed, 6 Mar 1996 18:50:15 +1100 From: Bruce Evans Message-Id: <199603060750.SAA09666@godzilla.zeta.org.au> To: jhay@mikom.csir.co.za Subject: fixes for rename panic (round 1) Cc: freebsd-current@FreeBSD.ORG Sender: owner-current@FreeBSD.ORG Precedence: bulk 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);