{
struct xfs_mount *mp = tp->t_mountp;
+ if (xfs_efi_is_realtime(xefi)) {
+ *dfpp = xfs_defer_add(tp, &xefi->xefi_list,
+ &xfs_rtextent_free_defer_type);
+ return;
+ }
+
xefi->xefi_pag = xfs_perag_intent_get(mp, xefi->xefi_startblock);
if (xefi->xefi_agresv == XFS_AG_RESV_AGFL)
*dfpp = xfs_defer_add(tp, &xefi->xefi_list,
.cancel_item = xfs_extent_free_cancel_item,
};
+static struct xfs_log_item *
+xfs_rtextent_free_create_intent(
+ struct xfs_trans *tp,
+ struct list_head *items,
+ unsigned int count,
+ bool sort)
+{
+ return NULL;
+}
+
+/* Cancel a free extent. */
+STATIC void
+xfs_rtextent_free_cancel_item(
+ struct list_head *item)
+{
+ struct xfs_extent_free_item *xefi = xefi_entry(item);
+
+ kmem_cache_free(xfs_extfree_item_cache, xefi);
+}
+
+STATIC int
+xfs_rtextent_free_finish_item(
+ struct xfs_trans *tp,
+ struct xfs_log_item *done,
+ struct list_head *item,
+ struct xfs_btree_cur **state)
+{
+ struct xfs_extent_free_item *xefi = xefi_entry(item);
+ int error;
+
+ error = xfs_rtfree_blocks(tp, xefi->xefi_rtg, xefi->xefi_startblock,
+ xefi->xefi_blockcount);
+ if (error != -EAGAIN)
+ xfs_rtextent_free_cancel_item(item);
+ return error;
+}
+
+const struct xfs_defer_op_type xfs_rtextent_free_defer_type = {
+ .name = "rtextent_free",
+ .create_intent = xfs_rtextent_free_create_intent,
+ .abort_intent = xfs_extent_free_abort_intent,
+ .create_done = xfs_extent_free_create_done,
+ .finish_item = xfs_rtextent_free_finish_item,
+ .cancel_item = xfs_rtextent_free_cancel_item,
+};
+
/*
* AGFL blocks are accounted differently in the reserve pools and are not
* inserted into the busy extent list.