aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2015-08-18 19:50:12 -0400
committerDave Chinner <david@fromorbit.com>2015-08-18 19:50:12 -0400
commit5e4b5386a2c29429add601c8cfb45bb10d80c490 (patch)
tree4818a1afca016449215b471dd557d1d3bd62357c
parentbc0195aad0daa2ad5b0d76cce22b167bc3435590 (diff)
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>
-rw-r--r--fs/xfs/xfs_extfree_item.c21
-rw-r--r--fs/xfs/xfs_extfree_item.h1
-rw-r--r--fs/xfs/xfs_log_recover.c2
-rw-r--r--fs/xfs/xfs_trans.h1
4 files changed, 11 insertions, 14 deletions
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index adc8f8fdd145..6ff738fe331a 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -149,7 +149,7 @@ xfs_efi_item_unpin(
149 xfs_efi_item_free(efip); 149 xfs_efi_item_free(efip);
150 return; 150 return;
151 } 151 }
152 __xfs_efi_release(efip); 152 xfs_efi_release(efip);
153} 153}
154 154
155/* 155/*
@@ -307,18 +307,15 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
307 * by this efi item we can free the efi item. 307 * by this efi item we can free the efi item.
308 */ 308 */
309void 309void
310xfs_efi_release(xfs_efi_log_item_t *efip, 310xfs_efi_release(
311 uint nextents) 311 struct xfs_efi_log_item *efip)
312{ 312{
313 ASSERT(atomic_read(&efip->efi_next_extent) >= nextents); 313 /* recovery needs us to drop the EFI reference, too */
314 if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) { 314 if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags))
315 /* recovery needs us to drop the EFI reference, too */
316 if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags))
317 __xfs_efi_release(efip);
318
319 __xfs_efi_release(efip); 315 __xfs_efi_release(efip);
320 /* efip may now have been freed, do not reference it again. */ 316
321 } 317 __xfs_efi_release(efip);
318 /* efip may now have been freed, do not reference it again. */
322} 319}
323 320
324static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip) 321static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
@@ -442,7 +439,7 @@ xfs_efd_item_committed(
442 * EFI got unpinned and freed before the EFD got aborted. 439 * EFI got unpinned and freed before the EFD got aborted.
443 */ 440 */
444 if (!(lip->li_flags & XFS_LI_ABORTED)) 441 if (!(lip->li_flags & XFS_LI_ABORTED))
445 xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents); 442 xfs_efi_release(efdp->efd_efip);
446 443
447 xfs_efd_item_free(efdp); 444 xfs_efd_item_free(efdp);
448 return (xfs_lsn_t)-1; 445 return (xfs_lsn_t)-1;
diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h
index 0ffbce32d569..399562eaf4f5 100644
--- a/fs/xfs/xfs_extfree_item.h
+++ b/fs/xfs/xfs_extfree_item.h
@@ -77,5 +77,6 @@ xfs_efd_log_item_t *xfs_efd_init(struct xfs_mount *, xfs_efi_log_item_t *,
77int xfs_efi_copy_format(xfs_log_iovec_t *buf, 77int xfs_efi_copy_format(xfs_log_iovec_t *buf,
78 xfs_efi_log_format_t *dst_efi_fmt); 78 xfs_efi_log_format_t *dst_efi_fmt);
79void xfs_efi_item_free(xfs_efi_log_item_t *); 79void xfs_efi_item_free(xfs_efi_log_item_t *);
80void xfs_efi_release(struct xfs_efi_log_item *);
80 81
81#endif /* __XFS_EXTFREE_ITEM_H__ */ 82#endif /* __XFS_EXTFREE_ITEM_H__ */
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 01dd228ca05e..578bc2d7bac8 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -3739,7 +3739,7 @@ xlog_recover_process_efi(
3739 * free the memory associated with it. 3739 * free the memory associated with it.
3740 */ 3740 */
3741 set_bit(XFS_EFI_RECOVERED, &efip->efi_flags); 3741 set_bit(XFS_EFI_RECOVERED, &efip->efi_flags);
3742 xfs_efi_release(efip, efip->efi_format.efi_nextents); 3742 xfs_efi_release(efip);
3743 return -EIO; 3743 return -EIO;
3744 } 3744 }
3745 } 3745 }
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 3b21b4e5e467..f48e839334af 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -213,7 +213,6 @@ void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *, uint);
213void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint); 213void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
214void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint); 214void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
215struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint); 215struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint);
216void xfs_efi_release(struct xfs_efi_log_item *, uint);
217void xfs_trans_log_efi_extent(xfs_trans_t *, 216void xfs_trans_log_efi_extent(xfs_trans_t *,
218 struct xfs_efi_log_item *, 217 struct xfs_efi_log_item *,
219 xfs_fsblock_t, 218 xfs_fsblock_t,