Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 May 2010 09:51:57 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r207956 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201005120951.o4C9pvWs065377@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Wed May 12 09:51:57 2010
New Revision: 207956
URL: http://svn.freebsd.org/changeset/base/207956

Log:
  Fix possible hang when replaying large truncations.
  
  OpenSolaris onnv revision:	7904:6a124a4ca9c5
  
  Approved by:	pjd, delphij (mentor)
  Obtained from:	OpenSolaris (Bug ID 6761624)
  MFC after:	3 days

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c	Wed May 12 09:34:10 2010	(r207955)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c	Wed May 12 09:51:57 2010	(r207956)
@@ -1567,6 +1567,29 @@ zil_replay_log_record(zilog_t *zilog, lr
 	}
 
 	/*
+	 * Replay of large truncates can end up needing additional txs
+	 * and a different txg. If they are nested within the replay tx
+	 * as below then a hang is possible. So we do the truncate here
+	 * and redo the truncate later (a no-op) and update the sequence
+	 * number whilst in the replay tx. Fortunately, it's safe to repeat
+	 * a truncate if we crash and the truncate commits. A create over
+	 * an existing file will also come in as a TX_TRUNCATE record.
+	 *
+	 * Note, remove of large files and renames over large files is
+	 * handled by putting the deleted object on a stable list
+	 * and if necessary force deleting the object outside of the replay
+	 * transaction using the zr_replay_cleaner.
+	 */
+	if (txtype == TX_TRUNCATE) {
+		*zr->zr_txgp = TXG_NOWAIT;
+		error = zr->zr_replay[TX_TRUNCATE](zr->zr_arg, zr->zr_lrbuf,
+		    zr->zr_byteswap);
+		if (error)
+			goto bad;
+		zr->zr_byteswap = 0; /* only byteswap once */
+	}
+
+	/*
 	 * We must now do two things atomically: replay this log record,
 	 * and update the log header to reflect the fact that we did so.
 	 * We use the DMU's ability to assign into a specific txg to do this.
@@ -1636,6 +1659,7 @@ zil_replay_log_record(zilog_t *zilog, lr
 		dprintf("pass %d, retrying\n", pass);
 	}
 
+bad:
 	ASSERT(error && error != ERESTART);
 	name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
 	dmu_objset_name(zr->zr_os, name);



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