xfs: format logged extents directly into the CIL

With the new iop_format scheme there is no need to have a temporary buffer
to format logged extents into, we can do so directly into the CIL.  This
also allows to remove the shortcut for big endian systems that probably
hasn't gotten a lot of test coverage for a long time.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
Christoph Hellwig 2013-12-13 11:34:04 +11:00 коммит произвёл Dave Chinner
Родитель bde7cff67c
Коммит da7765031d
3 изменённых файлов: 25 добавлений и 105 удалений

Просмотреть файл

@ -721,15 +721,16 @@ xfs_idestroy_fork(
}
/*
* xfs_iextents_copy()
* Convert in-core extents to on-disk form
*
* This is called to copy the REAL extents (as opposed to the delayed
* allocation extents) from the inode into the given buffer. It
* returns the number of bytes copied into the buffer.
* 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.
*
* If there are no delayed allocation extents, then we can just
* memcpy() the extents into the buffer. Otherwise, we need to
* examine each extent in turn and skip those which are delayed.
* 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 copy on-disk extents
* here, so callers must always use the physical fork size to determine the
* size of the buffer passed to this routine. We will return the size actually
* used.
*/
int
xfs_iextents_copy(

Просмотреть файл

@ -145,43 +145,6 @@ xfs_inode_item_size(
xfs_inode_item_attr_fork_size(iip, nvecs, nbytes);
}
/*
* 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 int
xfs_inode_item_format_extents(
struct xfs_inode *ip,
struct xfs_log_vec *lv,
struct xfs_log_iovec **vecp,
int whichfork,
int type)
{
xfs_bmbt_rec_t *ext_buffer;
int len;
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;
len = xfs_iextents_copy(ip, ext_buffer, whichfork);
xlog_copy_iovec(lv, vecp, type, ext_buffer, len);
return len;
}
/*
* If this is a v1 format inode, then we need to log it as such. This means
* that we have to copy the link count from the new field to the old. We
@ -229,30 +192,18 @@ xfs_inode_item_format_data_fork(
if ((iip->ili_fields & XFS_ILOG_DEXT) &&
ip->i_d.di_nextents > 0 &&
ip->i_df.if_bytes > 0) {
struct xfs_bmbt_rec *p;
ASSERT(ip->i_df.if_u1.if_extents != NULL);
ASSERT(ip->i_df.if_bytes / sizeof(xfs_bmbt_rec_t) > 0);
ASSERT(iip->ili_extents_buf == NULL);
#ifdef XFS_NATIVE_HOST
if (ip->i_d.di_nextents == ip->i_df.if_bytes /
(uint)sizeof(xfs_bmbt_rec_t)) {
/*
* There are no delayed allocation
* extents, so just point to the
* real extents array.
*/
xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IEXT,
ip->i_df.if_u1.if_extents,
ip->i_df.if_bytes);
ilf->ilf_dsize = ip->i_df.if_bytes;
} else
#endif
{
ilf->ilf_dsize =
xfs_inode_item_format_extents(ip, lv, vecp,
XFS_DATA_FORK, XLOG_REG_TYPE_IEXT);
ASSERT(iip->ili_format.ilf_dsize <= ip->i_df.if_bytes);
}
p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT);
data_bytes = xfs_iextents_copy(ip, p, XFS_DATA_FORK);
xlog_finish_iovec(lv, *vecp, data_bytes);
ASSERT(data_bytes <= ip->i_df.if_bytes);
ilf->ilf_dsize = data_bytes;
ilf->ilf_size++;
} else {
iip->ili_fields &= ~XFS_ILOG_DEXT;
@ -339,24 +290,17 @@ xfs_inode_item_format_attr_fork(
if ((iip->ili_fields & XFS_ILOG_AEXT) &&
ip->i_d.di_anextents > 0 &&
ip->i_afp->if_bytes > 0) {
struct xfs_bmbt_rec *p;
ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) ==
ip->i_d.di_anextents);
ASSERT(ip->i_afp->if_u1.if_extents != NULL);
#ifdef XFS_NATIVE_HOST
/*
* There are not delayed allocation extents
* for attributes, so just point at the array.
*/
xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT,
ip->i_afp->if_u1.if_extents,
ip->i_afp->if_bytes);
ilf->ilf_asize = ip->i_afp->if_bytes;
#else
ASSERT(iip->ili_aextents_buf == NULL);
ilf->ilf_asize =
xfs_inode_item_format_extents(ip, lv, vecp,
XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT);
#endif
p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT);
data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK);
xlog_finish_iovec(lv, *vecp, data_bytes);
ilf->ilf_asize = data_bytes;
ilf->ilf_size++;
} else {
iip->ili_fields &= ~XFS_ILOG_AEXT;
@ -571,27 +515,6 @@ xfs_inode_item_unlock(
ASSERT(ip->i_itemp != NULL);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
/*
* If the inode needed a separate buffer with which to log
* its extents, then free it now.
*/
if (iip->ili_extents_buf != NULL) {
ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS);
ASSERT(ip->i_d.di_nextents > 0);
ASSERT(iip->ili_fields & XFS_ILOG_DEXT);
ASSERT(ip->i_df.if_bytes > 0);
kmem_free(iip->ili_extents_buf);
iip->ili_extents_buf = NULL;
}
if (iip->ili_aextents_buf != NULL) {
ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS);
ASSERT(ip->i_d.di_anextents > 0);
ASSERT(iip->ili_fields & XFS_ILOG_AEXT);
ASSERT(ip->i_afp->if_bytes > 0);
kmem_free(iip->ili_aextents_buf);
iip->ili_aextents_buf = NULL;
}
lock_flags = iip->ili_lock_flags;
iip->ili_lock_flags = 0;
if (lock_flags)

Просмотреть файл

@ -34,10 +34,6 @@ typedef struct xfs_inode_log_item {
unsigned short ili_logged; /* flushed logged data */
unsigned int ili_last_fields; /* fields when flushed */
unsigned int ili_fields; /* fields to be logged */
struct xfs_bmbt_rec *ili_extents_buf; /* array of logged
data exts */
struct xfs_bmbt_rec *ili_aextents_buf; /* array of logged
attr exts */
xfs_inode_log_format_t ili_format; /* logged structure */
} xfs_inode_log_item_t;