Instead of setting up pointers to memory locations in iop_format which then get copied into the CIL linear buffer after return move the copy into the individual inode items. This avoids the need to always have a memory block in the exact same layout that gets written into the log around, and allow the log items to be much more flexible in their in-memory layouts. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- fs/xfs/xfs_buf_item.c | 89 ++++++++++++------- fs/xfs/xfs_dquot_item.c | 35 +++++--- fs/xfs/xfs_extfree_item.c | 33 ++++--- fs/xfs/xfs_icreate_item.c | 12 ++- fs/xfs/xfs_inode_fork.c | 15 ++-- fs/xfs/xfs_inode_item.c | 209 ++++++++++++++++----------------------------- fs/xfs/xfs_inode_item.h | 4 - fs/xfs/xfs_log.h | 30 +++++++ fs/xfs/xfs_log_cil.c | 35 +------- fs/xfs/xfs_trans.h | 2 +- 10 files changed, 222 insertions(+), 242 deletions(-) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index a64f67b..067a840 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -182,10 +182,44 @@ xfs_buf_item_size( trace_xfs_buf_item_size(bip); } +static inline struct xfs_log_iovec * +xfs_buf_item_set_iovec( + struct xfs_log_vec *lv, + struct xfs_log_iovec *vec, + struct xfs_buf *bp, + uint offset, + int first_bit, + uint len) +{ + vec = xlog_next_iovec(lv, vec); + + offset += first_bit * XFS_BLF_CHUNK; + len *= XFS_BLF_CHUNK; + + memcpy(vec->i_addr, xfs_buf_offset(bp, offset), len); + vec->i_len = len; + vec->i_type = XLOG_REG_TYPE_BCHUNK; + + return vec; +} + +static inline bool +xfs_buf_item_straddle( + struct xfs_buf *bp, + uint offset, + int next_bit, + int last_bit) +{ + return xfs_buf_offset(bp, offset + (next_bit << XFS_BLF_SHIFT)) != + (xfs_buf_offset(bp, offset + (last_bit << XFS_BLF_SHIFT)) + + XFS_BLF_CHUNK); +} + static struct xfs_log_iovec * xfs_buf_item_format_segment( struct xfs_buf_log_item *bip, - struct xfs_log_iovec *vecp, + struct xfs_log_vec *lv, + struct xfs_log_iovec *vec, uint offset, struct xfs_buf_log_format *blfp) { @@ -196,7 +230,6 @@ xfs_buf_item_format_segment( int last_bit; int next_bit; uint nbits; - uint buffer_offset; /* copy the flags across from the base format item */ blfp->blf_flags = bip->__bli_format.blf_flags; @@ -218,10 +251,14 @@ xfs_buf_item_format_segment( goto out; } - vecp->i_addr = blfp; - vecp->i_len = base_size; - vecp->i_type = XLOG_REG_TYPE_BFORMAT; - vecp++; + if (vec) + vec = xlog_next_iovec(lv, vec); + else + vec = xlog_first_iovec(lv); + + blfp = memcpy(vec->i_addr, blfp, base_size); + vec->i_len = base_size; + vec->i_type = XLOG_REG_TYPE_BFORMAT; nvecs = 1; if (bip->bli_flags & XFS_BLI_STALE) { @@ -261,33 +298,16 @@ xfs_buf_item_format_segment( * keep counting and scanning. */ if (next_bit == -1) { - buffer_offset = offset + first_bit * XFS_BLF_CHUNK; - vecp->i_addr = xfs_buf_offset(bp, buffer_offset); - vecp->i_len = nbits * XFS_BLF_CHUNK; - vecp->i_type = XLOG_REG_TYPE_BCHUNK; + vec = xfs_buf_item_set_iovec(lv, vec, bp, offset, + first_bit, nbits); nvecs++; break; - } else if (next_bit != last_bit + 1) { - buffer_offset = offset + first_bit * XFS_BLF_CHUNK; - vecp->i_addr = xfs_buf_offset(bp, buffer_offset); - vecp->i_len = nbits * XFS_BLF_CHUNK; - vecp->i_type = XLOG_REG_TYPE_BCHUNK; + } else if (next_bit != last_bit + 1 || + xfs_buf_item_straddle(bp, offset, next_bit, last_bit)) { + vec = xfs_buf_item_set_iovec(lv, vec, bp, offset, + first_bit, nbits); nvecs++; - vecp++; - first_bit = next_bit; - last_bit = next_bit; - nbits = 1; - } else if (xfs_buf_offset(bp, offset + - (next_bit << XFS_BLF_SHIFT)) != - (xfs_buf_offset(bp, offset + - (last_bit << XFS_BLF_SHIFT)) + - XFS_BLF_CHUNK)) { - buffer_offset = offset + first_bit * XFS_BLF_CHUNK; - vecp->i_addr = xfs_buf_offset(bp, buffer_offset); - vecp->i_len = nbits * XFS_BLF_CHUNK; - vecp->i_type = XLOG_REG_TYPE_BCHUNK; - nvecs++; - vecp++; + first_bit = next_bit; last_bit = next_bit; nbits = 1; @@ -298,7 +318,7 @@ xfs_buf_item_format_segment( } out: blfp->blf_size = nvecs; - return vecp; + return vec; } /* @@ -310,10 +330,11 @@ out: STATIC void xfs_buf_item_format( struct xfs_log_item *lip, - struct xfs_log_iovec *vecp) + struct xfs_log_vec *lv) { struct xfs_buf_log_item *bip = BUF_ITEM(lip); struct xfs_buf *bp = bip->bli_buf; + struct xfs_log_iovec *vec = NULL; uint offset = 0; int i; @@ -354,11 +375,13 @@ xfs_buf_item_format( } for (i = 0; i < bip->bli_format_count; i++) { - vecp = xfs_buf_item_format_segment(bip, vecp, offset, + vec = xfs_buf_item_format_segment(bip, lv, vec, offset, &bip->bli_formats[i]); offset += bp->b_maps[i].bm_len; } + xlog_last_iovec(lv, vec); + /* * Check to make sure everything is consistent. */ diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c index 92e5f62..5f446a7 100644 --- a/fs/xfs/xfs_dquot_item.c +++ b/fs/xfs/xfs_dquot_item.c @@ -57,20 +57,24 @@ xfs_qm_dquot_logitem_size( STATIC void xfs_qm_dquot_logitem_format( struct xfs_log_item *lip, - struct xfs_log_iovec *logvec) + struct xfs_log_vec *lv) { struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip); - - logvec->i_addr = &qlip->qli_format; - logvec->i_len = sizeof(xfs_dq_logformat_t); - logvec->i_type = XLOG_REG_TYPE_QFORMAT; - logvec++; - logvec->i_addr = &qlip->qli_dquot->q_core; - logvec->i_len = sizeof(xfs_disk_dquot_t); - logvec->i_type = XLOG_REG_TYPE_DQUOT; + struct xfs_log_iovec *vec; qlip->qli_format.qlf_size = 2; + vec = xlog_first_iovec(lv); + memcpy(vec->i_addr, &qlip->qli_format, sizeof(xfs_dq_logformat_t)); + vec->i_len = sizeof(xfs_dq_logformat_t); + vec->i_type = XLOG_REG_TYPE_QFORMAT; + + vec = xlog_next_iovec(lv, vec); + memcpy(vec->i_addr, &qlip->qli_dquot->q_core, sizeof(xfs_disk_dquot_t)); + vec->i_len = sizeof(xfs_disk_dquot_t); + vec->i_type = XLOG_REG_TYPE_DQUOT; + + xlog_last_iovec(lv, vec); } /* @@ -304,16 +308,21 @@ xfs_qm_qoff_logitem_size( STATIC void xfs_qm_qoff_logitem_format( struct xfs_log_item *lip, - struct xfs_log_iovec *log_vector) + struct xfs_log_vec *lv) { struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip); + struct xfs_log_iovec *vec; ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF); - log_vector->i_addr = &qflip->qql_format; - log_vector->i_len = sizeof(xfs_qoff_logitem_t); - log_vector->i_type = XLOG_REG_TYPE_QUOTAOFF; qflip->qql_format.qf_size = 1; + + vec = xlog_first_iovec(lv); + memcpy(vec->i_addr, &qflip->qql_format, sizeof(xfs_qoff_logitem_t)); + vec->i_len = sizeof(xfs_qoff_logitem_t); + vec->i_type = XLOG_REG_TYPE_QUOTAOFF; + + xlog_last_iovec(lv, vec); } /* diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 3680d04..94bf5e7 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -26,6 +26,7 @@ #include "xfs_trans_priv.h" #include "xfs_buf_item.h" #include "xfs_extfree_item.h" +#include "xfs_log.h" kmem_zone_t *xfs_efi_zone; @@ -101,9 +102,11 @@ xfs_efi_item_size( STATIC void xfs_efi_item_format( struct xfs_log_item *lip, - struct xfs_log_iovec *log_vector) + struct xfs_log_vec *lv) { struct xfs_efi_log_item *efip = EFI_ITEM(lip); + struct xfs_log_iovec *vec; + int size; ASSERT(atomic_read(&efip->efi_next_extent) == efip->efi_format.efi_nextents); @@ -111,12 +114,16 @@ xfs_efi_item_format( efip->efi_format.efi_type = XFS_LI_EFI; efip->efi_format.efi_size = 1; - log_vector->i_addr = &efip->efi_format; - log_vector->i_len = xfs_efi_item_sizeof(efip); - log_vector->i_type = XLOG_REG_TYPE_EFI_FORMAT; - ASSERT(log_vector->i_len >= sizeof(xfs_efi_log_format_t)); -} + size = xfs_efi_item_sizeof(efip); + ASSERT(size >= sizeof(xfs_efi_log_format_t)); + + vec = xlog_first_iovec(lv); + memcpy(vec->i_addr, &efip->efi_format, size); + vec->i_len = size; + vec->i_type = XLOG_REG_TYPE_EFI_FORMAT; + xlog_last_iovec(lv, vec); +} /* * Pinning has no meaning for an efi item, so just return. @@ -368,19 +375,23 @@ xfs_efd_item_size( STATIC void xfs_efd_item_format( struct xfs_log_item *lip, - struct xfs_log_iovec *log_vector) + struct xfs_log_vec *lv) { struct xfs_efd_log_item *efdp = EFD_ITEM(lip); + struct xfs_log_iovec *vec; ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents); efdp->efd_format.efd_type = XFS_LI_EFD; efdp->efd_format.efd_size = 1; - log_vector->i_addr = &efdp->efd_format; - log_vector->i_len = xfs_efd_item_sizeof(efdp); - log_vector->i_type = XLOG_REG_TYPE_EFD_FORMAT; - ASSERT(log_vector->i_len >= sizeof(xfs_efd_log_format_t)); + vec = xlog_first_iovec(lv); + memcpy(vec->i_addr, &efdp->efd_format, xfs_efd_item_sizeof(efdp)); + vec->i_len = xfs_efd_item_sizeof(efdp); + vec->i_type = XLOG_REG_TYPE_EFD_FORMAT; + ASSERT(vec->i_len >= sizeof(xfs_efd_log_format_t)); + + xlog_last_iovec(lv, vec); } /* diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c index d2eaccf..f6115c3 100644 --- a/fs/xfs/xfs_icreate_item.c +++ b/fs/xfs/xfs_icreate_item.c @@ -28,6 +28,7 @@ #include "xfs_trans_priv.h" #include "xfs_error.h" #include "xfs_icreate_item.h" +#include "xfs_log.h" kmem_zone_t *xfs_icreate_zone; /* inode create item zone */ @@ -58,13 +59,16 @@ xfs_icreate_item_size( STATIC void xfs_icreate_item_format( struct xfs_log_item *lip, - struct xfs_log_iovec *log_vector) + struct xfs_log_vec *lv) { struct xfs_icreate_item *icp = ICR_ITEM(lip); + struct xfs_log_iovec *vec; - log_vector->i_addr = (xfs_caddr_t)&icp->ic_format; - log_vector->i_len = sizeof(struct xfs_icreate_log); - log_vector->i_type = XLOG_REG_TYPE_ICREATE; + vec = xlog_first_iovec(lv); + memcpy(vec->i_addr, &icp->ic_format, sizeof(struct xfs_icreate_log)); + vec->i_len = sizeof(struct xfs_icreate_log); + vec->i_type = XLOG_REG_TYPE_ICREATE; + xlog_last_iovec(lv, vec); } diff --git a/fs/xfs/xfs_inode_fork.c b/fs/xfs/xfs_inode_fork.c index cfee14a..06abaee 100644 --- a/fs/xfs/xfs_inode_fork.c +++ b/fs/xfs/xfs_inode_fork.c @@ -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( diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 7c0d391f..fbdcde1 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -30,6 +30,7 @@ #include "xfs_trace.h" #include "xfs_trans_priv.h" #include "xfs_dinode.h" +#include "xfs_log.h" kmem_zone_t *xfs_ili_zone; /* inode log item zone */ @@ -137,41 +138,6 @@ xfs_inode_item_size( } /* - * 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 * log format structure, the second with the on-disk inode structure, @@ -181,24 +147,29 @@ xfs_inode_item_format_extents( STATIC void xfs_inode_item_format( struct xfs_log_item *lip, - struct xfs_log_iovec *vecp) + struct xfs_log_vec *lv) { struct xfs_inode_log_item *iip = INODE_ITEM(lip); struct xfs_inode *ip = iip->ili_inode; + struct xfs_log_iovec *vec; + struct xfs_inode_log_format *ilf; + uint size; uint nvecs; size_t data_bytes; xfs_mount_t *mp; - vecp->i_addr = &iip->ili_format; - vecp->i_len = sizeof(xfs_inode_log_format_t); - vecp->i_type = XLOG_REG_TYPE_IFORMAT; - vecp++; - nvecs = 1; - - vecp->i_addr = &ip->i_d; - vecp->i_len = xfs_icdinode_size(ip->i_d.di_version); - vecp->i_type = XLOG_REG_TYPE_ICORE; - vecp++; + vec = xlog_first_iovec(lv); + ilf = memcpy(vec->i_addr, &iip->ili_format, + sizeof(struct xfs_inode_log_format)); + vec->i_len = sizeof(struct xfs_inode_log_format); + vec->i_type = XLOG_REG_TYPE_IFORMAT; + nvecs = 1; + + vec = xlog_next_iovec(lv, vec); + size = xfs_icdinode_size(ip->i_d.di_version); + memcpy(vec->i_addr, &ip->i_d, size); + vec->i_len = size; + vec->i_type = XLOG_REG_TYPE_ICORE; nvecs++; /* @@ -210,9 +181,10 @@ xfs_inode_item_format( * has a new version number, then we don't bother converting back. */ mp = ip->i_mount; - ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb)); + ASSERT(ip->i_d.di_version == 1 || + xfs_sb_version_hasnlink(&ip->i_mount->m_sb)); if (ip->i_d.di_version == 1) { - if (!xfs_sb_version_hasnlink(&mp->m_sb)) { + if (!xfs_sb_version_hasnlink(&ip->i_mount->m_sb)) { /* * Convert it back. */ @@ -241,29 +213,15 @@ xfs_inode_item_format( ip->i_df.if_bytes > 0) { 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. - */ - vecp->i_addr = ip->i_df.if_u1.if_extents; - vecp->i_len = ip->i_df.if_bytes; - vecp->i_type = XLOG_REG_TYPE_IEXT; - } else -#endif - { - 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; - vecp++; + + vec = xlog_next_iovec(lv, vec); + vec->i_len = xfs_iextents_copy(ip, vec->i_addr, + XFS_DATA_FORK); + vec->i_type = XLOG_REG_TYPE_IEXT; nvecs++; + + ASSERT(vec->i_len <= ip->i_df.if_bytes); + ilf->ilf_dsize = vec->i_len; } else { iip->ili_fields &= ~XFS_ILOG_DEXT; } @@ -277,12 +235,15 @@ xfs_inode_item_format( if ((iip->ili_fields & XFS_ILOG_DBROOT) && ip->i_df.if_broot_bytes > 0) { ASSERT(ip->i_df.if_broot != NULL); - vecp->i_addr = ip->i_df.if_broot; - vecp->i_len = ip->i_df.if_broot_bytes; - vecp->i_type = XLOG_REG_TYPE_IBROOT; - vecp++; + + vec = xlog_next_iovec(lv, vec); + memcpy(vec->i_addr, ip->i_df.if_broot, + ip->i_df.if_broot_bytes); + vec->i_len = ip->i_df.if_broot_bytes; + vec->i_type = XLOG_REG_TYPE_IBROOT; nvecs++; - iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; + + ilf->ilf_dsize = ip->i_df.if_broot_bytes; } else { ASSERT(!(iip->ili_fields & XFS_ILOG_DBROOT)); @@ -299,7 +260,6 @@ xfs_inode_item_format( ASSERT(ip->i_df.if_u1.if_data != NULL); ASSERT(ip->i_d.di_size > 0); - vecp->i_addr = ip->i_df.if_u1.if_data; /* * Round i_bytes up to a word boundary. * The underlying memory is guaranteed to @@ -308,11 +268,14 @@ xfs_inode_item_format( data_bytes = roundup(ip->i_df.if_bytes, 4); ASSERT((ip->i_df.if_real_bytes == 0) || (ip->i_df.if_real_bytes == data_bytes)); - vecp->i_len = (int)data_bytes; - vecp->i_type = XLOG_REG_TYPE_ILOCAL; - vecp++; + + vec = xlog_next_iovec(lv, vec); + memcpy(vec->i_addr, ip->i_df.if_u1.if_data, data_bytes); + vec->i_len = data_bytes; + vec->i_type = XLOG_REG_TYPE_ILOCAL; nvecs++; - iip->ili_format.ilf_dsize = (unsigned)data_bytes; + + ilf->ilf_dsize = (unsigned)data_bytes; } else { iip->ili_fields &= ~XFS_ILOG_DDATA; } @@ -322,20 +285,16 @@ xfs_inode_item_format( iip->ili_fields &= ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEXT | XFS_ILOG_UUID); - if (iip->ili_fields & XFS_ILOG_DEV) { - iip->ili_format.ilf_u.ilfu_rdev = - ip->i_df.if_u2.if_rdev; - } + if (iip->ili_fields & XFS_ILOG_DEV) + ilf->ilf_u.ilfu_rdev = ip->i_df.if_u2.if_rdev; break; case XFS_DINODE_FMT_UUID: iip->ili_fields &= ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | XFS_ILOG_DEXT | XFS_ILOG_DEV); - if (iip->ili_fields & XFS_ILOG_UUID) { - iip->ili_format.ilf_u.ilfu_uuid = - ip->i_df.if_u2.if_uuid; - } + if (iip->ili_fields & XFS_ILOG_UUID) + ilf->ilf_u.ilfu_uuid = ip->i_df.if_u2.if_uuid; break; default: @@ -363,22 +322,14 @@ xfs_inode_item_format( 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. - */ - 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); - xfs_inode_item_format_extents(ip, vecp, - XFS_ATTR_FORK, XLOG_REG_TYPE_IATTR_EXT); -#endif - iip->ili_format.ilf_asize = vecp->i_len; - vecp++; + + vec = xlog_next_iovec(lv, vec); + vec->i_len = xfs_iextents_copy(ip, vec->i_addr, + XFS_ATTR_FORK); + vec->i_type = XLOG_REG_TYPE_IATTR_EXT; nvecs++; + + ilf->ilf_asize = vec->i_len; } else { iip->ili_fields &= ~XFS_ILOG_AEXT; } @@ -392,12 +343,14 @@ xfs_inode_item_format( ip->i_afp->if_broot_bytes > 0) { ASSERT(ip->i_afp->if_broot != NULL); - vecp->i_addr = ip->i_afp->if_broot; - vecp->i_len = ip->i_afp->if_broot_bytes; - vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT; - vecp++; + vec = xlog_next_iovec(lv, vec); + memcpy(vec->i_addr, ip->i_afp->if_broot, + ip->i_afp->if_broot_bytes); + vec->i_len = ip->i_afp->if_broot_bytes; + vec->i_type = XLOG_REG_TYPE_IATTR_BROOT; nvecs++; - iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; + + ilf->ilf_asize = ip->i_afp->if_broot_bytes; } else { iip->ili_fields &= ~XFS_ILOG_ABROOT; } @@ -411,7 +364,6 @@ xfs_inode_item_format( ip->i_afp->if_bytes > 0) { ASSERT(ip->i_afp->if_u1.if_data != NULL); - vecp->i_addr = ip->i_afp->if_u1.if_data; /* * Round i_bytes up to a word boundary. * The underlying memory is guaranteed to @@ -420,11 +372,15 @@ xfs_inode_item_format( data_bytes = roundup(ip->i_afp->if_bytes, 4); ASSERT((ip->i_afp->if_real_bytes == 0) || (ip->i_afp->if_real_bytes == data_bytes)); - vecp->i_len = (int)data_bytes; - vecp->i_type = XLOG_REG_TYPE_IATTR_LOCAL; - vecp++; + + vec = xlog_next_iovec(lv, vec); + memcpy(vec->i_addr, ip->i_afp->if_u1.if_data, + data_bytes); + vec->i_len = data_bytes; + vec->i_type = XLOG_REG_TYPE_IATTR_LOCAL; nvecs++; - iip->ili_format.ilf_asize = (unsigned)data_bytes; + + ilf->ilf_asize = (unsigned)data_bytes; } else { iip->ili_fields &= ~XFS_ILOG_ADATA; } @@ -436,18 +392,18 @@ xfs_inode_item_format( } out: + xlog_last_iovec(lv, vec); /* * Now update the log format that goes out to disk from the in-core * values. We always write the inode core to make the arithmetic * games in recovery easier, which isn't a big deal as just about any * transaction would dirty it anyway. */ - iip->ili_format.ilf_fields = XFS_ILOG_CORE | + ilf->ilf_fields = XFS_ILOG_CORE | (iip->ili_fields & ~XFS_ILOG_TIMESTAMP); - iip->ili_format.ilf_size = nvecs; + ilf->ilf_size = nvecs; } - /* * This is called to pin the inode associated with the inode log * item in memory so it cannot be written out. @@ -563,27 +519,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) diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index dce4d65..29b5f2b 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -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; diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h index e148719..3769830 100644 --- a/fs/xfs/xfs_log.h +++ b/fs/xfs/xfs_log.h @@ -30,6 +30,36 @@ struct xfs_log_vec { #define XFS_LOG_VEC_ORDERED (-1) +static inline struct xfs_log_iovec * +xlog_first_iovec(struct xfs_log_vec *lv) +{ + struct xfs_log_iovec *vec = &lv->lv_iovecp[0]; + + vec->i_addr = lv->lv_buf; + lv->lv_buf_len = 0; + return vec; +} + +static inline struct xfs_log_iovec * +xlog_next_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *prev) +{ + struct xfs_log_iovec *vec; + + ASSERT(prev - lv->lv_iovecp < lv->lv_niovecs); + + vec = prev + 1; + vec->i_addr = prev->i_addr + prev->i_len; + lv->lv_buf_len += prev->i_len; + return vec; +} + +static inline void +xlog_last_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *prev) +{ + ASSERT(prev - lv->lv_iovecp < lv->lv_niovecs); + lv->lv_buf_len += prev->i_len; +} + /* * Structure used to pass callback function and the function's argument * to the log manager. diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 5eb51fc..8d5f2ea 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -82,36 +82,6 @@ xlog_cil_init_post_recovery( log->l_curr_block); } -STATIC int -xlog_cil_lv_item_format( - struct xfs_log_item *lip, - struct xfs_log_vec *lv) -{ - int index; - char *ptr; - - /* format new vectors into array */ - lip->li_ops->iop_format(lip, lv->lv_iovecp); - - /* copy data into existing array */ - ptr = lv->lv_buf; - for (index = 0; index < lv->lv_niovecs; index++) { - struct xfs_log_iovec *vec = &lv->lv_iovecp[index]; - - memcpy(ptr, vec->i_addr, vec->i_len); - vec->i_addr = ptr; - ptr += vec->i_len; - } - - /* - * some size calculations for log vectors over-estimate, so the caller - * doesn't know the amount of space actually used by the item. Return - * the byte count to the caller so they can check and store it - * appropriately. - */ - return ptr - lv->lv_buf; -} - /* * Prepare the log item for insertion into the CIL. Calculate the difference in * log space and vectors it will consume, and if it is a new item pin it as @@ -259,7 +229,7 @@ xlog_cil_insert_format_items( lv->lv_niovecs = niovecs; lv->lv_buf = (char *)lv + buf_size - nbytes; - lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv); + lip->li_ops->iop_format(lip, lv); goto insert; } @@ -281,7 +251,8 @@ xlog_cil_insert_format_items( /* The allocated data region lies beyond the iovec region */ lv->lv_buf = (char *)lv + buf_size - nbytes; - lv->lv_buf_len = xlog_cil_lv_item_format(lip, lv); + /* Format new vectors into array */ + lip->li_ops->iop_format(lip, lv); insert: ASSERT(lv->lv_buf_len <= nbytes); xfs_cil_prepare_item(log, lv, old_lv, diff_len, diff_iovecs); diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 9b96d35..b5bc1ab 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -64,7 +64,7 @@ typedef struct xfs_log_item { struct xfs_item_ops { void (*iop_size)(xfs_log_item_t *, int *, int *); - void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *); + void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *); void (*iop_pin)(xfs_log_item_t *); void (*iop_unpin)(xfs_log_item_t *, int remove); uint (*iop_push)(struct xfs_log_item *, struct list_head *); -- 1.7.10.4 _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs