xfs: disentagle EFI release from the extent count
authorBrian Foster <bfoster@redhat.com>
Tue, 18 Aug 2015 23:50:12 +0000 (09:50 +1000)
committerDave Chinner <david@fromorbit.com>
Tue, 18 Aug 2015 23:50:12 +0000 (09:50 +1000)
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>
fs/xfs/xfs_extfree_item.c
fs/xfs/xfs_extfree_item.h
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_trans.h

index adc8f8fdd145ae4c0facfb377b177fdf3a59baeb..6ff738fe331ada29918691a6c8ca51220b352de8 100644 (file)
@@ -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;
index 0ffbce32d5693e05e042de8983c8274942616196..399562eaf4f58aa52f94c33c18ac0fa64e8fc24d 100644 (file)
@@ -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__ */
index 01dd228ca05e315b88feb7afbfaf3e81d728878b..578bc2d7bac8942f2a6c0e611def27fbf9cf9ae2 100644 (file)
@@ -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;
                }
        }
index 3b21b4e5e4678885f0a9197cd073684814a118a4..f48e839334af651c8ce8edea0779d2723fa7f4a9 100644 (file)
@@ -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,