Commit 9ce632a2 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent ddf92053
...@@ -209,39 +209,14 @@ xfs_bud_item_release( ...@@ -209,39 +209,14 @@ xfs_bud_item_release(
kmem_zone_free(xfs_bud_zone, budp); 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. * This is the ops vector shared by all bud log items.
*/ */
static const struct xfs_item_ops xfs_bud_item_ops = { static const struct xfs_item_ops xfs_bud_item_ops = {
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
.iop_size = xfs_bud_item_size, .iop_size = xfs_bud_item_size,
.iop_format = xfs_bud_item_format, .iop_format = xfs_bud_item_format,
.iop_release = xfs_bud_item_release, .iop_release = xfs_bud_item_release,
.iop_committed = xfs_bud_item_committed,
}; };
/* /*
......
...@@ -308,39 +308,14 @@ xfs_efd_item_release( ...@@ -308,39 +308,14 @@ xfs_efd_item_release(
xfs_efd_item_free(efdp); 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. * This is the ops vector shared by all efd log items.
*/ */
static const struct xfs_item_ops xfs_efd_item_ops = { static const struct xfs_item_ops xfs_efd_item_ops = {
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
.iop_size = xfs_efd_item_size, .iop_size = xfs_efd_item_size,
.iop_format = xfs_efd_item_format, .iop_format = xfs_efd_item_format,
.iop_release = xfs_efd_item_release, .iop_release = xfs_efd_item_release,
.iop_committed = xfs_efd_item_committed,
}; };
/* /*
......
...@@ -63,30 +63,14 @@ xfs_icreate_item_release( ...@@ -63,30 +63,14 @@ xfs_icreate_item_release(
kmem_zone_free(xfs_icreate_zone, ICR_ITEM(lip)); 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. * This is the ops vector shared by all buf log items.
*/ */
static const struct xfs_item_ops xfs_icreate_item_ops = { static const struct xfs_item_ops xfs_icreate_item_ops = {
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
.iop_size = xfs_icreate_item_size, .iop_size = xfs_icreate_item_size,
.iop_format = xfs_icreate_item_format, .iop_format = xfs_icreate_item_format,
.iop_release = xfs_icreate_item_release, .iop_release = xfs_icreate_item_release,
.iop_committed = xfs_icreate_item_committed,
}; };
......
...@@ -213,39 +213,14 @@ xfs_cud_item_release( ...@@ -213,39 +213,14 @@ xfs_cud_item_release(
kmem_zone_free(xfs_cud_zone, cudp); 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. * This is the ops vector shared by all cud log items.
*/ */
static const struct xfs_item_ops xfs_cud_item_ops = { static const struct xfs_item_ops xfs_cud_item_ops = {
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
.iop_size = xfs_cud_item_size, .iop_size = xfs_cud_item_size,
.iop_format = xfs_cud_item_format, .iop_format = xfs_cud_item_format,
.iop_release = xfs_cud_item_release, .iop_release = xfs_cud_item_release,
.iop_committed = xfs_cud_item_committed,
}; };
/* /*
......
...@@ -234,39 +234,14 @@ xfs_rud_item_release( ...@@ -234,39 +234,14 @@ xfs_rud_item_release(
kmem_zone_free(xfs_rud_zone, rudp); 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. * This is the ops vector shared by all rud log items.
*/ */
static const struct xfs_item_ops xfs_rud_item_ops = { static const struct xfs_item_ops xfs_rud_item_ops = {
.flags = XFS_ITEM_RELEASE_WHEN_COMMITTED,
.iop_size = xfs_rud_item_size, .iop_size = xfs_rud_item_size,
.iop_format = xfs_rud_item_format, .iop_format = xfs_rud_item_format,
.iop_release = xfs_rud_item_release, .iop_release = xfs_rud_item_release,
.iop_committed = xfs_rud_item_committed,
}; };
/* /*
......
...@@ -851,6 +851,12 @@ xfs_trans_committed_bulk( ...@@ -851,6 +851,12 @@ xfs_trans_committed_bulk(
if (aborted) if (aborted)
set_bit(XFS_LI_ABORTED, &lip->li_flags); 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) if (lip->li_ops->iop_committed)
item_lsn = lip->li_ops->iop_committed(lip, commit_lsn); item_lsn = lip->li_ops->iop_committed(lip, commit_lsn);
else else
......
...@@ -67,6 +67,7 @@ typedef struct xfs_log_item { ...@@ -67,6 +67,7 @@ typedef struct xfs_log_item {
{ (1 << XFS_LI_DIRTY), "DIRTY" } { (1 << XFS_LI_DIRTY), "DIRTY" }
struct xfs_item_ops { struct xfs_item_ops {
unsigned flags;
void (*iop_size)(xfs_log_item_t *, int *, int *); void (*iop_size)(xfs_log_item_t *, int *, int *);
void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *); void (*iop_format)(xfs_log_item_t *, struct xfs_log_vec *);
void (*iop_pin)(xfs_log_item_t *); void (*iop_pin)(xfs_log_item_t *);
...@@ -78,6 +79,12 @@ struct xfs_item_ops { ...@@ -78,6 +79,12 @@ struct xfs_item_ops {
void (*iop_error)(xfs_log_item_t *, xfs_buf_t *); 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, void xfs_log_item_init(struct xfs_mount *mp, struct xfs_log_item *item,
int type, const struct xfs_item_ops *ops); int type, const struct xfs_item_ops *ops);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment