ec.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _BCACHEFS_EC_H
  3. #define _BCACHEFS_EC_H
  4. #include "ec_types.h"
  5. #include "buckets_types.h"
  6. #include "extents_types.h"
  7. enum bch_validate_flags;
  8. int bch2_stripe_validate(struct bch_fs *, struct bkey_s_c, enum bch_validate_flags);
  9. void bch2_stripe_to_text(struct printbuf *, struct bch_fs *,
  10. struct bkey_s_c);
  11. int bch2_trigger_stripe(struct btree_trans *, enum btree_id, unsigned,
  12. struct bkey_s_c, struct bkey_s,
  13. enum btree_iter_update_trigger_flags);
  14. #define bch2_bkey_ops_stripe ((struct bkey_ops) { \
  15. .key_validate = bch2_stripe_validate, \
  16. .val_to_text = bch2_stripe_to_text, \
  17. .swab = bch2_ptr_swab, \
  18. .trigger = bch2_trigger_stripe, \
  19. .min_val_size = 8, \
  20. })
  21. static inline unsigned stripe_csums_per_device(const struct bch_stripe *s)
  22. {
  23. return DIV_ROUND_UP(le16_to_cpu(s->sectors),
  24. 1 << s->csum_granularity_bits);
  25. }
  26. static inline unsigned stripe_csum_offset(const struct bch_stripe *s,
  27. unsigned dev, unsigned csum_idx)
  28. {
  29. EBUG_ON(s->csum_type >= BCH_CSUM_NR);
  30. unsigned csum_bytes = bch_crc_bytes[s->csum_type];
  31. return sizeof(struct bch_stripe) +
  32. sizeof(struct bch_extent_ptr) * s->nr_blocks +
  33. (dev * stripe_csums_per_device(s) + csum_idx) * csum_bytes;
  34. }
  35. static inline unsigned stripe_blockcount_offset(const struct bch_stripe *s,
  36. unsigned idx)
  37. {
  38. return stripe_csum_offset(s, s->nr_blocks, 0) +
  39. sizeof(u16) * idx;
  40. }
  41. static inline unsigned stripe_blockcount_get(const struct bch_stripe *s,
  42. unsigned idx)
  43. {
  44. return le16_to_cpup((void *) s + stripe_blockcount_offset(s, idx));
  45. }
  46. static inline void stripe_blockcount_set(struct bch_stripe *s,
  47. unsigned idx, unsigned v)
  48. {
  49. __le16 *p = (void *) s + stripe_blockcount_offset(s, idx);
  50. *p = cpu_to_le16(v);
  51. }
  52. static inline unsigned stripe_val_u64s(const struct bch_stripe *s)
  53. {
  54. return DIV_ROUND_UP(stripe_blockcount_offset(s, s->nr_blocks),
  55. sizeof(u64));
  56. }
  57. static inline void *stripe_csum(struct bch_stripe *s,
  58. unsigned block, unsigned csum_idx)
  59. {
  60. EBUG_ON(block >= s->nr_blocks);
  61. EBUG_ON(csum_idx >= stripe_csums_per_device(s));
  62. return (void *) s + stripe_csum_offset(s, block, csum_idx);
  63. }
  64. static inline struct bch_csum stripe_csum_get(struct bch_stripe *s,
  65. unsigned block, unsigned csum_idx)
  66. {
  67. struct bch_csum csum = { 0 };
  68. memcpy(&csum, stripe_csum(s, block, csum_idx), bch_crc_bytes[s->csum_type]);
  69. return csum;
  70. }
  71. static inline void stripe_csum_set(struct bch_stripe *s,
  72. unsigned block, unsigned csum_idx,
  73. struct bch_csum csum)
  74. {
  75. memcpy(stripe_csum(s, block, csum_idx), &csum, bch_crc_bytes[s->csum_type]);
  76. }
  77. static inline bool __bch2_ptr_matches_stripe(const struct bch_extent_ptr *stripe_ptr,
  78. const struct bch_extent_ptr *data_ptr,
  79. unsigned sectors)
  80. {
  81. return (data_ptr->dev == stripe_ptr->dev ||
  82. data_ptr->dev == BCH_SB_MEMBER_INVALID ||
  83. stripe_ptr->dev == BCH_SB_MEMBER_INVALID) &&
  84. data_ptr->gen == stripe_ptr->gen &&
  85. data_ptr->offset >= stripe_ptr->offset &&
  86. data_ptr->offset < stripe_ptr->offset + sectors;
  87. }
  88. static inline bool bch2_ptr_matches_stripe(const struct bch_stripe *s,
  89. struct extent_ptr_decoded p)
  90. {
  91. unsigned nr_data = s->nr_blocks - s->nr_redundant;
  92. BUG_ON(!p.has_ec);
  93. if (p.ec.block >= nr_data)
  94. return false;
  95. return __bch2_ptr_matches_stripe(&s->ptrs[p.ec.block], &p.ptr,
  96. le16_to_cpu(s->sectors));
  97. }
  98. static inline bool bch2_ptr_matches_stripe_m(const struct gc_stripe *m,
  99. struct extent_ptr_decoded p)
  100. {
  101. unsigned nr_data = m->nr_blocks - m->nr_redundant;
  102. BUG_ON(!p.has_ec);
  103. if (p.ec.block >= nr_data)
  104. return false;
  105. return __bch2_ptr_matches_stripe(&m->ptrs[p.ec.block], &p.ptr,
  106. m->sectors);
  107. }
  108. struct bch_read_bio;
  109. struct ec_stripe_buf {
  110. /* might not be buffering the entire stripe: */
  111. unsigned offset;
  112. unsigned size;
  113. unsigned long valid[BITS_TO_LONGS(BCH_BKEY_PTRS_MAX)];
  114. void *data[BCH_BKEY_PTRS_MAX];
  115. __BKEY_PADDED(key, 255);
  116. };
  117. struct ec_stripe_head;
  118. enum ec_stripe_ref {
  119. STRIPE_REF_io,
  120. STRIPE_REF_stripe,
  121. STRIPE_REF_NR
  122. };
  123. struct ec_stripe_new {
  124. struct bch_fs *c;
  125. struct ec_stripe_head *h;
  126. struct mutex lock;
  127. struct list_head list;
  128. struct hlist_node hash;
  129. u64 idx;
  130. struct closure iodone;
  131. atomic_t ref[STRIPE_REF_NR];
  132. int err;
  133. u8 nr_data;
  134. u8 nr_parity;
  135. bool allocated;
  136. bool pending;
  137. bool have_existing_stripe;
  138. unsigned long blocks_gotten[BITS_TO_LONGS(BCH_BKEY_PTRS_MAX)];
  139. unsigned long blocks_allocated[BITS_TO_LONGS(BCH_BKEY_PTRS_MAX)];
  140. open_bucket_idx_t blocks[BCH_BKEY_PTRS_MAX];
  141. struct disk_reservation res;
  142. struct ec_stripe_buf new_stripe;
  143. struct ec_stripe_buf existing_stripe;
  144. };
  145. struct ec_stripe_head {
  146. struct list_head list;
  147. struct mutex lock;
  148. unsigned disk_label;
  149. unsigned algo;
  150. unsigned redundancy;
  151. enum bch_watermark watermark;
  152. bool insufficient_devs;
  153. unsigned long rw_devs_change_count;
  154. u64 nr_created;
  155. struct bch_devs_mask devs;
  156. unsigned nr_active_devs;
  157. unsigned blocksize;
  158. struct dev_stripe_state block_stripe;
  159. struct dev_stripe_state parity_stripe;
  160. struct ec_stripe_new *s;
  161. };
  162. int bch2_ec_read_extent(struct btree_trans *, struct bch_read_bio *, struct bkey_s_c);
  163. void *bch2_writepoint_ec_buf(struct bch_fs *, struct write_point *);
  164. void bch2_ec_bucket_cancel(struct bch_fs *, struct open_bucket *);
  165. int bch2_ec_stripe_new_alloc(struct bch_fs *, struct ec_stripe_head *);
  166. void bch2_ec_stripe_head_put(struct bch_fs *, struct ec_stripe_head *);
  167. struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *,
  168. unsigned, unsigned, unsigned,
  169. enum bch_watermark, struct closure *);
  170. void bch2_stripes_heap_update(struct bch_fs *, struct stripe *, size_t);
  171. void bch2_stripes_heap_del(struct bch_fs *, struct stripe *, size_t);
  172. void bch2_stripes_heap_insert(struct bch_fs *, struct stripe *, size_t);
  173. void bch2_do_stripe_deletes(struct bch_fs *);
  174. void bch2_ec_do_stripe_creates(struct bch_fs *);
  175. void bch2_ec_stripe_new_free(struct bch_fs *, struct ec_stripe_new *);
  176. static inline void ec_stripe_new_get(struct ec_stripe_new *s,
  177. enum ec_stripe_ref ref)
  178. {
  179. atomic_inc(&s->ref[ref]);
  180. }
  181. static inline void ec_stripe_new_put(struct bch_fs *c, struct ec_stripe_new *s,
  182. enum ec_stripe_ref ref)
  183. {
  184. BUG_ON(atomic_read(&s->ref[ref]) <= 0);
  185. if (atomic_dec_and_test(&s->ref[ref]))
  186. switch (ref) {
  187. case STRIPE_REF_stripe:
  188. bch2_ec_stripe_new_free(c, s);
  189. break;
  190. case STRIPE_REF_io:
  191. bch2_ec_do_stripe_creates(c);
  192. break;
  193. default:
  194. BUG();
  195. }
  196. }
  197. int bch2_dev_remove_stripes(struct bch_fs *, unsigned);
  198. void bch2_ec_stop_dev(struct bch_fs *, struct bch_dev *);
  199. void bch2_fs_ec_stop(struct bch_fs *);
  200. void bch2_fs_ec_flush(struct bch_fs *);
  201. int bch2_stripes_read(struct bch_fs *);
  202. void bch2_stripes_heap_to_text(struct printbuf *, struct bch_fs *);
  203. void bch2_new_stripes_to_text(struct printbuf *, struct bch_fs *);
  204. void bch2_fs_ec_exit(struct bch_fs *);
  205. void bch2_fs_ec_init_early(struct bch_fs *);
  206. int bch2_fs_ec_init(struct bch_fs *);
  207. #endif /* _BCACHEFS_EC_H */