xfs: disentagle EFI release from the extent count
Release of the EFI either occurs based on the reference count or the extent count. The extent count used is either the count tracked in the EFI or EFD, depending on the particular situation. In either case, the count is initialized to the final value and thus always matches the current efi_next_extent value once the EFI is completely constructed. For example, the EFI extent count is increased as the extents are logged in xfs_bmap_finish() and the full free list is always completely processed. Therefore, the count is guaranteed to be complete once the EFI transaction is committed. The EFD uses the efd_nextents counter to release the EFI. This counter is initialized to the count of the EFI when the EFD is created. Thus the EFD, as currently used, has no concept of partial EFI release based on extent count. Given that the EFI extent count is always released in whole, use of the extent count for reference counting is unnecessary. Remove this level of the API and release the EFI based on the core reference count. The efi_next_extent counter remains because it is still used to track the slot to log the next extent to free. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
bc0195aad0
commit
5e4b5386a2
4 changed files with 11 additions and 14 deletions
|
@ -149,7 +149,7 @@ xfs_efi_item_unpin(
|
|||
xfs_efi_item_free(efip);
|
||||
return;
|
||||
}
|
||||
__xfs_efi_release(efip);
|
||||
xfs_efi_release(efip);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -307,18 +307,15 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
|
|||
* by this efi item we can free the efi item.
|
||||
*/
|
||||
void
|
||||
xfs_efi_release(xfs_efi_log_item_t *efip,
|
||||
uint nextents)
|
||||
xfs_efi_release(
|
||||
struct xfs_efi_log_item *efip)
|
||||
{
|
||||
ASSERT(atomic_read(&efip->efi_next_extent) >= nextents);
|
||||
if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) {
|
||||
/* recovery needs us to drop the EFI reference, too */
|
||||
if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags))
|
||||
__xfs_efi_release(efip);
|
||||
|
||||
/* recovery needs us to drop the EFI reference, too */
|
||||
if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags))
|
||||
__xfs_efi_release(efip);
|
||||
/* efip may now have been freed, do not reference it again. */
|
||||
}
|
||||
|
||||
__xfs_efi_release(efip);
|
||||
/* efip may now have been freed, do not reference it again. */
|
||||
}
|
||||
|
||||
static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
|
||||
|
@ -442,7 +439,7 @@ xfs_efd_item_committed(
|
|||
* EFI got unpinned and freed before the EFD got aborted.
|
||||
*/
|
||||
if (!(lip->li_flags & XFS_LI_ABORTED))
|
||||
xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents);
|
||||
xfs_efi_release(efdp->efd_efip);
|
||||
|
||||
xfs_efd_item_free(efdp);
|
||||
return (xfs_lsn_t)-1;
|
||||
|
|
|
@ -77,5 +77,6 @@ xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
|
|||
int xfs_efi_copy_format(xfs_log_iovec_t *buf,
|
||||
xfs_efi_log_format_t *dst_efi_fmt);
|
||||
void xfs_efi_item_free(xfs_efi_log_item_t *);
|
||||
void xfs_efi_release(struct xfs_efi_log_item *);
|
||||
|
||||
#endif /* __XFS_EXTFREE_ITEM_H__ */
|
||||
|
|
|
@ -3739,7 +3739,7 @@ xlog_recover_process_efi(
|
|||
* free the memory associated with it.
|
||||
*/
|
||||
set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
|
||||
xfs_efi_release(efip, efip->efi_format.efi_nextents);
|
||||
xfs_efi_release(efip);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,7 +213,6 @@ void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
|
|||
void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
|
||||
void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
|
||||
struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint);
|
||||
void xfs_efi_release(struct xfs_efi_log_item *, uint);
|
||||
void xfs_trans_log_efi_extent(xfs_trans_t *,
|
||||
struct xfs_efi_log_item *,
|
||||
xfs_fsblock_t,
|
||||
|
|
Loading…
Reference in a new issue