Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Sep 2016 12:09:34 +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: r305601 - head/sys/ufs/ufs
Message-ID:  <201609081209.u88C9YVf017137@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu Sep  8 12:09:34 2016
New Revision: 305601
URL: https://svnweb.freebsd.org/changeset/base/305601

Log:
  On rename, do not perform truncation of dirhash if the vnode
  truncation failed.
  
  Doing so resulted in inconsistent state of the ufs dirhash with regard
  to the actual directory inode state, and could lead to spurious ENOENT
  errors for lookups of existing files in production kernels, or
  assertion failures in the debugging kernels.
  
  Change the logic of calling ufsdirhash_dirtrunc() to be same as in
  ufs_direnter().  Execute UFS_TRUNCATE() first, log error, and only do
  dirtrunc() if UFS_TRUNCATE() succeeded.
  
  Note that the problem was exacerbated by the bug in the
  flush_newblk_dep() function (see r305599), which caused in the spurios
  errors from ffs_sync() and then ffs_truncate().
  
  In collaboration with:	pho
  Reviewed by:	mckusick
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

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

Modified: head/sys/ufs/ufs/ufs_vnops.c
==============================================================================
--- head/sys/ufs/ufs/ufs_vnops.c	Thu Sep  8 12:09:13 2016	(r305600)
+++ head/sys/ufs/ufs/ufs_vnops.c	Thu Sep  8 12:09:34 2016	(r305601)
@@ -1529,11 +1529,21 @@ unlockout:
 	 * are no longer needed.
 	 */
 	if (error == 0 && endoff != 0) {
+		error = UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | IO_SYNC,
+		    tcnp->cn_cred);
+		if (error != 0)
+			vn_printf(tdvp, "ufs_rename: failed to truncate "
+			    "err %d", error);
 #ifdef UFS_DIRHASH
-		if (tdp->i_dirhash != NULL)
+		else if (tdp->i_dirhash != NULL)
 			ufsdirhash_dirtrunc(tdp, endoff);
 #endif
-		UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | IO_SYNC, tcnp->cn_cred);
+		/*
+		 * Even if the directory compaction failed, rename was
+		 * succesful.  Do not propagate a UFS_TRUNCATE() error
+		 * to the caller.
+		 */
+		error = 0;
 	}
 	if (error == 0 && tdp->i_flag & IN_NEEDSYNC)
 		error = VOP_FSYNC(tdvp, MNT_WAIT, td);



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