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);
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to