move.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _BCACHEFS_MOVE_H
  3. #define _BCACHEFS_MOVE_H
  4. #include "bbpos.h"
  5. #include "bcachefs_ioctl.h"
  6. #include "btree_iter.h"
  7. #include "buckets.h"
  8. #include "data_update.h"
  9. #include "move_types.h"
  10. struct bch_read_bio;
  11. struct moving_context {
  12. struct btree_trans *trans;
  13. struct list_head list;
  14. void *fn;
  15. struct bch_ratelimit *rate;
  16. struct bch_move_stats *stats;
  17. struct write_point_specifier wp;
  18. bool wait_on_copygc;
  19. bool write_error;
  20. /* For waiting on outstanding reads and writes: */
  21. struct closure cl;
  22. struct mutex lock;
  23. struct list_head reads;
  24. struct list_head ios;
  25. /* in flight sectors: */
  26. atomic_t read_sectors;
  27. atomic_t write_sectors;
  28. atomic_t read_ios;
  29. atomic_t write_ios;
  30. wait_queue_head_t wait;
  31. };
  32. #define move_ctxt_wait_event_timeout(_ctxt, _cond, _timeout) \
  33. ({ \
  34. int _ret = 0; \
  35. while (true) { \
  36. bool cond_finished = false; \
  37. bch2_moving_ctxt_do_pending_writes(_ctxt); \
  38. \
  39. if (_cond) \
  40. break; \
  41. bch2_trans_unlock_long((_ctxt)->trans); \
  42. _ret = __wait_event_timeout((_ctxt)->wait, \
  43. bch2_moving_ctxt_next_pending_write(_ctxt) || \
  44. (cond_finished = (_cond)), _timeout); \
  45. if (_ret || ( cond_finished)) \
  46. break; \
  47. } \
  48. _ret; \
  49. })
  50. #define move_ctxt_wait_event(_ctxt, _cond) \
  51. do { \
  52. bool cond_finished = false; \
  53. bch2_moving_ctxt_do_pending_writes(_ctxt); \
  54. \
  55. if (_cond) \
  56. break; \
  57. bch2_trans_unlock_long((_ctxt)->trans); \
  58. __wait_event((_ctxt)->wait, \
  59. bch2_moving_ctxt_next_pending_write(_ctxt) || \
  60. (cond_finished = (_cond))); \
  61. if (cond_finished) \
  62. break; \
  63. } while (1)
  64. typedef bool (*move_pred_fn)(struct bch_fs *, void *, struct bkey_s_c,
  65. struct bch_io_opts *, struct data_update_opts *);
  66. extern const char * const bch2_data_ops_strs[];
  67. void bch2_moving_ctxt_exit(struct moving_context *);
  68. void bch2_moving_ctxt_init(struct moving_context *, struct bch_fs *,
  69. struct bch_ratelimit *, struct bch_move_stats *,
  70. struct write_point_specifier, bool);
  71. struct moving_io *bch2_moving_ctxt_next_pending_write(struct moving_context *);
  72. void bch2_moving_ctxt_do_pending_writes(struct moving_context *);
  73. void bch2_moving_ctxt_flush_all(struct moving_context *);
  74. void bch2_move_ctxt_wait_for_io(struct moving_context *);
  75. int bch2_move_ratelimit(struct moving_context *);
  76. /* Inodes in different snapshots may have different IO options: */
  77. struct snapshot_io_opts_entry {
  78. u32 snapshot;
  79. struct bch_io_opts io_opts;
  80. };
  81. struct per_snapshot_io_opts {
  82. u64 cur_inum;
  83. struct bch_io_opts fs_io_opts;
  84. DARRAY(struct snapshot_io_opts_entry) d;
  85. };
  86. static inline void per_snapshot_io_opts_init(struct per_snapshot_io_opts *io_opts, struct bch_fs *c)
  87. {
  88. memset(io_opts, 0, sizeof(*io_opts));
  89. io_opts->fs_io_opts = bch2_opts_to_inode_opts(c->opts);
  90. }
  91. static inline void per_snapshot_io_opts_exit(struct per_snapshot_io_opts *io_opts)
  92. {
  93. darray_exit(&io_opts->d);
  94. }
  95. struct bch_io_opts *bch2_move_get_io_opts(struct btree_trans *,
  96. struct per_snapshot_io_opts *, struct bkey_s_c);
  97. int bch2_move_get_io_opts_one(struct btree_trans *, struct bch_io_opts *, struct bkey_s_c);
  98. int bch2_scan_old_btree_nodes(struct bch_fs *, struct bch_move_stats *);
  99. int bch2_move_extent(struct moving_context *,
  100. struct move_bucket_in_flight *,
  101. struct btree_iter *,
  102. struct bkey_s_c,
  103. struct bch_io_opts,
  104. struct data_update_opts);
  105. int __bch2_move_data(struct moving_context *,
  106. struct bbpos,
  107. struct bbpos,
  108. move_pred_fn, void *);
  109. int bch2_move_data(struct bch_fs *,
  110. struct bbpos start,
  111. struct bbpos end,
  112. struct bch_ratelimit *,
  113. struct bch_move_stats *,
  114. struct write_point_specifier,
  115. bool,
  116. move_pred_fn, void *);
  117. int bch2_evacuate_bucket(struct moving_context *,
  118. struct move_bucket_in_flight *,
  119. struct bpos, int,
  120. struct data_update_opts);
  121. int bch2_data_job(struct bch_fs *,
  122. struct bch_move_stats *,
  123. struct bch_ioctl_data);
  124. void bch2_move_stats_to_text(struct printbuf *, struct bch_move_stats *);
  125. void bch2_move_stats_exit(struct bch_move_stats *, struct bch_fs *);
  126. void bch2_move_stats_init(struct bch_move_stats *, const char *);
  127. void bch2_fs_moving_ctxts_to_text(struct printbuf *, struct bch_fs *);
  128. void bch2_fs_move_init(struct bch_fs *);
  129. #endif /* _BCACHEFS_MOVE_H */