|
@@ -197,6 +197,41 @@ xfs_inode_item_size(
|
|
|
return nvecs;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * xfs_inode_item_format_extents - convert in-core extents to on-disk form
|
|
|
+ *
|
|
|
+ * For either the data or attr fork in extent format, we need to endian convert
|
|
|
+ * the in-core extent as we place them into the on-disk inode. In this case, we
|
|
|
+ * need to do this conversion before we write the extents into the log. Because
|
|
|
+ * we don't have the disk inode to write into here, we allocate a buffer and
|
|
|
+ * format the extents into it via xfs_iextents_copy(). We free the buffer in
|
|
|
+ * the unlock routine after the copy for the log has been made.
|
|
|
+ *
|
|
|
+ * In the case of the data fork, the in-core and on-disk fork sizes can be
|
|
|
+ * different due to delayed allocation extents. We only log on-disk extents
|
|
|
+ * here, so always use the physical fork size to determine the size of the
|
|
|
+ * buffer we need to allocate.
|
|
|
+ */
|
|
|
+STATIC void
|
|
|
+xfs_inode_item_format_extents(
|
|
|
+ struct xfs_inode *ip,
|
|
|
+ struct xfs_log_iovec *vecp,
|
|
|
+ int whichfork,
|
|
|
+ int type)
|
|
|
+{
|
|
|
+ xfs_bmbt_rec_t *ext_buffer;
|
|
|
+
|
|
|
+ ext_buffer = kmem_alloc(XFS_IFORK_SIZE(ip, whichfork), KM_SLEEP);
|
|
|
+ if (whichfork == XFS_DATA_FORK)
|
|
|
+ ip->i_itemp->ili_extents_buf = ext_buffer;
|
|
|
+ else
|
|
|
+ ip->i_itemp->ili_aextents_buf = ext_buffer;
|
|
|
+
|
|
|
+ vecp->i_addr = ext_buffer;
|
|
|
+ vecp->i_len = xfs_iextents_copy(ip, ext_buffer, whichfork);
|
|
|
+ vecp->i_type = type;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* This is called to fill in the vector of log iovecs for the
|
|
|
* given inode log item. It fills the first item with an inode
|
|
@@ -213,7 +248,6 @@ xfs_inode_item_format(
|
|
|
struct xfs_inode *ip = iip->ili_inode;
|
|
|
uint nvecs;
|
|
|
size_t data_bytes;
|
|
|
- xfs_bmbt_rec_t *ext_buffer;
|
|
|
xfs_mount_t *mp;
|
|
|
|
|
|
vecp->i_addr = &iip->ili_format;
|
|
@@ -320,22 +354,8 @@ xfs_inode_item_format(
|
|
|
} else
|
|
|
#endif
|
|
|
{
|
|
|
- /*
|
|
|
- * There are delayed allocation extents
|
|
|
- * in the inode, or we need to convert
|
|
|
- * the extents to on disk format.
|
|
|
- * Use xfs_iextents_copy()
|
|
|
- * to copy only the real extents into
|
|
|
- * a separate buffer. We'll free the
|
|
|
- * buffer in the unlock routine.
|
|
|
- */
|
|
|
- ext_buffer = kmem_alloc(ip->i_df.if_bytes,
|
|
|
- KM_SLEEP);
|
|
|
- iip->ili_extents_buf = ext_buffer;
|
|
|
- vecp->i_addr = ext_buffer;
|
|
|
- vecp->i_len = xfs_iextents_copy(ip, ext_buffer,
|
|
|
- XFS_DATA_FORK);
|
|
|
- vecp->i_type = XLOG_REG_TYPE_IEXT;
|
|
|
+ xfs_inode_item_format_extents(ip, vecp,
|
|
|
+ XFS_DATA_FORK, XLOG_REG_TYPE_IEXT);
|
|
|
}
|
|
|
ASSERT(vecp->i_len <= ip->i_df.if_bytes);
|
|
|
iip->ili_format.ilf_dsize = vecp->i_len;
|
|
@@ -445,19 +465,12 @@ xfs_inode_item_format(
|
|
|
*/
|
|
|
vecp->i_addr = ip->i_afp->if_u1.if_extents;
|
|
|
vecp->i_len = ip->i_afp->if_bytes;
|
|
|
+ vecp->i_type = XLOG_REG_TYPE_IATTR_EXT;
|
|
|
#else
|
|
|
ASSERT(iip->ili_aextents_buf == NULL);
|
|
|
- /*
|
|
|
- * Need to endian flip before logging
|
|
|
- */
|
|
|
- ext_buffer = kmem_alloc(ip->i_afp->if_bytes,
|
|
|
- KM_SLEEP);
|
|
|
- iip->ili_aextents_buf = ext_buffer;
|
|
|
- vecp->i_addr = ext_buffer;
|
|
|
- vecp->i_len = xfs_iextents_copy(ip, ext_buffer,
|
|
|
- XFS_ATTR_FORK);
|
|
|
+ xfs_inode_item_format_extents(ip, vecp,
|
|
|
+ XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT);
|
|
|
#endif
|
|
|
- vecp->i_type = XLOG_REG_TYPE_IATTR_EXT;
|
|
|
iip->ili_format.ilf_asize = vecp->i_len;
|
|
|
vecp++;
|
|
|
nvecs++;
|