btree_write_buffer.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _BCACHEFS_BTREE_WRITE_BUFFER_H
  3. #define _BCACHEFS_BTREE_WRITE_BUFFER_H
  4. #include "bkey.h"
  5. #include "disk_accounting.h"
  6. static inline bool bch2_btree_write_buffer_should_flush(struct bch_fs *c)
  7. {
  8. struct btree_write_buffer *wb = &c->btree_write_buffer;
  9. return wb->inc.keys.nr + wb->flushing.keys.nr > wb->inc.keys.size / 4;
  10. }
  11. static inline bool bch2_btree_write_buffer_must_wait(struct bch_fs *c)
  12. {
  13. struct btree_write_buffer *wb = &c->btree_write_buffer;
  14. return wb->inc.keys.nr > wb->inc.keys.size * 3 / 4;
  15. }
  16. struct btree_trans;
  17. int bch2_btree_write_buffer_flush_sync(struct btree_trans *);
  18. bool bch2_btree_write_buffer_flush_going_ro(struct bch_fs *);
  19. int bch2_btree_write_buffer_flush_nocheck_rw(struct btree_trans *);
  20. int bch2_btree_write_buffer_tryflush(struct btree_trans *);
  21. struct bkey_buf;
  22. int bch2_btree_write_buffer_maybe_flush(struct btree_trans *, struct bkey_s_c, struct bkey_buf *);
  23. struct journal_keys_to_wb {
  24. struct btree_write_buffer_keys *wb;
  25. size_t room;
  26. u64 seq;
  27. };
  28. static inline int wb_key_cmp(const void *_l, const void *_r)
  29. {
  30. const struct btree_write_buffered_key *l = _l;
  31. const struct btree_write_buffered_key *r = _r;
  32. return cmp_int(l->btree, r->btree) ?: bpos_cmp(l->k.k.p, r->k.k.p);
  33. }
  34. int bch2_accounting_key_to_wb_slowpath(struct bch_fs *,
  35. enum btree_id, struct bkey_i_accounting *);
  36. static inline int bch2_accounting_key_to_wb(struct bch_fs *c,
  37. enum btree_id btree, struct bkey_i_accounting *k)
  38. {
  39. struct btree_write_buffer *wb = &c->btree_write_buffer;
  40. struct btree_write_buffered_key search;
  41. search.btree = btree;
  42. search.k.k.p = k->k.p;
  43. unsigned idx = eytzinger0_find(wb->accounting.data, wb->accounting.nr,
  44. sizeof(wb->accounting.data[0]),
  45. wb_key_cmp, &search);
  46. if (idx >= wb->accounting.nr)
  47. return bch2_accounting_key_to_wb_slowpath(c, btree, k);
  48. struct bkey_i_accounting *dst = bkey_i_to_accounting(&wb->accounting.data[idx].k);
  49. bch2_accounting_accumulate(dst, accounting_i_to_s_c(k));
  50. return 0;
  51. }
  52. int bch2_journal_key_to_wb_slowpath(struct bch_fs *,
  53. struct journal_keys_to_wb *,
  54. enum btree_id, struct bkey_i *);
  55. static inline int __bch2_journal_key_to_wb(struct bch_fs *c,
  56. struct journal_keys_to_wb *dst,
  57. enum btree_id btree, struct bkey_i *k)
  58. {
  59. if (unlikely(!dst->room))
  60. return bch2_journal_key_to_wb_slowpath(c, dst, btree, k);
  61. struct btree_write_buffered_key *wb_k = &darray_top(dst->wb->keys);
  62. wb_k->journal_seq = dst->seq;
  63. wb_k->btree = btree;
  64. bkey_copy(&wb_k->k, k);
  65. dst->wb->keys.nr++;
  66. dst->room--;
  67. return 0;
  68. }
  69. static inline int bch2_journal_key_to_wb(struct bch_fs *c,
  70. struct journal_keys_to_wb *dst,
  71. enum btree_id btree, struct bkey_i *k)
  72. {
  73. EBUG_ON(!dst->seq);
  74. return k->k.type == KEY_TYPE_accounting
  75. ? bch2_accounting_key_to_wb(c, btree, bkey_i_to_accounting(k))
  76. : __bch2_journal_key_to_wb(c, dst, btree, k);
  77. }
  78. void bch2_journal_keys_to_write_buffer_start(struct bch_fs *, struct journal_keys_to_wb *, u64);
  79. int bch2_journal_keys_to_write_buffer_end(struct bch_fs *, struct journal_keys_to_wb *);
  80. int bch2_btree_write_buffer_resize(struct bch_fs *, size_t);
  81. void bch2_fs_btree_write_buffer_exit(struct bch_fs *);
  82. int bch2_fs_btree_write_buffer_init(struct bch_fs *);
  83. #endif /* _BCACHEFS_BTREE_WRITE_BUFFER_H */