Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 7 Aug 1998 12:09:03 -0400 (EDT)
From:      Luoqi Chen <luoqi@watermarkgroup.com>
To:        julian@whistle.com, kkennawa@physics.adelaide.edu.au
Cc:        current@FreeBSD.ORG
Subject:   Re: Softupdates panic
Message-ID:  <199808071609.MAA22564@lor.watermarkgroup.com>

next in thread | raw e-mail | index | archive | help
> Well, here's the problem simplified:
> 
> cd /tmp (assuming mounted soft-updates)
> mkdir d1
> mkdir d1/d2
> mkdir d2
> mv d2 d1
> rmdir d1/d2
> rmdir d1
> [system will panic in 15 seconds at 'sync' of that data.]
> 
> fix to follow. (and checked in I guess)
> 
> julian
> 
I looked at the problem and figured out what went wrong. During the rename
step (mv d2 d1), the target directory d1/d2 is deleted and a dirrem
dependency is generated. Normally, a dirrem dependency would decrease
the parent's link count by 1 and subdirectory's link count by 2. But for
this particular dirrem, we don't want to decrement the parent's link count,
otherwise we would the panic above. The solution would be mark this dirrem
as such, and don't decrement the parent's link count when it's handled.
Attached is a fix.

-lq

Index: ffs_softdep.c
===================================================================
RCS file: /fun/cvs/src/contrib/sys/softupdates/ffs_softdep.c,v
retrieving revision 1.12
diff -u -r1.12 ffs_softdep.c
--- ffs_softdep.c	1998/06/12 21:21:26	1.12
+++ ffs_softdep.c	1998/08/07 15:37:57
@@ -2436,6 +2436,7 @@
 	 * Allocate a new dirrem and ACQUIRE_LOCK.
 	 */
 	dirrem = newdirrem(bp, dp, ip, isrmdir);
+	dirrem->dm_state |= DIRCHG;
 	pagedep = dirrem->dm_pagedep;
 
 	/*
@@ -2546,6 +2547,15 @@
 	ip->i_flag |= IN_CHANGE;
 	if ((error = UFS_TRUNCATE(vp, (off_t)0, 0, p->p_ucred, p)) != 0)
 		softdep_error("handle_workitem_remove: truncate", error);
+	/*
+	 * Target directory deletion during a directory rename. The
+	 * parent directory's link count doesn't need to be decremented.
+	 */
+	if (dirrem->dm_state & DIRCHG) {
+		vput(vp);
+		WORKITEM_FREE(dirrem, D_DIRREM);
+		return;
+	}
 	ACQUIRE_LOCK(&lk);
 	(void) inodedep_lookup(ip->i_fs, dirrem->dm_oldinum, DEPALLOC,
 	    &inodedep);

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



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