diff options
Diffstat (limited to 'fs/xfs/xfs_refcount_item.c')
-rw-r--r-- | fs/xfs/xfs_refcount_item.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c index 7a39f40645f7..15c9393dd7a7 100644 --- a/fs/xfs/xfs_refcount_item.c +++ b/fs/xfs/xfs_refcount_item.c @@ -52,6 +52,25 @@ xfs_cui_item_free( kmem_zone_free(xfs_cui_zone, cuip); } +/* + * Freeing the CUI requires that we remove it from the AIL if it has already + * been placed there. However, the CUI may not yet have been placed in the AIL + * when called by xfs_cui_release() from CUD processing due to the ordering of + * committed vs unpin operations in bulk insert operations. Hence the reference + * count to ensure only the last caller frees the CUI. + */ +void +xfs_cui_release( + struct xfs_cui_log_item *cuip) +{ + ASSERT(atomic_read(&cuip->cui_refcount) > 0); + if (atomic_dec_and_test(&cuip->cui_refcount)) { + xfs_trans_ail_remove(&cuip->cui_item, SHUTDOWN_LOG_IO_ERROR); + xfs_cui_item_free(cuip); + } +} + + STATIC void xfs_cui_item_size( struct xfs_log_item *lip, @@ -141,7 +160,7 @@ xfs_cui_item_unlock( struct xfs_log_item *lip) { if (lip->li_flags & XFS_LI_ABORTED) - xfs_cui_item_free(CUI_ITEM(lip)); + xfs_cui_release(CUI_ITEM(lip)); } /* @@ -211,24 +230,6 @@ xfs_cui_init( return cuip; } -/* - * Freeing the CUI requires that we remove it from the AIL if it has already - * been placed there. However, the CUI may not yet have been placed in the AIL - * when called by xfs_cui_release() from CUD processing due to the ordering of - * committed vs unpin operations in bulk insert operations. Hence the reference - * count to ensure only the last caller frees the CUI. - */ -void -xfs_cui_release( - struct xfs_cui_log_item *cuip) -{ - ASSERT(atomic_read(&cuip->cui_refcount) > 0); - if (atomic_dec_and_test(&cuip->cui_refcount)) { - xfs_trans_ail_remove(&cuip->cui_item, SHUTDOWN_LOG_IO_ERROR); - xfs_cui_item_free(cuip); - } -} - static inline struct xfs_cud_log_item *CUD_ITEM(struct xfs_log_item *lip) { return container_of(lip, struct xfs_cud_log_item, cud_item); |