xfs_trans_extfree.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2000,2005 Silicon Graphics, Inc.
  4. * All Rights Reserved.
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_log_format.h"
  11. #include "xfs_trans_resv.h"
  12. #include "xfs_bit.h"
  13. #include "xfs_mount.h"
  14. #include "xfs_defer.h"
  15. #include "xfs_trans.h"
  16. #include "xfs_trans_priv.h"
  17. #include "xfs_extfree_item.h"
  18. #include "xfs_alloc.h"
  19. #include "xfs_bmap.h"
  20. #include "xfs_trace.h"
  21. /*
  22. * This routine is called to allocate an "extent free done"
  23. * log item that will hold nextents worth of extents. The
  24. * caller must use all nextents extents, because we are not
  25. * flexible about this at all.
  26. */
  27. struct xfs_efd_log_item *
  28. xfs_trans_get_efd(struct xfs_trans *tp,
  29. struct xfs_efi_log_item *efip,
  30. uint nextents)
  31. {
  32. struct xfs_efd_log_item *efdp;
  33. ASSERT(tp != NULL);
  34. ASSERT(nextents > 0);
  35. efdp = xfs_efd_init(tp->t_mountp, efip, nextents);
  36. ASSERT(efdp != NULL);
  37. /*
  38. * Get a log_item_desc to point at the new item.
  39. */
  40. xfs_trans_add_item(tp, &efdp->efd_item);
  41. return efdp;
  42. }
  43. /*
  44. * Free an extent and log it to the EFD. Note that the transaction is marked
  45. * dirty regardless of whether the extent free succeeds or fails to support the
  46. * EFI/EFD lifecycle rules.
  47. */
  48. int
  49. xfs_trans_free_extent(
  50. struct xfs_trans *tp,
  51. struct xfs_efd_log_item *efdp,
  52. xfs_fsblock_t start_block,
  53. xfs_extlen_t ext_len,
  54. struct xfs_owner_info *oinfo,
  55. bool skip_discard)
  56. {
  57. struct xfs_mount *mp = tp->t_mountp;
  58. uint next_extent;
  59. xfs_agnumber_t agno = XFS_FSB_TO_AGNO(mp, start_block);
  60. xfs_agblock_t agbno = XFS_FSB_TO_AGBNO(mp, start_block);
  61. struct xfs_extent *extp;
  62. int error;
  63. trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno, ext_len);
  64. error = __xfs_free_extent(tp, start_block, ext_len,
  65. oinfo, XFS_AG_RESV_NONE, skip_discard);
  66. /*
  67. * Mark the transaction dirty, even on error. This ensures the
  68. * transaction is aborted, which:
  69. *
  70. * 1.) releases the EFI and frees the EFD
  71. * 2.) shuts down the filesystem
  72. */
  73. tp->t_flags |= XFS_TRANS_DIRTY;
  74. set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
  75. next_extent = efdp->efd_next_extent;
  76. ASSERT(next_extent < efdp->efd_format.efd_nextents);
  77. extp = &(efdp->efd_format.efd_extents[next_extent]);
  78. extp->ext_start = start_block;
  79. extp->ext_len = ext_len;
  80. efdp->efd_next_extent++;
  81. return error;
  82. }
  83. /* Sort bmap items by AG. */
  84. static int
  85. xfs_extent_free_diff_items(
  86. void *priv,
  87. struct list_head *a,
  88. struct list_head *b)
  89. {
  90. struct xfs_mount *mp = priv;
  91. struct xfs_extent_free_item *ra;
  92. struct xfs_extent_free_item *rb;
  93. ra = container_of(a, struct xfs_extent_free_item, xefi_list);
  94. rb = container_of(b, struct xfs_extent_free_item, xefi_list);
  95. return XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
  96. XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
  97. }
  98. /* Get an EFI. */
  99. STATIC void *
  100. xfs_extent_free_create_intent(
  101. struct xfs_trans *tp,
  102. unsigned int count)
  103. {
  104. struct xfs_efi_log_item *efip;
  105. ASSERT(tp != NULL);
  106. ASSERT(count > 0);
  107. efip = xfs_efi_init(tp->t_mountp, count);
  108. ASSERT(efip != NULL);
  109. /*
  110. * Get a log_item_desc to point at the new item.
  111. */
  112. xfs_trans_add_item(tp, &efip->efi_item);
  113. return efip;
  114. }
  115. /* Log a free extent to the intent item. */
  116. STATIC void
  117. xfs_extent_free_log_item(
  118. struct xfs_trans *tp,
  119. void *intent,
  120. struct list_head *item)
  121. {
  122. struct xfs_efi_log_item *efip = intent;
  123. struct xfs_extent_free_item *free;
  124. uint next_extent;
  125. struct xfs_extent *extp;
  126. free = container_of(item, struct xfs_extent_free_item, xefi_list);
  127. tp->t_flags |= XFS_TRANS_DIRTY;
  128. set_bit(XFS_LI_DIRTY, &efip->efi_item.li_flags);
  129. /*
  130. * atomic_inc_return gives us the value after the increment;
  131. * we want to use it as an array index so we need to subtract 1 from
  132. * it.
  133. */
  134. next_extent = atomic_inc_return(&efip->efi_next_extent) - 1;
  135. ASSERT(next_extent < efip->efi_format.efi_nextents);
  136. extp = &efip->efi_format.efi_extents[next_extent];
  137. extp->ext_start = free->xefi_startblock;
  138. extp->ext_len = free->xefi_blockcount;
  139. }
  140. /* Get an EFD so we can process all the free extents. */
  141. STATIC void *
  142. xfs_extent_free_create_done(
  143. struct xfs_trans *tp,
  144. void *intent,
  145. unsigned int count)
  146. {
  147. return xfs_trans_get_efd(tp, intent, count);
  148. }
  149. /* Process a free extent. */
  150. STATIC int
  151. xfs_extent_free_finish_item(
  152. struct xfs_trans *tp,
  153. struct list_head *item,
  154. void *done_item,
  155. void **state)
  156. {
  157. struct xfs_extent_free_item *free;
  158. int error;
  159. free = container_of(item, struct xfs_extent_free_item, xefi_list);
  160. error = xfs_trans_free_extent(tp, done_item,
  161. free->xefi_startblock,
  162. free->xefi_blockcount,
  163. &free->xefi_oinfo, free->xefi_skip_discard);
  164. kmem_free(free);
  165. return error;
  166. }
  167. /* Abort all pending EFIs. */
  168. STATIC void
  169. xfs_extent_free_abort_intent(
  170. void *intent)
  171. {
  172. xfs_efi_release(intent);
  173. }
  174. /* Cancel a free extent. */
  175. STATIC void
  176. xfs_extent_free_cancel_item(
  177. struct list_head *item)
  178. {
  179. struct xfs_extent_free_item *free;
  180. free = container_of(item, struct xfs_extent_free_item, xefi_list);
  181. kmem_free(free);
  182. }
  183. static const struct xfs_defer_op_type xfs_extent_free_defer_type = {
  184. .type = XFS_DEFER_OPS_TYPE_FREE,
  185. .max_items = XFS_EFI_MAX_FAST_EXTENTS,
  186. .diff_items = xfs_extent_free_diff_items,
  187. .create_intent = xfs_extent_free_create_intent,
  188. .abort_intent = xfs_extent_free_abort_intent,
  189. .log_item = xfs_extent_free_log_item,
  190. .create_done = xfs_extent_free_create_done,
  191. .finish_item = xfs_extent_free_finish_item,
  192. .cancel_item = xfs_extent_free_cancel_item,
  193. };
  194. /*
  195. * AGFL blocks are accounted differently in the reserve pools and are not
  196. * inserted into the busy extent list.
  197. */
  198. STATIC int
  199. xfs_agfl_free_finish_item(
  200. struct xfs_trans *tp,
  201. struct list_head *item,
  202. void *done_item,
  203. void **state)
  204. {
  205. struct xfs_mount *mp = tp->t_mountp;
  206. struct xfs_efd_log_item *efdp = done_item;
  207. struct xfs_extent_free_item *free;
  208. struct xfs_extent *extp;
  209. struct xfs_buf *agbp;
  210. int error;
  211. xfs_agnumber_t agno;
  212. xfs_agblock_t agbno;
  213. uint next_extent;
  214. free = container_of(item, struct xfs_extent_free_item, xefi_list);
  215. ASSERT(free->xefi_blockcount == 1);
  216. agno = XFS_FSB_TO_AGNO(mp, free->xefi_startblock);
  217. agbno = XFS_FSB_TO_AGBNO(mp, free->xefi_startblock);
  218. trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, free->xefi_blockcount);
  219. error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
  220. if (!error)
  221. error = xfs_free_agfl_block(tp, agno, agbno, agbp,
  222. &free->xefi_oinfo);
  223. /*
  224. * Mark the transaction dirty, even on error. This ensures the
  225. * transaction is aborted, which:
  226. *
  227. * 1.) releases the EFI and frees the EFD
  228. * 2.) shuts down the filesystem
  229. */
  230. tp->t_flags |= XFS_TRANS_DIRTY;
  231. set_bit(XFS_LI_DIRTY, &efdp->efd_item.li_flags);
  232. next_extent = efdp->efd_next_extent;
  233. ASSERT(next_extent < efdp->efd_format.efd_nextents);
  234. extp = &(efdp->efd_format.efd_extents[next_extent]);
  235. extp->ext_start = free->xefi_startblock;
  236. extp->ext_len = free->xefi_blockcount;
  237. efdp->efd_next_extent++;
  238. kmem_free(free);
  239. return error;
  240. }
  241. /* sub-type with special handling for AGFL deferred frees */
  242. static const struct xfs_defer_op_type xfs_agfl_free_defer_type = {
  243. .type = XFS_DEFER_OPS_TYPE_AGFL_FREE,
  244. .max_items = XFS_EFI_MAX_FAST_EXTENTS,
  245. .diff_items = xfs_extent_free_diff_items,
  246. .create_intent = xfs_extent_free_create_intent,
  247. .abort_intent = xfs_extent_free_abort_intent,
  248. .log_item = xfs_extent_free_log_item,
  249. .create_done = xfs_extent_free_create_done,
  250. .finish_item = xfs_agfl_free_finish_item,
  251. .cancel_item = xfs_extent_free_cancel_item,
  252. };
  253. /* Register the deferred op type. */
  254. void
  255. xfs_extent_free_init_defer_op(void)
  256. {
  257. xfs_defer_init_op_type(&xfs_extent_free_defer_type);
  258. xfs_defer_init_op_type(&xfs_agfl_free_defer_type);
  259. }