1cac06d84SQu Wenruo /* SPDX-License-Identifier: GPL-2.0 */ 2cac06d84SQu Wenruo 3cac06d84SQu Wenruo #ifndef BTRFS_SUBPAGE_H 4cac06d84SQu Wenruo #define BTRFS_SUBPAGE_H 5cac06d84SQu Wenruo 6cac06d84SQu Wenruo #include <linux/spinlock.h> 7cac06d84SQu Wenruo 8cac06d84SQu Wenruo /* 98481dd80SQu Wenruo * Extra info for subpapge bitmap. 108481dd80SQu Wenruo * 11*2b2553f1SChristoph Hellwig * For subpage we pack all uptodate/dirty/writeback/ordered bitmaps into 128481dd80SQu Wenruo * one larger bitmap. 138481dd80SQu Wenruo * 148481dd80SQu Wenruo * This structure records how they are organized in the bitmap: 158481dd80SQu Wenruo * 16*2b2553f1SChristoph Hellwig * /- uptodate_offset /- dirty_offset /- ordered_offset 178481dd80SQu Wenruo * | | | 188481dd80SQu Wenruo * v v v 19*2b2553f1SChristoph Hellwig * |u|u|u|u|........|u|u|d|d|.......|d|d|o|o|.......|o|o| 208481dd80SQu Wenruo * |<- bitmap_nr_bits ->| 21*2b2553f1SChristoph Hellwig * |<----------------- total_nr_bits ------------------>| 228481dd80SQu Wenruo */ 238481dd80SQu Wenruo struct btrfs_subpage_info { 248481dd80SQu Wenruo /* Number of bits for each bitmap */ 258481dd80SQu Wenruo unsigned int bitmap_nr_bits; 268481dd80SQu Wenruo 278481dd80SQu Wenruo /* Total number of bits for the whole bitmap */ 288481dd80SQu Wenruo unsigned int total_nr_bits; 298481dd80SQu Wenruo 308481dd80SQu Wenruo /* 318481dd80SQu Wenruo * *_start indicates where the bitmap starts, the length is always 328481dd80SQu Wenruo * @bitmap_size, which is calculated from PAGE_SIZE / sectorsize. 338481dd80SQu Wenruo */ 348481dd80SQu Wenruo unsigned int uptodate_offset; 358481dd80SQu Wenruo unsigned int dirty_offset; 368481dd80SQu Wenruo unsigned int writeback_offset; 378481dd80SQu Wenruo unsigned int ordered_offset; 38e4f94347SQu Wenruo unsigned int checked_offset; 398481dd80SQu Wenruo }; 408481dd80SQu Wenruo 418481dd80SQu Wenruo /* 42cac06d84SQu Wenruo * Structure to trace status of each sector inside a page, attached to 43cac06d84SQu Wenruo * page::private for both data and metadata inodes. 44cac06d84SQu Wenruo */ 45cac06d84SQu Wenruo struct btrfs_subpage { 46cac06d84SQu Wenruo /* Common members for both data and metadata pages */ 47cac06d84SQu Wenruo spinlock_t lock; 483d078efaSQu Wenruo /* 493d078efaSQu Wenruo * Both data and metadata needs to track how many readers are for the 503d078efaSQu Wenruo * page. 513d078efaSQu Wenruo * Data relies on @readers to unlock the page when last reader finished. 523d078efaSQu Wenruo * While metadata doesn't need page unlock, it needs to prevent 533d078efaSQu Wenruo * page::private get cleared before the last end_page_read(). 543d078efaSQu Wenruo */ 553d078efaSQu Wenruo atomic_t readers; 56760f991fSQu Wenruo union { 578ff8466dSQu Wenruo /* 588ff8466dSQu Wenruo * Structures only used by metadata 598ff8466dSQu Wenruo * 608ff8466dSQu Wenruo * @eb_refs should only be operated under private_lock, as it 618ff8466dSQu Wenruo * manages whether the subpage can be detached. 628ff8466dSQu Wenruo */ 638ff8466dSQu Wenruo atomic_t eb_refs; 646f17400bSQu Wenruo 6572a69cd0SQu Wenruo /* Structures only used by data */ 6672a69cd0SQu Wenruo atomic_t writers; 6792082d40SQu Wenruo }; 6872a69cd0SQu Wenruo unsigned long bitmaps[]; 69cac06d84SQu Wenruo }; 70cac06d84SQu Wenruo 71cac06d84SQu Wenruo enum btrfs_subpage_type { 72cac06d84SQu Wenruo BTRFS_SUBPAGE_METADATA, 73cac06d84SQu Wenruo BTRFS_SUBPAGE_DATA, 74cac06d84SQu Wenruo }; 75cac06d84SQu Wenruo 76fbca46ebSQu Wenruo bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info, struct page *page); 77fbca46ebSQu Wenruo 788481dd80SQu Wenruo void btrfs_init_subpage_info(struct btrfs_subpage_info *subpage_info, u32 sectorsize); 79cac06d84SQu Wenruo int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info, 80cac06d84SQu Wenruo struct page *page, enum btrfs_subpage_type type); 81cac06d84SQu Wenruo void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, 82cac06d84SQu Wenruo struct page *page); 83cac06d84SQu Wenruo 84760f991fSQu Wenruo /* Allocate additional data where page represents more than one sector */ 85651fb419SQu Wenruo struct btrfs_subpage *btrfs_alloc_subpage(const struct btrfs_fs_info *fs_info, 86760f991fSQu Wenruo enum btrfs_subpage_type type); 87760f991fSQu Wenruo void btrfs_free_subpage(struct btrfs_subpage *subpage); 88760f991fSQu Wenruo 898ff8466dSQu Wenruo void btrfs_page_inc_eb_refs(const struct btrfs_fs_info *fs_info, 908ff8466dSQu Wenruo struct page *page); 918ff8466dSQu Wenruo void btrfs_page_dec_eb_refs(const struct btrfs_fs_info *fs_info, 928ff8466dSQu Wenruo struct page *page); 938ff8466dSQu Wenruo 9492082d40SQu Wenruo void btrfs_subpage_start_reader(const struct btrfs_fs_info *fs_info, 9592082d40SQu Wenruo struct page *page, u64 start, u32 len); 9692082d40SQu Wenruo void btrfs_subpage_end_reader(const struct btrfs_fs_info *fs_info, 9792082d40SQu Wenruo struct page *page, u64 start, u32 len); 9892082d40SQu Wenruo 991e1de387SQu Wenruo void btrfs_subpage_start_writer(const struct btrfs_fs_info *fs_info, 1001e1de387SQu Wenruo struct page *page, u64 start, u32 len); 1011e1de387SQu Wenruo bool btrfs_subpage_end_and_test_writer(const struct btrfs_fs_info *fs_info, 1021e1de387SQu Wenruo struct page *page, u64 start, u32 len); 1031e1de387SQu Wenruo int btrfs_page_start_writer_lock(const struct btrfs_fs_info *fs_info, 1041e1de387SQu Wenruo struct page *page, u64 start, u32 len); 1051e1de387SQu Wenruo void btrfs_page_end_writer_lock(const struct btrfs_fs_info *fs_info, 1061e1de387SQu Wenruo struct page *page, u64 start, u32 len); 1071e1de387SQu Wenruo 108a1d767c1SQu Wenruo /* 109a1d767c1SQu Wenruo * Template for subpage related operations. 110a1d767c1SQu Wenruo * 111a1d767c1SQu Wenruo * btrfs_subpage_*() are for call sites where the page has subpage attached and 112a1d767c1SQu Wenruo * the range is ensured to be inside the page. 113a1d767c1SQu Wenruo * 114a1d767c1SQu Wenruo * btrfs_page_*() are for call sites where the page can either be subpage 115a1d767c1SQu Wenruo * specific or regular page. The function will handle both cases. 116a1d767c1SQu Wenruo * But the range still needs to be inside the page. 11760e2d255SQu Wenruo * 11860e2d255SQu Wenruo * btrfs_page_clamp_*() are similar to btrfs_page_*(), except the range doesn't 11960e2d255SQu Wenruo * need to be inside the page. Those functions will truncate the range 12060e2d255SQu Wenruo * automatically. 121a1d767c1SQu Wenruo */ 122a1d767c1SQu Wenruo #define DECLARE_BTRFS_SUBPAGE_OPS(name) \ 123a1d767c1SQu Wenruo void btrfs_subpage_set_##name(const struct btrfs_fs_info *fs_info, \ 124a1d767c1SQu Wenruo struct page *page, u64 start, u32 len); \ 125a1d767c1SQu Wenruo void btrfs_subpage_clear_##name(const struct btrfs_fs_info *fs_info, \ 126a1d767c1SQu Wenruo struct page *page, u64 start, u32 len); \ 127a1d767c1SQu Wenruo bool btrfs_subpage_test_##name(const struct btrfs_fs_info *fs_info, \ 128a1d767c1SQu Wenruo struct page *page, u64 start, u32 len); \ 129a1d767c1SQu Wenruo void btrfs_page_set_##name(const struct btrfs_fs_info *fs_info, \ 130a1d767c1SQu Wenruo struct page *page, u64 start, u32 len); \ 131a1d767c1SQu Wenruo void btrfs_page_clear_##name(const struct btrfs_fs_info *fs_info, \ 132a1d767c1SQu Wenruo struct page *page, u64 start, u32 len); \ 133a1d767c1SQu Wenruo bool btrfs_page_test_##name(const struct btrfs_fs_info *fs_info, \ 13460e2d255SQu Wenruo struct page *page, u64 start, u32 len); \ 13560e2d255SQu Wenruo void btrfs_page_clamp_set_##name(const struct btrfs_fs_info *fs_info, \ 13660e2d255SQu Wenruo struct page *page, u64 start, u32 len); \ 13760e2d255SQu Wenruo void btrfs_page_clamp_clear_##name(const struct btrfs_fs_info *fs_info, \ 13860e2d255SQu Wenruo struct page *page, u64 start, u32 len); \ 13960e2d255SQu Wenruo bool btrfs_page_clamp_test_##name(const struct btrfs_fs_info *fs_info, \ 140a1d767c1SQu Wenruo struct page *page, u64 start, u32 len); 141a1d767c1SQu Wenruo 142a1d767c1SQu Wenruo DECLARE_BTRFS_SUBPAGE_OPS(uptodate); 143d8a5713eSQu Wenruo DECLARE_BTRFS_SUBPAGE_OPS(dirty); 1443470da3bSQu Wenruo DECLARE_BTRFS_SUBPAGE_OPS(writeback); 1456f17400bSQu Wenruo DECLARE_BTRFS_SUBPAGE_OPS(ordered); 146e4f94347SQu Wenruo DECLARE_BTRFS_SUBPAGE_OPS(checked); 147d8a5713eSQu Wenruo 148d8a5713eSQu Wenruo bool btrfs_subpage_clear_and_test_dirty(const struct btrfs_fs_info *fs_info, 149d8a5713eSQu Wenruo struct page *page, u64 start, u32 len); 150a1d767c1SQu Wenruo 151cc1d0d93SQu Wenruo void btrfs_page_assert_not_dirty(const struct btrfs_fs_info *fs_info, 152cc1d0d93SQu Wenruo struct page *page); 153e55a0de1SQu Wenruo void btrfs_page_unlock_writer(struct btrfs_fs_info *fs_info, struct page *page, 154e55a0de1SQu Wenruo u64 start, u32 len); 15575258f20SQu Wenruo void __cold btrfs_subpage_dump_bitmap(const struct btrfs_fs_info *fs_info, 15675258f20SQu Wenruo struct page *page, u64 start, u32 len); 157cc1d0d93SQu Wenruo 158cac06d84SQu Wenruo #endif 159