subpage.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef BTRFS_SUBPAGE_H
  3. #define BTRFS_SUBPAGE_H
  4. #include <linux/spinlock.h>
  5. #include <linux/atomic.h>
  6. #include <linux/sizes.h>
  7. struct address_space;
  8. struct folio;
  9. struct btrfs_fs_info;
  10. /*
  11. * Extra info for subpapge bitmap.
  12. *
  13. * For subpage we pack all uptodate/dirty/writeback/ordered bitmaps into
  14. * one larger bitmap.
  15. *
  16. * This structure records how they are organized in the bitmap:
  17. *
  18. * /- uptodate /- dirty /- ordered
  19. * | | |
  20. * v v v
  21. * |u|u|u|u|........|u|u|d|d|.......|d|d|o|o|.......|o|o|
  22. * |< sectors_per_page >|
  23. *
  24. * Unlike regular macro-like enums, here we do not go upper-case names, as
  25. * these names will be utilized in various macros to define function names.
  26. */
  27. enum {
  28. btrfs_bitmap_nr_uptodate = 0,
  29. btrfs_bitmap_nr_dirty,
  30. btrfs_bitmap_nr_writeback,
  31. btrfs_bitmap_nr_ordered,
  32. btrfs_bitmap_nr_checked,
  33. btrfs_bitmap_nr_locked,
  34. btrfs_bitmap_nr_max
  35. };
  36. /*
  37. * Structure to trace status of each sector inside a page, attached to
  38. * page::private for both data and metadata inodes.
  39. */
  40. struct btrfs_subpage {
  41. /* Common members for both data and metadata pages */
  42. spinlock_t lock;
  43. union {
  44. /*
  45. * Structures only used by metadata
  46. *
  47. * @eb_refs should only be operated under private_lock, as it
  48. * manages whether the subpage can be detached.
  49. */
  50. atomic_t eb_refs;
  51. /*
  52. * Structures only used by data,
  53. *
  54. * How many sectors inside the page is locked.
  55. */
  56. atomic_t nr_locked;
  57. };
  58. unsigned long bitmaps[];
  59. };
  60. enum btrfs_subpage_type {
  61. BTRFS_SUBPAGE_METADATA,
  62. BTRFS_SUBPAGE_DATA,
  63. };
  64. #if PAGE_SIZE > SZ_4K
  65. bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, struct address_space *mapping);
  66. #else
  67. static inline bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info,
  68. struct address_space *mapping)
  69. {
  70. return false;
  71. }
  72. #endif
  73. int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
  74. struct folio *folio, enum btrfs_subpage_type type);
  75. void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, struct folio *folio);
  76. /* Allocate additional data where page represents more than one sector */
  77. struct btrfs_subpage *btrfs_alloc_subpage(const struct btrfs_fs_info *fs_info,
  78. enum btrfs_subpage_type type);
  79. void btrfs_free_subpage(struct btrfs_subpage *subpage);
  80. void btrfs_folio_inc_eb_refs(const struct btrfs_fs_info *fs_info, struct folio *folio);
  81. void btrfs_folio_dec_eb_refs(const struct btrfs_fs_info *fs_info, struct folio *folio);
  82. void btrfs_folio_end_lock(const struct btrfs_fs_info *fs_info,
  83. struct folio *folio, u64 start, u32 len);
  84. void btrfs_folio_set_lock(const struct btrfs_fs_info *fs_info,
  85. struct folio *folio, u64 start, u32 len);
  86. void btrfs_folio_end_lock_bitmap(const struct btrfs_fs_info *fs_info,
  87. struct folio *folio, unsigned long bitmap);
  88. /*
  89. * Template for subpage related operations.
  90. *
  91. * btrfs_subpage_*() are for call sites where the folio has subpage attached and
  92. * the range is ensured to be inside the folio's single page.
  93. *
  94. * btrfs_folio_*() are for call sites where the page can either be subpage
  95. * specific or regular folios. The function will handle both cases.
  96. * But the range still needs to be inside one single page.
  97. *
  98. * btrfs_folio_clamp_*() are similar to btrfs_folio_*(), except the range doesn't
  99. * need to be inside the page. Those functions will truncate the range
  100. * automatically.
  101. */
  102. #define DECLARE_BTRFS_SUBPAGE_OPS(name) \
  103. void btrfs_subpage_set_##name(const struct btrfs_fs_info *fs_info, \
  104. struct folio *folio, u64 start, u32 len); \
  105. void btrfs_subpage_clear_##name(const struct btrfs_fs_info *fs_info, \
  106. struct folio *folio, u64 start, u32 len); \
  107. bool btrfs_subpage_test_##name(const struct btrfs_fs_info *fs_info, \
  108. struct folio *folio, u64 start, u32 len); \
  109. void btrfs_folio_set_##name(const struct btrfs_fs_info *fs_info, \
  110. struct folio *folio, u64 start, u32 len); \
  111. void btrfs_folio_clear_##name(const struct btrfs_fs_info *fs_info, \
  112. struct folio *folio, u64 start, u32 len); \
  113. bool btrfs_folio_test_##name(const struct btrfs_fs_info *fs_info, \
  114. struct folio *folio, u64 start, u32 len); \
  115. void btrfs_folio_clamp_set_##name(const struct btrfs_fs_info *fs_info, \
  116. struct folio *folio, u64 start, u32 len); \
  117. void btrfs_folio_clamp_clear_##name(const struct btrfs_fs_info *fs_info, \
  118. struct folio *folio, u64 start, u32 len); \
  119. bool btrfs_folio_clamp_test_##name(const struct btrfs_fs_info *fs_info, \
  120. struct folio *folio, u64 start, u32 len);
  121. DECLARE_BTRFS_SUBPAGE_OPS(uptodate);
  122. DECLARE_BTRFS_SUBPAGE_OPS(dirty);
  123. DECLARE_BTRFS_SUBPAGE_OPS(writeback);
  124. DECLARE_BTRFS_SUBPAGE_OPS(ordered);
  125. DECLARE_BTRFS_SUBPAGE_OPS(checked);
  126. /*
  127. * Helper for error cleanup, where a folio will have its dirty flag cleared,
  128. * with writeback started and finished.
  129. */
  130. static inline void btrfs_folio_clamp_finish_io(struct btrfs_fs_info *fs_info,
  131. struct folio *locked_folio,
  132. u64 start, u32 len)
  133. {
  134. btrfs_folio_clamp_clear_dirty(fs_info, locked_folio, start, len);
  135. btrfs_folio_clamp_set_writeback(fs_info, locked_folio, start, len);
  136. btrfs_folio_clamp_clear_writeback(fs_info, locked_folio, start, len);
  137. }
  138. bool btrfs_subpage_clear_and_test_dirty(const struct btrfs_fs_info *fs_info,
  139. struct folio *folio, u64 start, u32 len);
  140. void btrfs_folio_assert_not_dirty(const struct btrfs_fs_info *fs_info,
  141. struct folio *folio, u64 start, u32 len);
  142. void btrfs_get_subpage_dirty_bitmap(struct btrfs_fs_info *fs_info,
  143. struct folio *folio,
  144. unsigned long *ret_bitmap);
  145. void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info,
  146. struct folio *folio, u64 start, u32 len);
  147. #endif