]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: improve the ->iop_format interface
authorChristoph Hellwig <hch@lst.de>
Wed, 12 Nov 2025 12:14:19 +0000 (13:14 +0100)
committerCarlos Maiolino <cem@kernel.org>
Wed, 21 Jan 2026 11:57:16 +0000 (12:57 +0100)
Export a higher level interface to format log items.  The xlog_format_buf
structure is hidden inside xfs_log_cil.c and only accessed using two
helpers (and a wrapper build on top), hiding details of log iovecs from
the log items.  This also allows simply using an index into lv_iovecp
instead of keeping a cursor vec.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
14 files changed:
fs/xfs/xfs_attr_item.c
fs/xfs/xfs_bmap_item.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_dquot_item.c
fs/xfs/xfs_exchmaps_item.c
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_icreate_item.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_log.c
fs/xfs/xfs_log.h
fs/xfs/xfs_log_cil.c
fs/xfs/xfs_refcount_item.c
fs/xfs/xfs_rmap_item.c
fs/xfs/xfs_trans.h

index e8fa326ac995bcc67e60bca05f65b8a42bda1d4a..ad2956f78ecab5b73480801cf57947a83f677ef7 100644 (file)
@@ -192,10 +192,9 @@ xfs_attri_item_size(
 STATIC void
 xfs_attri_item_format(
        struct xfs_log_item             *lip,
-       struct xfs_log_vec              *lv)
+       struct xlog_format_buf          *lfb)
 {
        struct xfs_attri_log_item       *attrip = ATTRI_ITEM(lip);
-       struct xfs_log_iovec            *vecp = NULL;
        struct xfs_attri_log_nameval    *nv = attrip->attri_nameval;
 
        attrip->attri_format.alfi_type = XFS_LI_ATTRI;
@@ -220,24 +219,23 @@ xfs_attri_item_format(
        if (nv->new_value.iov_len > 0)
                attrip->attri_format.alfi_size++;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTRI_FORMAT,
-                       &attrip->attri_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_ATTRI_FORMAT, &attrip->attri_format,
                        sizeof(struct xfs_attri_log_format));
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTR_NAME, nv->name.iov_base,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_ATTR_NAME, nv->name.iov_base,
                        nv->name.iov_len);
 
        if (nv->new_name.iov_len > 0)
-               xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTR_NEWNAME,
-                       nv->new_name.iov_base, nv->new_name.iov_len);
+               xlog_format_copy(lfb, XLOG_REG_TYPE_ATTR_NEWNAME,
+                               nv->new_name.iov_base, nv->new_name.iov_len);
 
        if (nv->value.iov_len > 0)
-               xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTR_VALUE,
-                       nv->value.iov_base, nv->value.iov_len);
+               xlog_format_copy(lfb, XLOG_REG_TYPE_ATTR_VALUE,
+                               nv->value.iov_base, nv->value.iov_len);
 
        if (nv->new_value.iov_len > 0)
-               xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTR_NEWVALUE,
-                       nv->new_value.iov_base, nv->new_value.iov_len);
+               xlog_format_copy(lfb, XLOG_REG_TYPE_ATTR_NEWVALUE,
+                               nv->new_value.iov_base, nv->new_value.iov_len);
 }
 
 /*
@@ -322,16 +320,15 @@ xfs_attrd_item_size(
  */
 STATIC void
 xfs_attrd_item_format(
-       struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xfs_log_item             *lip,
+       struct xlog_format_buf          *lfb)
 {
        struct xfs_attrd_log_item       *attrdp = ATTRD_ITEM(lip);
-       struct xfs_log_iovec            *vecp = NULL;
 
        attrdp->attrd_format.alfd_type = XFS_LI_ATTRD;
        attrdp->attrd_format.alfd_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ATTRD_FORMAT,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_ATTRD_FORMAT,
                        &attrdp->attrd_format,
                        sizeof(struct xfs_attrd_log_format));
 }
index 80f0c4bcc483fbf2425ca8dfc4fa38e2d424a8f3..f38ed63fe86beae8a0f4fef5210b888b34e3cafa 100644 (file)
@@ -92,10 +92,9 @@ unsigned int xfs_bui_log_space(unsigned int nr)
 STATIC void
 xfs_bui_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_bui_log_item *buip = BUI_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(atomic_read(&buip->bui_next_extent) ==
                        buip->bui_format.bui_nextents);
@@ -103,7 +102,7 @@ xfs_bui_item_format(
        buip->bui_format.bui_type = XFS_LI_BUI;
        buip->bui_format.bui_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_BUI_FORMAT, &buip->bui_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_BUI_FORMAT, &buip->bui_format,
                        xfs_bui_log_format_sizeof(buip->bui_format.bui_nextents));
 }
 
@@ -188,15 +187,14 @@ unsigned int xfs_bud_log_space(void)
 STATIC void
 xfs_bud_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_bud_log_item *budp = BUD_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        budp->bud_format.bud_type = XFS_LI_BUD;
        budp->bud_format.bud_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_BUD_FORMAT, &budp->bud_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_BUD_FORMAT, &budp->bud_format,
                        sizeof(struct xfs_bud_log_format));
 }
 
index f4c5be67826e2208e2c8e38a6281347a5cfa504a..cb2a36374ed4cc71cdb38cc62cd4cf72574e5706 100644 (file)
@@ -263,24 +263,21 @@ xfs_buf_item_size(
 
 static inline void
 xfs_buf_item_copy_iovec(
-       struct xfs_log_vec      *lv,
-       struct xfs_log_iovec    **vecp,
+       struct xlog_format_buf  *lfb,
        struct xfs_buf          *bp,
        uint                    offset,
        int                     first_bit,
        uint                    nbits)
 {
        offset += first_bit * XFS_BLF_CHUNK;
-       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BCHUNK,
-                       xfs_buf_offset(bp, offset),
+       xlog_format_copy(lfb, XLOG_REG_TYPE_BCHUNK, xfs_buf_offset(bp, offset),
                        nbits * XFS_BLF_CHUNK);
 }
 
 static void
 xfs_buf_item_format_segment(
        struct xfs_buf_log_item *bip,
-       struct xfs_log_vec      *lv,
-       struct xfs_log_iovec    **vecp,
+       struct xlog_format_buf  *lfb,
        uint                    offset,
        struct xfs_buf_log_format *blfp)
 {
@@ -308,7 +305,7 @@ xfs_buf_item_format_segment(
                return;
        }
 
-       blfp = xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_BFORMAT, blfp, base_size);
+       blfp = xlog_format_copy(lfb, XLOG_REG_TYPE_BFORMAT, blfp, base_size);
        blfp->blf_size = 1;
 
        if (bip->bli_flags & XFS_BLI_STALE) {
@@ -331,8 +328,7 @@ xfs_buf_item_format_segment(
                nbits = xfs_contig_bits(blfp->blf_data_map,
                                        blfp->blf_map_size, first_bit);
                ASSERT(nbits > 0);
-               xfs_buf_item_copy_iovec(lv, vecp, bp, offset,
-                                       first_bit, nbits);
+               xfs_buf_item_copy_iovec(lfb, bp, offset, first_bit, nbits);
                blfp->blf_size++;
 
                /*
@@ -357,11 +353,10 @@ xfs_buf_item_format_segment(
 STATIC void
 xfs_buf_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_buf_log_item *bip = BUF_ITEM(lip);
        struct xfs_buf          *bp = bip->bli_buf;
-       struct xfs_log_iovec    *vecp = NULL;
        uint                    offset = 0;
        int                     i;
 
@@ -398,7 +393,7 @@ xfs_buf_item_format(
        }
 
        for (i = 0; i < bip->bli_format_count; i++) {
-               xfs_buf_item_format_segment(bip, lv, &vecp, offset,
+               xfs_buf_item_format_segment(bip, lfb, offset,
                                            &bip->bli_formats[i]);
                offset += BBTOB(bp->b_maps[i].bm_len);
        }
index b374cd9f1900341b97ac6b9eee1ed0c668ea8d5b..8bc7f43093a2aa7781a7d4a3069afecdfa185e90 100644 (file)
@@ -44,25 +44,24 @@ xfs_qm_dquot_logitem_size(
 STATIC void
 xfs_qm_dquot_logitem_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_disk_dquot   ddq;
        struct xfs_dq_logitem   *qlip = DQUOT_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
        struct xfs_dq_logformat *qlf;
 
-       qlf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_QFORMAT);
+       qlf = xlog_format_start(lfb, XLOG_REG_TYPE_QFORMAT);
        qlf->qlf_type = XFS_LI_DQUOT;
        qlf->qlf_size = 2;
        qlf->qlf_id = qlip->qli_dquot->q_id;
        qlf->qlf_blkno = qlip->qli_dquot->q_blkno;
        qlf->qlf_len = 1;
        qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
-       xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat));
+       xlog_format_commit(lfb, sizeof(struct xfs_dq_logformat));
 
        xfs_dquot_to_disk(&ddq, qlip->qli_dquot);
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_DQUOT, &ddq,
                        sizeof(struct xfs_disk_dquot));
 }
 
index 229cbe0adf17f8a7bcfc7025c9b4cf8837e9ba70..10d6fbeff651237ad45d339bfdd5815b774c27af 100644 (file)
@@ -83,16 +83,14 @@ xfs_xmi_item_size(
 STATIC void
 xfs_xmi_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_xmi_log_item *xmi_lip = XMI_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        xmi_lip->xmi_format.xmi_type = XFS_LI_XMI;
        xmi_lip->xmi_format.xmi_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_XMI_FORMAT,
-                       &xmi_lip->xmi_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_XMI_FORMAT, &xmi_lip->xmi_format,
                        sizeof(struct xfs_xmi_log_format));
 }
 
@@ -166,15 +164,14 @@ xfs_xmd_item_size(
 STATIC void
 xfs_xmd_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_xmd_log_item *xmd_lip = XMD_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        xmd_lip->xmd_format.xmd_type = XFS_LI_XMD;
        xmd_lip->xmd_format.xmd_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_XMD_FORMAT, &xmd_lip->xmd_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_XMD_FORMAT, &xmd_lip->xmd_format,
                        sizeof(struct xfs_xmd_log_format));
 }
 
index 418ddab590e06b58913de9fbec9d2f01b4243fa3..3d1edc43e6fb07a81a6dad3285ea047299f54541 100644 (file)
@@ -98,10 +98,9 @@ unsigned int xfs_efi_log_space(unsigned int nr)
 STATIC void
 xfs_efi_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_efi_log_item *efip = EFI_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(atomic_read(&efip->efi_next_extent) ==
                                efip->efi_format.efi_nextents);
@@ -110,7 +109,7 @@ xfs_efi_item_format(
        efip->efi_format.efi_type = lip->li_type;
        efip->efi_format.efi_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFI_FORMAT, &efip->efi_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_EFI_FORMAT, &efip->efi_format,
                        xfs_efi_log_format_sizeof(efip->efi_format.efi_nextents));
 }
 
@@ -277,10 +276,9 @@ unsigned int xfs_efd_log_space(unsigned int nr)
 STATIC void
 xfs_efd_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);
        ASSERT(lip->li_type == XFS_LI_EFD || lip->li_type == XFS_LI_EFD_RT);
@@ -288,7 +286,7 @@ xfs_efd_item_format(
        efdp->efd_format.efd_type = lip->li_type;
        efdp->efd_format.efd_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_EFD_FORMAT, &efdp->efd_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_EFD_FORMAT, &efdp->efd_format,
                        xfs_efd_log_format_sizeof(efdp->efd_format.efd_nextents));
 }
 
index f83ec2bd0583c798d75d4dfca78f9589af6eb18d..004dd22393dc7f8fe2f1969c926a78db4cdf1db1 100644 (file)
@@ -49,13 +49,11 @@ xfs_icreate_item_size(
 STATIC void
 xfs_icreate_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_icreate_item *icp = ICR_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_ICREATE,
-                       &icp->ic_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_ICREATE, &icp->ic_format,
                        sizeof(struct xfs_icreate_log));
 }
 
index 2eb0c6011a2e8a08288eefd955bb2cd17b105870..81dfe70e173d557082fba32237fc0c7b7b6925e7 100644 (file)
@@ -336,8 +336,7 @@ STATIC void
 xfs_inode_item_format_data_fork(
        struct xfs_inode_log_item *iip,
        struct xfs_inode_log_format *ilf,
-       struct xfs_log_vec      *lv,
-       struct xfs_log_iovec    **vecp)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_inode        *ip = iip->ili_inode;
        size_t                  data_bytes;
@@ -354,9 +353,9 @@ xfs_inode_item_format_data_fork(
 
                        ASSERT(xfs_iext_count(&ip->i_df) > 0);
 
-                       p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IEXT);
+                       p = xlog_format_start(lfb, XLOG_REG_TYPE_IEXT);
                        data_bytes = xfs_iextents_copy(ip, p, XFS_DATA_FORK);
-                       xlog_finish_iovec(lv, *vecp, data_bytes);
+                       xlog_format_commit(lfb, data_bytes);
 
                        ASSERT(data_bytes <= ip->i_df.if_bytes);
 
@@ -374,7 +373,7 @@ xfs_inode_item_format_data_fork(
                if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
                    ip->i_df.if_broot_bytes > 0) {
                        ASSERT(ip->i_df.if_broot != NULL);
-                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IBROOT,
+                       xlog_format_copy(lfb, XLOG_REG_TYPE_IBROOT,
                                        ip->i_df.if_broot,
                                        ip->i_df.if_broot_bytes);
                        ilf->ilf_dsize = ip->i_df.if_broot_bytes;
@@ -392,8 +391,9 @@ xfs_inode_item_format_data_fork(
                    ip->i_df.if_bytes > 0) {
                        ASSERT(ip->i_df.if_data != NULL);
                        ASSERT(ip->i_disk_size > 0);
-                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_ILOCAL,
-                                       ip->i_df.if_data, ip->i_df.if_bytes);
+                       xlog_format_copy(lfb, XLOG_REG_TYPE_ILOCAL,
+                                       ip->i_df.if_data,
+                                       ip->i_df.if_bytes);
                        ilf->ilf_dsize = (unsigned)ip->i_df.if_bytes;
                        ilf->ilf_size++;
                } else {
@@ -416,8 +416,7 @@ STATIC void
 xfs_inode_item_format_attr_fork(
        struct xfs_inode_log_item *iip,
        struct xfs_inode_log_format *ilf,
-       struct xfs_log_vec      *lv,
-       struct xfs_log_iovec    **vecp)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_inode        *ip = iip->ili_inode;
        size_t                  data_bytes;
@@ -435,9 +434,9 @@ xfs_inode_item_format_attr_fork(
                        ASSERT(xfs_iext_count(&ip->i_af) ==
                                ip->i_af.if_nextents);
 
-                       p = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_EXT);
+                       p = xlog_format_start(lfb, XLOG_REG_TYPE_IATTR_EXT);
                        data_bytes = xfs_iextents_copy(ip, p, XFS_ATTR_FORK);
-                       xlog_finish_iovec(lv, *vecp, data_bytes);
+                       xlog_format_commit(lfb, data_bytes);
 
                        ilf->ilf_asize = data_bytes;
                        ilf->ilf_size++;
@@ -453,7 +452,7 @@ xfs_inode_item_format_attr_fork(
                    ip->i_af.if_broot_bytes > 0) {
                        ASSERT(ip->i_af.if_broot != NULL);
 
-                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_BROOT,
+                       xlog_format_copy(lfb, XLOG_REG_TYPE_IATTR_BROOT,
                                        ip->i_af.if_broot,
                                        ip->i_af.if_broot_bytes);
                        ilf->ilf_asize = ip->i_af.if_broot_bytes;
@@ -469,8 +468,9 @@ xfs_inode_item_format_attr_fork(
                if ((iip->ili_fields & XFS_ILOG_ADATA) &&
                    ip->i_af.if_bytes > 0) {
                        ASSERT(ip->i_af.if_data != NULL);
-                       xlog_copy_iovec(lv, vecp, XLOG_REG_TYPE_IATTR_LOCAL,
-                                       ip->i_af.if_data, ip->i_af.if_bytes);
+                       xlog_format_copy(lfb, XLOG_REG_TYPE_IATTR_LOCAL,
+                                       ip->i_af.if_data,
+                                       ip->i_af.if_bytes);
                        ilf->ilf_asize = (unsigned)ip->i_af.if_bytes;
                        ilf->ilf_size++;
                } else {
@@ -619,14 +619,13 @@ xfs_inode_to_log_dinode(
 static void
 xfs_inode_item_format_core(
        struct xfs_inode        *ip,
-       struct xfs_log_vec      *lv,
-       struct xfs_log_iovec    **vecp)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_log_dinode   *dic;
 
-       dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE);
+       dic = xlog_format_start(lfb, XLOG_REG_TYPE_ICORE);
        xfs_inode_to_log_dinode(ip, dic, ip->i_itemp->ili_item.li_lsn);
-       xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_mount));
+       xlog_format_commit(lfb, xfs_log_dinode_size(ip->i_mount));
 }
 
 /*
@@ -644,14 +643,13 @@ xfs_inode_item_format_core(
 STATIC void
 xfs_inode_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_inode_log_item *iip = INODE_ITEM(lip);
        struct xfs_inode        *ip = iip->ili_inode;
-       struct xfs_log_iovec    *vecp = NULL;
        struct xfs_inode_log_format *ilf;
 
-       ilf = xlog_prepare_iovec(lv, &vecp, XLOG_REG_TYPE_IFORMAT);
+       ilf = xlog_format_start(lfb, XLOG_REG_TYPE_IFORMAT);
        ilf->ilf_type = XFS_LI_INODE;
        ilf->ilf_ino = ip->i_ino;
        ilf->ilf_blkno = ip->i_imap.im_blkno;
@@ -668,13 +666,12 @@ xfs_inode_item_format(
        ilf->ilf_asize = 0;
        ilf->ilf_pad = 0;
        memset(&ilf->ilf_u, 0, sizeof(ilf->ilf_u));
+       xlog_format_commit(lfb, sizeof(*ilf));
 
-       xlog_finish_iovec(lv, vecp, sizeof(*ilf));
-
-       xfs_inode_item_format_core(ip, lv, &vecp);
-       xfs_inode_item_format_data_fork(iip, ilf, lv, &vecp);
+       xfs_inode_item_format_core(ip, lfb);
+       xfs_inode_item_format_data_fork(iip, ilf, lfb);
        if (xfs_inode_has_attr_fork(ip)) {
-               xfs_inode_item_format_attr_fork(iip, ilf, lv, &vecp);
+               xfs_inode_item_format_attr_fork(iip, ilf, lfb);
        } else {
                iip->ili_fields &=
                        ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
index 4869eacfde241f34af13e7186ea5bc24f1211936..1d2cdea1e3ac0170e37308195b8fc255f847520c 100644 (file)
@@ -74,62 +74,6 @@ xlog_iclogs_empty(
 static int
 xfs_log_cover(struct xfs_mount *);
 
-/*
- * We need to make sure the buffer pointer returned is naturally aligned for the
- * biggest basic data type we put into it. We have already accounted for this
- * padding when sizing the buffer.
- *
- * However, this padding does not get written into the log, and hence we have to
- * track the space used by the log vectors separately to prevent log space hangs
- * due to inaccurate accounting (i.e. a leak) of the used log space through the
- * CIL context ticket.
- *
- * We also add space for the xlog_op_header that describes this region in the
- * log. This prepends the data region we return to the caller to copy their data
- * into, so do all the static initialisation of the ophdr now. Because the ophdr
- * is not 8 byte aligned, we have to be careful to ensure that we align the
- * start of the buffer such that the region we return to the call is 8 byte
- * aligned and packed against the tail of the ophdr.
- */
-void *
-xlog_prepare_iovec(
-       struct xfs_log_vec      *lv,
-       struct xfs_log_iovec    **vecp,
-       uint                    type)
-{
-       struct xfs_log_iovec    *vec = *vecp;
-       struct xlog_op_header   *oph;
-       uint32_t                len;
-       void                    *buf;
-
-       if (vec) {
-               ASSERT(vec - lv->lv_iovecp < lv->lv_niovecs);
-               vec++;
-       } else {
-               vec = &lv->lv_iovecp[0];
-       }
-
-       len = lv->lv_buf_used + sizeof(struct xlog_op_header);
-       if (!IS_ALIGNED(len, sizeof(uint64_t))) {
-               lv->lv_buf_used = round_up(len, sizeof(uint64_t)) -
-                                       sizeof(struct xlog_op_header);
-       }
-
-       vec->i_type = type;
-       vec->i_addr = lv->lv_buf + lv->lv_buf_used;
-
-       oph = vec->i_addr;
-       oph->oh_clientid = XFS_TRANSACTION;
-       oph->oh_res2 = 0;
-       oph->oh_flags = 0;
-
-       buf = vec->i_addr + sizeof(struct xlog_op_header);
-       ASSERT(IS_ALIGNED((unsigned long)buf, sizeof(uint64_t)));
-
-       *vecp = vec;
-       return buf;
-}
-
 static inline void
 xlog_grant_sub_space(
        struct xlog_grant_head  *head,
index dcc1f44ed68f90d2ae2f153d9d872ad7d46107ee..c4930e925fed90c7664e7ed5b0a5f80ddb6bc68c 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef        __XFS_LOG_H__
 #define __XFS_LOG_H__
 
+struct xlog_format_buf;
 struct xfs_cil_ctx;
 
 struct xfs_log_vec {
@@ -70,58 +71,24 @@ xlog_calc_iovec_len(int len)
        return roundup(len, sizeof(uint32_t));
 }
 
-void *xlog_prepare_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp,
-               uint type);
-
-static inline void
-xlog_finish_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec *vec,
-               int data_len)
-{
-       struct xlog_op_header   *oph = vec->i_addr;
-       int                     len;
-
-       /*
-        * Always round up the length to the correct alignment so callers don't
-        * need to know anything about this log vec layout requirement. This
-        * means we have to zero the area the data to be written does not cover.
-        * This is complicated by fact the payload region is offset into the
-        * logvec region by the opheader that tracks the payload.
-        */
-       len = xlog_calc_iovec_len(data_len);
-       if (len - data_len != 0) {
-               char    *buf = vec->i_addr + sizeof(struct xlog_op_header);
-
-               memset(buf + data_len, 0, len - data_len);
-       }
-
-       /*
-        * The opheader tracks aligned payload length, whilst the logvec tracks
-        * the overall region length.
-        */
-       oph->oh_len = cpu_to_be32(len);
-
-       len += sizeof(struct xlog_op_header);
-       lv->lv_buf_used += len;
-       lv->lv_bytes += len;
-       vec->i_len = len;
-
-       /* Catch buffer overruns */
-       ASSERT((void *)lv->lv_buf + lv->lv_bytes <=
-               (void *)lv + lv->lv_alloc_size);
-}
+void *xlog_format_start(struct xlog_format_buf *lfb, uint16_t type);
+void xlog_format_commit(struct xlog_format_buf *lfb, unsigned int data_len);
 
 /*
  * Copy the amount of data requested by the caller into a new log iovec.
  */
 static inline void *
-xlog_copy_iovec(struct xfs_log_vec *lv, struct xfs_log_iovec **vecp,
-               uint type, void *data, int len)
+xlog_format_copy(
+       struct xlog_format_buf  *lfb,
+       uint16_t                type,
+       void                    *data,
+       unsigned int            len)
 {
        void *buf;
 
-       buf = xlog_prepare_iovec(lv, vecp, type);
+       buf = xlog_format_start(lfb, type);
        memcpy(buf, data, len);
-       xlog_finish_iovec(lv, *vecp, len);
+       xlog_format_commit(lfb, len);
        return buf;
 }
 
index 83aa06e19cfb2bc3746f251a88a7e2c2ece502d4..bc25012ac5c0bd86dda604fba8e0e81c1e59aa68 100644 (file)
@@ -409,6 +409,102 @@ xfs_cil_prepare_item(
                lv->lv_item->li_seq = log->l_cilp->xc_ctx->sequence;
 }
 
+struct xlog_format_buf {
+       struct xfs_log_vec      *lv;
+       unsigned int            idx;
+};
+
+/*
+ * We need to make sure the buffer pointer returned is naturally aligned for the
+ * biggest basic data type we put into it. We have already accounted for this
+ * padding when sizing the buffer.
+ *
+ * However, this padding does not get written into the log, and hence we have to
+ * track the space used by the log vectors separately to prevent log space hangs
+ * due to inaccurate accounting (i.e. a leak) of the used log space through the
+ * CIL context ticket.
+ *
+ * We also add space for the xlog_op_header that describes this region in the
+ * log. This prepends the data region we return to the caller to copy their data
+ * into, so do all the static initialisation of the ophdr now. Because the ophdr
+ * is not 8 byte aligned, we have to be careful to ensure that we align the
+ * start of the buffer such that the region we return to the call is 8 byte
+ * aligned and packed against the tail of the ophdr.
+ */
+void *
+xlog_format_start(
+       struct xlog_format_buf  *lfb,
+       uint16_t                type)
+{
+       struct xfs_log_vec      *lv = lfb->lv;
+       struct xfs_log_iovec    *vec = &lv->lv_iovecp[lfb->idx];
+       struct xlog_op_header   *oph;
+       uint32_t                len;
+       void                    *buf;
+
+       ASSERT(lfb->idx < lv->lv_niovecs);
+
+       len = lv->lv_buf_used + sizeof(struct xlog_op_header);
+       if (!IS_ALIGNED(len, sizeof(uint64_t))) {
+               lv->lv_buf_used = round_up(len, sizeof(uint64_t)) -
+                                       sizeof(struct xlog_op_header);
+       }
+
+       vec->i_type = type;
+       vec->i_addr = lv->lv_buf + lv->lv_buf_used;
+
+       oph = vec->i_addr;
+       oph->oh_clientid = XFS_TRANSACTION;
+       oph->oh_res2 = 0;
+       oph->oh_flags = 0;
+
+       buf = vec->i_addr + sizeof(struct xlog_op_header);
+       ASSERT(IS_ALIGNED((unsigned long)buf, sizeof(uint64_t)));
+       return buf;
+}
+
+void
+xlog_format_commit(
+       struct xlog_format_buf  *lfb,
+       unsigned int            data_len)
+{
+       struct xfs_log_vec      *lv = lfb->lv;
+       struct xfs_log_iovec    *vec = &lv->lv_iovecp[lfb->idx];
+       struct xlog_op_header   *oph = vec->i_addr;
+       int                     len;
+
+       /*
+        * Always round up the length to the correct alignment so callers don't
+        * need to know anything about this log vec layout requirement. This
+        * means we have to zero the area the data to be written does not cover.
+        * This is complicated by fact the payload region is offset into the
+        * logvec region by the opheader that tracks the payload.
+        */
+       len = xlog_calc_iovec_len(data_len);
+       if (len - data_len != 0) {
+               char    *buf = vec->i_addr + sizeof(struct xlog_op_header);
+
+               memset(buf + data_len, 0, len - data_len);
+       }
+
+       /*
+        * The opheader tracks aligned payload length, whilst the logvec tracks
+        * the overall region length.
+        */
+       oph->oh_len = cpu_to_be32(len);
+
+       len += sizeof(struct xlog_op_header);
+       lv->lv_buf_used += len;
+       lv->lv_bytes += len;
+       vec->i_len = len;
+
+       /* Catch buffer overruns */
+       ASSERT((void *)lv->lv_buf + lv->lv_bytes <=
+               (void *)lv + lv->lv_alloc_size);
+
+       lfb->idx++;
+}
+
 /*
  * Format log item into a flat buffers
  *
@@ -454,6 +550,7 @@ xlog_cil_insert_format_items(
        list_for_each_entry(lip, &tp->t_items, li_trans) {
                struct xfs_log_vec *lv = lip->li_lv;
                struct xfs_log_vec *shadow = lip->li_lv_shadow;
+               struct xlog_format_buf lfb = { };
 
                /* Skip items which aren't dirty in this transaction. */
                if (!test_bit(XFS_LI_DIRTY, &lip->li_flags))
@@ -501,8 +598,9 @@ xlog_cil_insert_format_items(
                        lv->lv_item = lip;
                }
 
+               lfb.lv = lv;
                ASSERT(IS_ALIGNED((unsigned long)lv->lv_buf, sizeof(uint64_t)));
-               lip->li_ops->iop_format(lip, lv);
+               lip->li_ops->iop_format(lip, &lfb);
                xfs_cil_prepare_item(log, lip, lv, diff_len);
        }
 }
index 3728234699a233086acfe2ba3ab6dfec3ff8dd22..a41f5b577e22cbc23f4f5c68dffe26fe9b0882f6 100644 (file)
@@ -93,10 +93,9 @@ unsigned int xfs_cui_log_space(unsigned int nr)
 STATIC void
 xfs_cui_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_cui_log_item *cuip = CUI_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(atomic_read(&cuip->cui_next_extent) ==
                        cuip->cui_format.cui_nextents);
@@ -105,7 +104,7 @@ xfs_cui_item_format(
        cuip->cui_format.cui_type = lip->li_type;
        cuip->cui_format.cui_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_CUI_FORMAT, &cuip->cui_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_CUI_FORMAT, &cuip->cui_format,
                        xfs_cui_log_format_sizeof(cuip->cui_format.cui_nextents));
 }
 
@@ -199,17 +198,16 @@ unsigned int xfs_cud_log_space(void)
 STATIC void
 xfs_cud_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_cud_log_item *cudp = CUD_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(lip->li_type == XFS_LI_CUD || lip->li_type == XFS_LI_CUD_RT);
 
        cudp->cud_format.cud_type = lip->li_type;
        cudp->cud_format.cud_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_CUD_FORMAT, &cudp->cud_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_CUD_FORMAT, &cudp->cud_format,
                        sizeof(struct xfs_cud_log_format));
 }
 
index 15f0903f6fd48ca9ca7eba39873ec797d03e896e..8bf04b1011569f0e09d793067790f1e2350218a2 100644 (file)
@@ -92,10 +92,9 @@ unsigned int xfs_rui_log_space(unsigned int nr)
 STATIC void
 xfs_rui_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_rui_log_item *ruip = RUI_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(atomic_read(&ruip->rui_next_extent) ==
                        ruip->rui_format.rui_nextents);
@@ -105,7 +104,7 @@ xfs_rui_item_format(
        ruip->rui_format.rui_type = lip->li_type;
        ruip->rui_format.rui_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUI_FORMAT, &ruip->rui_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_RUI_FORMAT, &ruip->rui_format,
                        xfs_rui_log_format_sizeof(ruip->rui_format.rui_nextents));
 }
 
@@ -200,17 +199,16 @@ unsigned int xfs_rud_log_space(void)
 STATIC void
 xfs_rud_item_format(
        struct xfs_log_item     *lip,
-       struct xfs_log_vec      *lv)
+       struct xlog_format_buf  *lfb)
 {
        struct xfs_rud_log_item *rudp = RUD_ITEM(lip);
-       struct xfs_log_iovec    *vecp = NULL;
 
        ASSERT(lip->li_type == XFS_LI_RUD || lip->li_type == XFS_LI_RUD_RT);
 
        rudp->rud_format.rud_type = lip->li_type;
        rudp->rud_format.rud_size = 1;
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_RUD_FORMAT, &rudp->rud_format,
+       xlog_format_copy(lfb, XLOG_REG_TYPE_RUD_FORMAT, &rudp->rud_format,
                        sizeof(struct xfs_rud_log_format));
 }
 
index 7fb860f645a3a49c7a4f63c620605c21c2cfff8f..8830600b3e72981812a925a25f46d22120be23df 100644 (file)
@@ -9,6 +9,7 @@
 /* kernel only transaction subsystem defines */
 
 struct xlog;
+struct xlog_format_buf;
 struct xfs_buf;
 struct xfs_buftarg;
 struct xfs_efd_log_item;
@@ -70,7 +71,8 @@ struct xfs_log_item {
 struct xfs_item_ops {
        unsigned flags;
        void (*iop_size)(struct xfs_log_item *, int *, int *);
-       void (*iop_format)(struct xfs_log_item *, struct xfs_log_vec *);
+       void (*iop_format)(struct xfs_log_item *lip,
+                       struct xlog_format_buf *lfb);
        void (*iop_pin)(struct xfs_log_item *);
        void (*iop_unpin)(struct xfs_log_item *, int remove);
        uint64_t (*iop_sort)(struct xfs_log_item *lip);