1 /* SPDX-License-Identifier: GPL-2.0 */ 2 3 #ifndef BTRFS_SUBPAGE_H 4 #define BTRFS_SUBPAGE_H 5 6 #include <linux/spinlock.h> 7 8 /* 9 * Maximum page size we support is 64K, minimum sector size is 4K, u16 bitmap 10 * is sufficient. Regular bitmap_* is not used due to size reasons. 11 */ 12 #define BTRFS_SUBPAGE_BITMAP_SIZE 16 13 14 /* 15 * Structure to trace status of each sector inside a page, attached to 16 * page::private for both data and metadata inodes. 17 */ 18 struct btrfs_subpage { 19 /* Common members for both data and metadata pages */ 20 spinlock_t lock; 21 u16 uptodate_bitmap; 22 u16 error_bitmap; 23 u16 dirty_bitmap; 24 u16 writeback_bitmap; 25 /* 26 * Both data and metadata needs to track how many readers are for the 27 * page. 28 * Data relies on @readers to unlock the page when last reader finished. 29 * While metadata doesn't need page unlock, it needs to prevent 30 * page::private get cleared before the last end_page_read(). 31 */ 32 atomic_t readers; 33 union { 34 /* 35 * Structures only used by metadata 36 * 37 * @eb_refs should only be operated under private_lock, as it 38 * manages whether the subpage can be detached. 39 */ 40 atomic_t eb_refs; 41 /* Structures only used by data */ 42 struct { 43 atomic_t writers; 44 45 /* Tracke pending ordered extent in this sector */ 46 u16 ordered_bitmap; 47 }; 48 }; 49 }; 50 51 enum btrfs_subpage_type { 52 BTRFS_SUBPAGE_METADATA, 53 BTRFS_SUBPAGE_DATA, 54 }; 55 56 int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info, 57 struct page *page, enum btrfs_subpage_type type); 58 void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, 59 struct page *page); 60 61 /* Allocate additional data where page represents more than one sector */ 62 int btrfs_alloc_subpage(const struct btrfs_fs_info *fs_info, 63 struct btrfs_subpage **ret, 64 enum btrfs_subpage_type type); 65 void btrfs_free_subpage(struct btrfs_subpage *subpage); 66 67 void btrfs_page_inc_eb_refs(const struct btrfs_fs_info *fs_info, 68 struct page *page); 69 void btrfs_page_dec_eb_refs(const struct btrfs_fs_info *fs_info, 70 struct page *page); 71 72 void btrfs_subpage_start_reader(const struct btrfs_fs_info *fs_info, 73 struct page *page, u64 start, u32 len); 74 void btrfs_subpage_end_reader(const struct btrfs_fs_info *fs_info, 75 struct page *page, u64 start, u32 len); 76 77 void btrfs_subpage_start_writer(const struct btrfs_fs_info *fs_info, 78 struct page *page, u64 start, u32 len); 79 bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info, 80 struct page *page, u64 start, u32 len); 81 int btrfs_page_start_writer_lock(const struct btrfs_fs_info *fs_info, 82 struct page *page, u64 start, u32 len); 83 void btrfs_page_end_writer_lock(const struct btrfs_fs_info *fs_info, 84 struct page *page, u64 start, u32 len); 85 86 /* 87 * Template for subpage related operations. 88 * 89 * btrfs_subpage_*() are for call sites where the page has subpage attached and 90 * the range is ensured to be inside the page. 91 * 92 * btrfs_page_*() are for call sites where the page can either be subpage 93 * specific or regular page. The function will handle both cases. 94 * But the range still needs to be inside the page. 95 * 96 * btrfs_page_clamp_*() are similar to btrfs_page_*(), except the range doesn't 97 * need to be inside the page. Those functions will truncate the range 98 * automatically. 99 */ 100 #define DECLARE_BTRFS_SUBPAGE_OPS(name) \ 101 void btrfs_subpage_set_##name(const struct btrfs_fs_info *fs_info, \ 102 struct page *page, u64 start, u32 len); \ 103 void btrfs_subpage_clear_##name(const struct btrfs_fs_info *fs_info, \ 104 struct page *page, u64 start, u32 len); \ 105 bool btrfs_subpage_test_##name(const struct btrfs_fs_info *fs_info, \ 106 struct page *page, u64 start, u32 len); \ 107 void btrfs_page_set_##name(const struct btrfs_fs_info *fs_info, \ 108 struct page *page, u64 start, u32 len); \ 109 void btrfs_page_clear_##name(const struct btrfs_fs_info *fs_info, \ 110 struct page *page, u64 start, u32 len); \ 111 bool btrfs_page_test_##name(const struct btrfs_fs_info *fs_info, \ 112 struct page *page, u64 start, u32 len); \ 113 void btrfs_page_clamp_set_##name(const struct btrfs_fs_info *fs_info, \ 114 struct page *page, u64 start, u32 len); \ 115 void btrfs_page_clamp_clear_##name(const struct btrfs_fs_info *fs_info, \ 116 struct page *page, u64 start, u32 len); \ 117 bool btrfs_page_clamp_test_##name(const struct btrfs_fs_info *fs_info, \ 118 struct page *page, u64 start, u32 len); 119 120 DECLARE_BTRFS_SUBPAGE_OPS(uptodate); 121 DECLARE_BTRFS_SUBPAGE_OPS(error); 122 DECLARE_BTRFS_SUBPAGE_OPS(dirty); 123 DECLARE_BTRFS_SUBPAGE_OPS(writeback); 124 DECLARE_BTRFS_SUBPAGE_OPS(ordered); 125 126 bool btrfs_subpage_clear_and_test_dirty(const struct btrfs_fs_info *fs_info, 127 struct page *page, u64 start, u32 len); 128 129 #endif 130