From 9ce632a28a41bd9aeeaa3913d95b23648a82c2ee Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 28 Jun 2019 19:27:32 -0700 Subject: [PATCH] xfs: add a flag to release log items on commit We have various items that are released from ->iop_comitting. Add a flag to just call ->iop_release from the commit path to avoid tons of boilerplate code. Signed-off-by: Christoph Hellwig Reviewed-by: Brian Foster Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_item.c | 27 +-------------------------- fs/xfs/xfs_extfree_item.c | 27 +-------------------------- fs/xfs/xfs_icreate_item.c | 18 +----------------- fs/xfs/xfs_refcount_item.c | 27 +-------------------------- fs/xfs/xfs_rmap_item.c | 27 +-------------------------- fs/xfs/xfs_trans.c | 6 ++++++ fs/xfs/xfs_trans.h | 7 +++++++ 7 files changed, 18 insertions(+), 121 deletions(-) diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index bb5fff120ef5..6c3c03770b3f 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -209,39 +209,14 @@ xfs_bud_item_release( kmem_zone_free(xfs_bud_zone, budp); } -/* - * When the bud item is committed to disk, all we need to do is delete our - * reference to our partner bui item and then free ourselves. Since we're - * freeing ourselves we must return -1 to keep the transaction code from - * further referencing this item. - */ -STATIC xfs_lsn_t -xfs_bud_item_committed( - struct xfs_log_item *lip, - xfs_lsn_t lsn) -{ - struct xfs_bud_log_item *budp = BUD_ITEM(lip); - - /* - * Drop the BUI reference regardless of whether the BUD has been - * aborted. Once the BUD transaction is constructed, it is the sole - * responsibility of the BUD to release the BUI (even if the BUI is - * aborted due to log I/O error). - */ - xfs_bui_release(budp->bud_buip); - kmem_zone_free(xfs_bud_zone, budp); - - return (xfs_lsn_t)-1; -} - /* * This is the ops vector shared by all bud log items. */ static const struct xfs_item_ops xfs_bud_item_ops = { + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .iop_size = xfs_bud_item_size, .iop_format = xfs_bud_item_format, .iop_release = xfs_bud_item_release, - .iop_committed = xfs_bud_item_committed, }; /* diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 70df19007995..811923231bb7 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -308,39 +308,14 @@ xfs_efd_item_release( xfs_efd_item_free(efdp); } -/* - * When the efd item is committed to disk, all we need to do is delete our - * reference to our partner efi item and then free ourselves. Since we're - * freeing ourselves we must return -1 to keep the transaction code from further - * referencing this item. - */ -STATIC xfs_lsn_t -xfs_efd_item_committed( - struct xfs_log_item *lip, - xfs_lsn_t lsn) -{ - struct xfs_efd_log_item *efdp = EFD_ITEM(lip); - - /* - * Drop the EFI reference regardless of whether the EFD has been - * aborted. Once the EFD transaction is constructed, it is the sole - * responsibility of the EFD to release the EFI (even if the EFI is - * aborted due to log I/O error). - */ - xfs_efi_release(efdp->efd_efip); - xfs_efd_item_free(efdp); - - return (xfs_lsn_t)-1; -} - /* * This is the ops vector shared by all efd log items. */ static const struct xfs_item_ops xfs_efd_item_ops = { + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .iop_size = xfs_efd_item_size, .iop_format = xfs_efd_item_format, .iop_release = xfs_efd_item_release, - .iop_committed = xfs_efd_item_committed, }; /* diff --git a/fs/xfs/xfs_icreate_item.c b/fs/xfs/xfs_icreate_item.c index 9aceb35dce24..ac9918da5f4a 100644 --- a/fs/xfs/xfs_icreate_item.c +++ b/fs/xfs/xfs_icreate_item.c @@ -63,30 +63,14 @@ xfs_icreate_item_release( kmem_zone_free(xfs_icreate_zone, ICR_ITEM(lip)); } -/* - * Because we have ordered buffers being tracked in the AIL for the inode - * creation, we don't need the create item after this. Hence we can free - * the log item and return -1 to tell the caller we're done with the item. - */ -STATIC xfs_lsn_t -xfs_icreate_item_committed( - struct xfs_log_item *lip, - xfs_lsn_t lsn) -{ - struct xfs_icreate_item *icp = ICR_ITEM(lip); - - kmem_zone_free(xfs_icreate_zone, icp); - return (xfs_lsn_t)-1; -} - /* * This is the ops vector shared by all buf log items. */ static const struct xfs_item_ops xfs_icreate_item_ops = { + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .iop_size = xfs_icreate_item_size, .iop_format = xfs_icreate_item_format, .iop_release = xfs_icreate_item_release, - .iop_committed = xfs_icreate_item_committed, }; diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 9f8fb23dcc81..5b03478c5d1f 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -213,39 +213,14 @@ xfs_cud_item_release( kmem_zone_free(xfs_cud_zone, cudp); } -/* - * When the cud item is committed to disk, all we need to do is delete our - * reference to our partner cui item and then free ourselves. Since we're - * freeing ourselves we must return -1 to keep the transaction code from - * further referencing this item. - */ -STATIC xfs_lsn_t -xfs_cud_item_committed( - struct xfs_log_item *lip, - xfs_lsn_t lsn) -{ - struct xfs_cud_log_item *cudp = CUD_ITEM(lip); - - /* - * Drop the CUI reference regardless of whether the CUD has been - * aborted. Once the CUD transaction is constructed, it is the sole - * responsibility of the CUD to release the CUI (even if the CUI is - * aborted due to log I/O error). - */ - xfs_cui_release(cudp->cud_cuip); - kmem_zone_free(xfs_cud_zone, cudp); - - return (xfs_lsn_t)-1; -} - /* * This is the ops vector shared by all cud log items. */ static const struct xfs_item_ops xfs_cud_item_ops = { + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .iop_size = xfs_cud_item_size, .iop_format = xfs_cud_item_format, .iop_release = xfs_cud_item_release, - .iop_committed = xfs_cud_item_committed, }; /* diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c index e907bd169de5..3fbc7c5ffa96 100644 --- a/fs/xfs/xfs_rmap_item.c +++ b/fs/xfs/xfs_rmap_item.c @@ -234,39 +234,14 @@ xfs_rud_item_release( kmem_zone_free(xfs_rud_zone, rudp); } -/* - * When the rud item is committed to disk, all we need to do is delete our - * reference to our partner rui item and then free ourselves. Since we're - * freeing ourselves we must return -1 to keep the transaction code from - * further referencing this item. - */ -STATIC xfs_lsn_t -xfs_rud_item_committed( - struct xfs_log_item *lip, - xfs_lsn_t lsn) -{ - struct xfs_rud_log_item *rudp = RUD_ITEM(lip); - - /* - * Drop the RUI reference regardless of whether the RUD has been - * aborted. Once the RUD transaction is constructed, it is the sole - * responsibility of the RUD to release the RUI (even if the RUI is - * aborted due to log I/O error). - */ - xfs_rui_release(rudp->rud_ruip); - kmem_zone_free(xfs_rud_zone, rudp); - - return (xfs_lsn_t)-1; -} - /* * This is the ops vector shared by all rud log items. */ static const struct xfs_item_ops xfs_rud_item_ops = { + .flags = XFS_ITEM_RELEASE_WHEN_COMMITTED, .iop_size = xfs_rud_item_size, .iop_format = xfs_rud_item_format, .iop_release = xfs_rud_item_release, - .iop_committed = xfs_rud_item_committed, }; /* diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 261c51486d7a..b026f87608ce 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -851,6 +851,12 @@ xfs_trans_committed_bulk( if (aborted) set_bit(XFS_LI_ABORTED, &lip->li_flags); + + if (lip->li_ops->flags & XFS_ITEM_RELEASE_WHEN_COMMITTED) { + lip->li_ops->iop_release(lip); + continue; + } + if (lip->li_ops->iop_committed) item_lsn = lip->li_ops->iop_committed(lip, commit_lsn); else diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 522c1d565aa4..ef5fd5db5350 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -67,6 +67,7 @@ typedef struct xfs_log_item { { (1 << XFS_LI_DIRTY), "DIRTY" } struct xfs_item_ops { + unsigned flags; void (*iop_size)(xfs_log_item_t *, int *, int *); void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *); void (*iop_pin)(xfs_log_item_t *); @@ -78,6 +79,12 @@ struct xfs_item_ops { void (*iop_error)(xfs_log_item_t *, xfs_buf_t *); }; +/* + * Release the log item as soon as committed. This is for items just logging + * intents that never need to be written back in place. + */ +#define XFS_ITEM_RELEASE_WHEN_COMMITTED (1 << 0) + void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item, int type, const struct xfs_item_ops *ops);