Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Dec 2010 10:52:07 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r216818 - in head/sys/ufs: ffs ufs
Message-ID:  <201012301052.oBUAq7SH037458@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Dec 30 10:52:07 2010
New Revision: 216818
URL: http://svn.freebsd.org/changeset/base/216818

Log:
  Handle missing jremrefs when a directory is renamed overtop of
  another, deleting it.  If the directory is removed, UFS always need to
  remove the .. ref, even if the ultimate ref on the parent would not
  change. The new directory must have a new journal entry for that ref.
  Otherwise journal processing would not properly account for the
  parent's reference since it will belong to a removed directory entry.
  
  Change ufs_rename()'s dotdot rename section to always
  setup_dotdot_link(). In the tip != NULL case SUJ needs the newref dependency
  allocated via setup_dotdot_link().
  
  Stop setting isrmdir to 2 for newdirrem() in softdep_setup_remove().
  Remove the isdirrem > 1 checks from newdirrem().
  
  Reported by:	many
  Submitted by:	jeff
  Tested by:	pho

Modified:
  head/sys/ufs/ffs/ffs_softdep.c
  head/sys/ufs/ufs/ufs_vnops.c

Modified: head/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- head/sys/ufs/ffs/ffs_softdep.c	Thu Dec 30 10:41:17 2010	(r216817)
+++ head/sys/ufs/ffs/ffs_softdep.c	Thu Dec 30 10:52:07 2010	(r216818)
@@ -6918,7 +6918,7 @@ softdep_setup_remove(bp, dp, ip, isrmdir
 	 * newdirrem() to setup the full directory remove which requires
 	 * isrmdir > 1.
 	 */
-	dirrem = newdirrem(bp, dp, ip, isrmdir?2:0, &prevdirrem);
+	dirrem = newdirrem(bp, dp, ip, isrmdir, &prevdirrem);
 	/*
 	 * Add the dirrem to the inodedep's pending remove list for quick
 	 * discovery later.
@@ -7152,14 +7152,12 @@ newdirrem(bp, dp, ip, isrmdir, prevdirre
 			    ip->i_effnlink + 2);
 			dotremref = newjremref(dirrem, ip, ip, DOT_OFFSET,
 			    ip->i_effnlink + 1);
-		} else
-			jremref = newjremref(dirrem, dp, ip, dp->i_offset,
-			    ip->i_effnlink + 1);
-		if (isrmdir > 1) {
 			dotdotremref = newjremref(dirrem, ip, dp, DOTDOT_OFFSET,
 			    dp->i_effnlink + 1);
 			dotdotremref->jr_state |= MKDIR_PARENT;
-		}
+		} else
+			jremref = newjremref(dirrem, dp, ip, dp->i_offset,
+			    ip->i_effnlink + 1);
 	}
 	ACQUIRE_LOCK(&lk);
 	lbn = lblkno(dp->i_fs, dp->i_offset);
@@ -7184,7 +7182,7 @@ newdirrem(bp, dp, ip, isrmdir, prevdirre
 	 * cancel it.  Any pending journal work will be added to the dirrem
 	 * to be completed when the workitem remove completes.
 	 */
-	if (isrmdir > 1)
+	if (isrmdir)
 		dotdotremref = cancel_diradd_dotdot(ip, dirrem, dotdotremref);
 	/*
 	 * Check for a diradd dependency for the same directory entry.

Modified: head/sys/ufs/ufs/ufs_vnops.c
==============================================================================
--- head/sys/ufs/ufs/ufs_vnops.c	Thu Dec 30 10:41:17 2010	(r216817)
+++ head/sys/ufs/ufs/ufs_vnops.c	Thu Dec 30 10:52:07 2010	(r216818)
@@ -1497,7 +1497,9 @@ relock:
 			/* Don't go to bad here as the new link exists. */
 			if (error)
 				goto unlockout;
-		}
+		} else if (DOINGSUJ(tdvp))
+			/* Journal must account for each new link. */
+			softdep_setup_dotdot_link(tdp, fip);
 		fip->i_offset = mastertemplate.dot_reclen;
 		ufs_dirrewrite(fip, fdp, newparent, DT_DIR, 0);
 		cache_purge(fdvp);



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