extent_update.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include "bcachefs.h"
  3. #include "btree_update.h"
  4. #include "btree_update_interior.h"
  5. #include "buckets.h"
  6. #include "debug.h"
  7. #include "extents.h"
  8. #include "extent_update.h"
  9. /*
  10. * This counts the number of iterators to the alloc & ec btrees we'll need
  11. * inserting/removing this extent:
  12. */
  13. static unsigned bch2_bkey_nr_alloc_ptrs(struct bkey_s_c k)
  14. {
  15. struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
  16. const union bch_extent_entry *entry;
  17. unsigned ret = 0, lru = 0;
  18. bkey_extent_entry_for_each(ptrs, entry) {
  19. switch (__extent_entry_type(entry)) {
  20. case BCH_EXTENT_ENTRY_ptr:
  21. /* Might also be updating LRU btree */
  22. if (entry->ptr.cached)
  23. lru++;
  24. fallthrough;
  25. case BCH_EXTENT_ENTRY_stripe_ptr:
  26. ret++;
  27. }
  28. }
  29. /*
  30. * Updating keys in the alloc btree may also update keys in the
  31. * freespace or discard btrees:
  32. */
  33. return lru + ret * 2;
  34. }
  35. static int count_iters_for_insert(struct btree_trans *trans,
  36. struct bkey_s_c k,
  37. unsigned offset,
  38. struct bpos *end,
  39. unsigned *nr_iters,
  40. unsigned max_iters)
  41. {
  42. int ret = 0, ret2 = 0;
  43. if (*nr_iters >= max_iters) {
  44. *end = bpos_min(*end, k.k->p);
  45. ret = 1;
  46. }
  47. switch (k.k->type) {
  48. case KEY_TYPE_extent:
  49. case KEY_TYPE_reflink_v:
  50. *nr_iters += bch2_bkey_nr_alloc_ptrs(k);
  51. if (*nr_iters >= max_iters) {
  52. *end = bpos_min(*end, k.k->p);
  53. ret = 1;
  54. }
  55. break;
  56. case KEY_TYPE_reflink_p: {
  57. struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
  58. u64 idx = le64_to_cpu(p.v->idx);
  59. unsigned sectors = bpos_min(*end, p.k->p).offset -
  60. bkey_start_offset(p.k);
  61. struct btree_iter iter;
  62. struct bkey_s_c r_k;
  63. for_each_btree_key_norestart(trans, iter,
  64. BTREE_ID_reflink, POS(0, idx + offset),
  65. BTREE_ITER_slots, r_k, ret2) {
  66. if (bkey_ge(bkey_start_pos(r_k.k), POS(0, idx + sectors)))
  67. break;
  68. /* extent_update_to_keys(), for the reflink_v update */
  69. *nr_iters += 1;
  70. *nr_iters += 1 + bch2_bkey_nr_alloc_ptrs(r_k);
  71. if (*nr_iters >= max_iters) {
  72. struct bpos pos = bkey_start_pos(k.k);
  73. pos.offset += min_t(u64, k.k->size,
  74. r_k.k->p.offset - idx);
  75. *end = bpos_min(*end, pos);
  76. ret = 1;
  77. break;
  78. }
  79. }
  80. bch2_trans_iter_exit(trans, &iter);
  81. break;
  82. }
  83. }
  84. return ret2 ?: ret;
  85. }
  86. #define EXTENT_ITERS_MAX (BTREE_ITER_INITIAL / 3)
  87. int bch2_extent_atomic_end(struct btree_trans *trans,
  88. struct btree_iter *iter,
  89. struct bkey_i *insert,
  90. struct bpos *end)
  91. {
  92. struct btree_iter copy;
  93. struct bkey_s_c k;
  94. unsigned nr_iters = 0;
  95. int ret;
  96. ret = bch2_btree_iter_traverse(iter);
  97. if (ret)
  98. return ret;
  99. *end = insert->k.p;
  100. /* extent_update_to_keys(): */
  101. nr_iters += 1;
  102. ret = count_iters_for_insert(trans, bkey_i_to_s_c(insert), 0, end,
  103. &nr_iters, EXTENT_ITERS_MAX / 2);
  104. if (ret < 0)
  105. return ret;
  106. bch2_trans_copy_iter(&copy, iter);
  107. for_each_btree_key_upto_continue_norestart(copy, insert->k.p, 0, k, ret) {
  108. unsigned offset = 0;
  109. if (bkey_gt(bkey_start_pos(&insert->k), bkey_start_pos(k.k)))
  110. offset = bkey_start_offset(&insert->k) -
  111. bkey_start_offset(k.k);
  112. /* extent_handle_overwrites(): */
  113. switch (bch2_extent_overlap(&insert->k, k.k)) {
  114. case BCH_EXTENT_OVERLAP_ALL:
  115. case BCH_EXTENT_OVERLAP_FRONT:
  116. nr_iters += 1;
  117. break;
  118. case BCH_EXTENT_OVERLAP_BACK:
  119. case BCH_EXTENT_OVERLAP_MIDDLE:
  120. nr_iters += 2;
  121. break;
  122. }
  123. ret = count_iters_for_insert(trans, k, offset, end,
  124. &nr_iters, EXTENT_ITERS_MAX);
  125. if (ret)
  126. break;
  127. }
  128. bch2_trans_iter_exit(trans, &copy);
  129. return ret < 0 ? ret : 0;
  130. }
  131. int bch2_extent_trim_atomic(struct btree_trans *trans,
  132. struct btree_iter *iter,
  133. struct bkey_i *k)
  134. {
  135. struct bpos end;
  136. int ret;
  137. ret = bch2_extent_atomic_end(trans, iter, k, &end);
  138. if (ret)
  139. return ret;
  140. bch2_cut_back(end, k);
  141. return 0;
  142. }