/*
         * If it is an inode buffer, transfer the in-memory state to the
-        * format flags and clear the in-memory state. We do not transfer
+        * format flags and clear the in-memory state.
+        *
+        * For buffer based inode allocation, we do not transfer
         * this state if the inode buffer allocation has not yet been committed
         * to the log as setting the XFS_BLI_INODE_BUF flag will prevent
         * correct replay of the inode allocation.
+        *
+        * For icreate item based inode allocation, the buffers aren't written
+        * to the journal during allocation, and hence we should always tag the
+        * buffer as an inode buffer so that the correct unlinked list replay
+        * occurs during recovery.
         */
        if (bip->bli_flags & XFS_BLI_INODE_BUF) {
-               if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
+               if (xfs_sb_version_hascrc(&lip->li_mountp->m_sb) ||
+                   !((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
                      xfs_log_item_in_current_chkpt(lip)))
                        bip->__bli_format.blf_flags |= XFS_BLF_INODE_BUF;
                bip->bli_flags &= ~XFS_BLI_INODE_BUF;
 
 #include "xfs_bmap.h"
 #include "xfs_cksum.h"
 #include "xfs_buf_item.h"
+#include "xfs_icreate_item.h"
 
 
 /*
  * than logging them (which in a transaction context puts them into the AIL
  * for writeback rather than the xfsbufd queue).
  */
-STATIC int
+int
 xfs_ialloc_inode_init(
        struct xfs_mount        *mp,
        struct xfs_trans        *tp,
                version = 3;
                ino = XFS_AGINO_TO_INO(mp, agno,
                                       XFS_OFFBNO_TO_AGINO(mp, agbno, 0));
+
+               /*
+                * log the initialisation that is about to take place as an
+                * logical operation. This means the transaction does not
+                * need to log the physical changes to the inode buffers as log
+                * recovery will know what initialisation is actually needed.
+                * Hence we only need to log the buffers as "ordered" buffers so
+                * they track in the AIL as if they were physically logged.
+                */
+               if (tp)
+                       xfs_icreate_log(tp, agno, agbno, XFS_IALLOC_INODES(mp),
+                                       mp->m_sb.sb_inodesize, length, gen);
        } else if (xfs_sb_version_hasnlink(&mp->m_sb))
                version = 2;
        else
                                         XBF_UNMAPPED);
                if (!fbuf)
                        return ENOMEM;
-               /*
-                * Initialize all inodes in this buffer and then log them.
-                *
-                * XXX: It would be much better if we had just one transaction
-                *      to log a whole cluster of inodes instead of all the
-                *      individual transactions causing a lot of log traffic.
-                */
+
+               /* Initialize the inode buffers and log them appropriately. */
                fbuf->b_ops = &xfs_inode_buf_ops;
                xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
                for (i = 0; i < ninodes; i++) {
                         */
                        xfs_trans_inode_alloc_buf(tp, fbuf);
                        if (version == 3) {
-                               /* need to log the entire buffer */
+                               /*
+                                * Mark the buffer as ordered so that they are
+                                * not physically logged in the transaction but
+                                * still tracked in the AIL as part of the
+                                * transaction and pin the log appropriately.
+                                */
+                               xfs_trans_ordered_buf(tp, fbuf);
                                xfs_trans_log_buf(tp, fbuf, 0,
                                                  BBTOB(fbuf->b_length) - 1);
                        }