xfs_trans_bmap.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Oracle. All Rights Reserved.
  4. * Author: Darrick J. Wong <darrick.wong@oracle.com>
  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_mount.h"
  13. #include "xfs_defer.h"
  14. #include "xfs_trans.h"
  15. #include "xfs_trans_priv.h"
  16. #include "xfs_bmap_item.h"
  17. #include "xfs_alloc.h"
  18. #include "xfs_bmap.h"
  19. #include "xfs_inode.h"
  20. /*
  21. * This routine is called to allocate a "bmap update done"
  22. * log item.
  23. */
  24. struct xfs_bud_log_item *
  25. xfs_trans_get_bud(
  26. struct xfs_trans *tp,
  27. struct xfs_bui_log_item *buip)
  28. {
  29. struct xfs_bud_log_item *budp;
  30. budp = xfs_bud_init(tp->t_mountp, buip);
  31. xfs_trans_add_item(tp, &budp->bud_item);
  32. return budp;
  33. }
  34. /*
  35. * Finish an bmap update and log it to the BUD. Note that the
  36. * transaction is marked dirty regardless of whether the bmap update
  37. * succeeds or fails to support the BUI/BUD lifecycle rules.
  38. */
  39. int
  40. xfs_trans_log_finish_bmap_update(
  41. struct xfs_trans *tp,
  42. struct xfs_bud_log_item *budp,
  43. struct xfs_defer_ops *dop,
  44. enum xfs_bmap_intent_type type,
  45. struct xfs_inode *ip,
  46. int whichfork,
  47. xfs_fileoff_t startoff,
  48. xfs_fsblock_t startblock,
  49. xfs_filblks_t *blockcount,
  50. xfs_exntst_t state)
  51. {
  52. int error;
  53. error = xfs_bmap_finish_one(tp, dop, ip, type, whichfork, startoff,
  54. startblock, blockcount, state);
  55. /*
  56. * Mark the transaction dirty, even on error. This ensures the
  57. * transaction is aborted, which:
  58. *
  59. * 1.) releases the BUI and frees the BUD
  60. * 2.) shuts down the filesystem
  61. */
  62. tp->t_flags |= XFS_TRANS_DIRTY;
  63. set_bit(XFS_LI_DIRTY, &budp->bud_item.li_flags);
  64. return error;
  65. }
  66. /* Sort bmap intents by inode. */
  67. static int
  68. xfs_bmap_update_diff_items(
  69. void *priv,
  70. struct list_head *a,
  71. struct list_head *b)
  72. {
  73. struct xfs_bmap_intent *ba;
  74. struct xfs_bmap_intent *bb;
  75. ba = container_of(a, struct xfs_bmap_intent, bi_list);
  76. bb = container_of(b, struct xfs_bmap_intent, bi_list);
  77. return ba->bi_owner->i_ino - bb->bi_owner->i_ino;
  78. }
  79. /* Get an BUI. */
  80. STATIC void *
  81. xfs_bmap_update_create_intent(
  82. struct xfs_trans *tp,
  83. unsigned int count)
  84. {
  85. struct xfs_bui_log_item *buip;
  86. ASSERT(count == XFS_BUI_MAX_FAST_EXTENTS);
  87. ASSERT(tp != NULL);
  88. buip = xfs_bui_init(tp->t_mountp);
  89. ASSERT(buip != NULL);
  90. /*
  91. * Get a log_item_desc to point at the new item.
  92. */
  93. xfs_trans_add_item(tp, &buip->bui_item);
  94. return buip;
  95. }
  96. /* Set the map extent flags for this mapping. */
  97. static void
  98. xfs_trans_set_bmap_flags(
  99. struct xfs_map_extent *bmap,
  100. enum xfs_bmap_intent_type type,
  101. int whichfork,
  102. xfs_exntst_t state)
  103. {
  104. bmap->me_flags = 0;
  105. switch (type) {
  106. case XFS_BMAP_MAP:
  107. case XFS_BMAP_UNMAP:
  108. bmap->me_flags = type;
  109. break;
  110. default:
  111. ASSERT(0);
  112. }
  113. if (state == XFS_EXT_UNWRITTEN)
  114. bmap->me_flags |= XFS_BMAP_EXTENT_UNWRITTEN;
  115. if (whichfork == XFS_ATTR_FORK)
  116. bmap->me_flags |= XFS_BMAP_EXTENT_ATTR_FORK;
  117. }
  118. /* Log bmap updates in the intent item. */
  119. STATIC void
  120. xfs_bmap_update_log_item(
  121. struct xfs_trans *tp,
  122. void *intent,
  123. struct list_head *item)
  124. {
  125. struct xfs_bui_log_item *buip = intent;
  126. struct xfs_bmap_intent *bmap;
  127. uint next_extent;
  128. struct xfs_map_extent *map;
  129. bmap = container_of(item, struct xfs_bmap_intent, bi_list);
  130. tp->t_flags |= XFS_TRANS_DIRTY;
  131. set_bit(XFS_LI_DIRTY, &buip->bui_item.li_flags);
  132. /*
  133. * atomic_inc_return gives us the value after the increment;
  134. * we want to use it as an array index so we need to subtract 1 from
  135. * it.
  136. */
  137. next_extent = atomic_inc_return(&buip->bui_next_extent) - 1;
  138. ASSERT(next_extent < buip->bui_format.bui_nextents);
  139. map = &buip->bui_format.bui_extents[next_extent];
  140. map->me_owner = bmap->bi_owner->i_ino;
  141. map->me_startblock = bmap->bi_bmap.br_startblock;
  142. map->me_startoff = bmap->bi_bmap.br_startoff;
  143. map->me_len = bmap->bi_bmap.br_blockcount;
  144. xfs_trans_set_bmap_flags(map, bmap->bi_type, bmap->bi_whichfork,
  145. bmap->bi_bmap.br_state);
  146. }
  147. /* Get an BUD so we can process all the deferred rmap updates. */
  148. STATIC void *
  149. xfs_bmap_update_create_done(
  150. struct xfs_trans *tp,
  151. void *intent,
  152. unsigned int count)
  153. {
  154. return xfs_trans_get_bud(tp, intent);
  155. }
  156. /* Process a deferred rmap update. */
  157. STATIC int
  158. xfs_bmap_update_finish_item(
  159. struct xfs_trans *tp,
  160. struct xfs_defer_ops *dop,
  161. struct list_head *item,
  162. void *done_item,
  163. void **state)
  164. {
  165. struct xfs_bmap_intent *bmap;
  166. xfs_filblks_t count;
  167. int error;
  168. bmap = container_of(item, struct xfs_bmap_intent, bi_list);
  169. count = bmap->bi_bmap.br_blockcount;
  170. error = xfs_trans_log_finish_bmap_update(tp, done_item, dop,
  171. bmap->bi_type,
  172. bmap->bi_owner, bmap->bi_whichfork,
  173. bmap->bi_bmap.br_startoff,
  174. bmap->bi_bmap.br_startblock,
  175. &count,
  176. bmap->bi_bmap.br_state);
  177. if (!error && count > 0) {
  178. ASSERT(bmap->bi_type == XFS_BMAP_UNMAP);
  179. bmap->bi_bmap.br_blockcount = count;
  180. return -EAGAIN;
  181. }
  182. kmem_free(bmap);
  183. return error;
  184. }
  185. /* Abort all pending BUIs. */
  186. STATIC void
  187. xfs_bmap_update_abort_intent(
  188. void *intent)
  189. {
  190. xfs_bui_release(intent);
  191. }
  192. /* Cancel a deferred rmap update. */
  193. STATIC void
  194. xfs_bmap_update_cancel_item(
  195. struct list_head *item)
  196. {
  197. struct xfs_bmap_intent *bmap;
  198. bmap = container_of(item, struct xfs_bmap_intent, bi_list);
  199. kmem_free(bmap);
  200. }
  201. static const struct xfs_defer_op_type xfs_bmap_update_defer_type = {
  202. .type = XFS_DEFER_OPS_TYPE_BMAP,
  203. .max_items = XFS_BUI_MAX_FAST_EXTENTS,
  204. .diff_items = xfs_bmap_update_diff_items,
  205. .create_intent = xfs_bmap_update_create_intent,
  206. .abort_intent = xfs_bmap_update_abort_intent,
  207. .log_item = xfs_bmap_update_log_item,
  208. .create_done = xfs_bmap_update_create_done,
  209. .finish_item = xfs_bmap_update_finish_item,
  210. .cancel_item = xfs_bmap_update_cancel_item,
  211. };
  212. /* Register the deferred op type. */
  213. void
  214. xfs_bmap_update_init_defer_op(void)
  215. {
  216. xfs_defer_init_op_type(&xfs_bmap_update_defer_type);
  217. }