Skip to content

Commit

Permalink
xfs: format logged extents directly into the CIL
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Christoph Hellwig authored and Dave Chinner committed Dec 13, 2013
1 parent bde7cff commit da77650
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 106 deletions.
15 changes: 8 additions & 7 deletions fs/xfs/xfs_inode_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
113 changes: 18 additions & 95 deletions fs/xfs/xfs_inode_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
4 changes: 0 additions & 4 deletions fs/xfs/xfs_inode_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit da77650

Please sign in to comment.