{
        struct btrfs_fs_info *fs_info = folio_to_fs_info(folio);
        const u64 folio_start = folio_pos(folio);
-       const unsigned int bitmap_size = fs_info->sectors_per_page;
+       const unsigned int bitmap_size = btrfs_blocks_per_folio(fs_info, folio);
        unsigned int start_bit;
        unsigned int first_zero;
        unsigned int first_set;
        const bool is_subpage = btrfs_is_subpage(fs_info, folio->mapping);
        const u64 page_start = folio_pos(folio);
        const u64 page_end = page_start + folio_size(folio) - 1;
+       const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
        unsigned long delalloc_bitmap = 0;
        /*
         * Save the last found delalloc end. As the delalloc end can go beyond
 
        /* Save the dirty bitmap as our submission bitmap will be a subset of it. */
        if (btrfs_is_subpage(fs_info, inode->vfs_inode.i_mapping)) {
-               ASSERT(fs_info->sectors_per_page > 1);
+               ASSERT(blocks_per_folio > 1);
                btrfs_get_subpage_dirty_bitmap(fs_info, folio, &bio_ctrl->submit_bitmap);
        } else {
                bio_ctrl->submit_bitmap = 1;
        }
 
-       for_each_set_bit(bit, &bio_ctrl->submit_bitmap, fs_info->sectors_per_page) {
+       for_each_set_bit(bit, &bio_ctrl->submit_bitmap, blocks_per_folio) {
                u64 start = page_start + (bit << fs_info->sectorsize_bits);
 
                btrfs_folio_set_lock(fs_info, folio, start, fs_info->sectorsize);
                                             btrfs_root_id(inode->root),
                                             btrfs_ino(inode),
                                             folio_pos(folio),
-                                            fs_info->sectors_per_page,
+                                            blocks_per_folio,
                                             &bio_ctrl->submit_bitmap,
                                             found_start, found_len, ret);
                } else {
                unsigned int bitmap_size = min(
                                (last_finished_delalloc_end - page_start) >>
                                fs_info->sectorsize_bits,
-                               fs_info->sectors_per_page);
+                               blocks_per_folio);
 
                for_each_set_bit(bit, &bio_ctrl->submit_bitmap, bitmap_size)
                        btrfs_mark_ordered_io_finished(inode, folio,
         * If all ranges are submitted asynchronously, we just need to account
         * for them here.
         */
-       if (bitmap_empty(&bio_ctrl->submit_bitmap, fs_info->sectors_per_page)) {
+       if (bitmap_empty(&bio_ctrl->submit_bitmap, blocks_per_folio)) {
                wbc->nr_to_write -= delalloc_to_write;
                return 1;
        }
        bool submitted_io = false;
        bool error = false;
        const u64 folio_start = folio_pos(folio);
+       const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
        u64 cur;
        int bit;
        int ret = 0;
        for (cur = start; cur < start + len; cur += fs_info->sectorsize)
                set_bit((cur - folio_start) >> fs_info->sectorsize_bits, &range_bitmap);
        bitmap_and(&bio_ctrl->submit_bitmap, &bio_ctrl->submit_bitmap, &range_bitmap,
-                  fs_info->sectors_per_page);
+                  blocks_per_folio);
 
        bio_ctrl->end_io_func = end_bbio_data_write;
 
-       for_each_set_bit(bit, &bio_ctrl->submit_bitmap, fs_info->sectors_per_page) {
+       for_each_set_bit(bit, &bio_ctrl->submit_bitmap, blocks_per_folio) {
                cur = folio_pos(folio) + (bit << fs_info->sectorsize_bits);
 
                if (cur >= i_size) {
        size_t pg_offset;
        loff_t i_size = i_size_read(&inode->vfs_inode);
        unsigned long end_index = i_size >> PAGE_SHIFT;
+       const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
 
        trace_extent_writepage(folio, &inode->vfs_inode, bio_ctrl->wbc);
 
                btrfs_err_rl(fs_info,
 "failed to submit blocks, root=%lld inode=%llu folio=%llu submit_bitmap=%*pbl: %d",
                             btrfs_root_id(inode->root), btrfs_ino(inode),
-                            folio_pos(folio), fs_info->sectors_per_page,
+                            folio_pos(folio), blocks_per_folio,
                             &bio_ctrl->submit_bitmap, ret);
 
        bio_ctrl->wbc->nr_to_write--;
        u64 folio_start = folio_pos(folio);
        int bit_start = 0;
        int sectors_per_node = fs_info->nodesize >> fs_info->sectorsize_bits;
+       const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
 
        /* Lock and write each dirty extent buffers in the range */
-       while (bit_start < fs_info->sectors_per_page) {
+       while (bit_start < blocks_per_folio) {
                struct btrfs_subpage *subpage = folio_get_private(folio);
                struct extent_buffer *eb;
                unsigned long flags;
                        break;
                }
                spin_lock_irqsave(&subpage->lock, flags);
-               if (!test_bit(bit_start + btrfs_bitmap_nr_dirty * fs_info->sectors_per_page,
+               if (!test_bit(bit_start + btrfs_bitmap_nr_dirty * blocks_per_folio,
                              subpage->bitmaps)) {
                        spin_unlock_irqrestore(&subpage->lock, flags);
                        spin_unlock(&folio->mapping->i_private_lock);
 
 {
        struct btrfs_subpage *subpage;
 
+       /* For metadata we don't support large folio yet. */
+       ASSERT(!folio_test_large(folio));
+
        /*
         * We have cases like a dummy extent buffer page, which is not mapped
         * and doesn't need to be locked.
        ASSERT(fs_info->sectorsize < PAGE_SIZE);
 
        real_size = struct_size(ret, bitmaps,
-                       BITS_TO_LONGS(btrfs_bitmap_nr_max * fs_info->sectors_per_page));
+                       BITS_TO_LONGS(btrfs_bitmap_nr_max *
+                                     (PAGE_SIZE >> fs_info->sectorsize_bits)));
        ret = kzalloc(real_size, GFP_NOFS);
        if (!ret)
                return ERR_PTR(-ENOMEM);
 
 #define subpage_calc_start_bit(fs_info, folio, name, start, len)       \
 ({                                                                     \
-       unsigned int __start_bit;                                               \
+       unsigned int __start_bit;                                       \
+       const unsigned int blocks_per_folio =                           \
+                          btrfs_blocks_per_folio(fs_info, folio);      \
                                                                        \
        btrfs_subpage_assert(fs_info, folio, start, len);               \
        __start_bit = offset_in_page(start) >> fs_info->sectorsize_bits; \
-       __start_bit += fs_info->sectors_per_page * btrfs_bitmap_nr_##name; \
+       __start_bit += blocks_per_folio * btrfs_bitmap_nr_##name;       \
        __start_bit;                                                    \
 })
 
                                 struct folio *folio, unsigned long bitmap)
 {
        struct btrfs_subpage *subpage = folio_get_private(folio);
-       const int start_bit = fs_info->sectors_per_page * btrfs_bitmap_nr_locked;
+       const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
+       const int start_bit = blocks_per_folio * btrfs_bitmap_nr_locked;
        unsigned long flags;
        bool last = false;
        int cleared = 0;
        }
 
        spin_lock_irqsave(&subpage->lock, flags);
-       for_each_set_bit(bit, &bitmap, fs_info->sectors_per_page) {
+       for_each_set_bit(bit, &bitmap, blocks_per_folio) {
                if (test_and_clear_bit(bit + start_bit, subpage->bitmaps))
                        cleared++;
        }
                folio_unlock(folio);
 }
 
-#define subpage_test_bitmap_all_set(fs_info, subpage, name)            \
+#define subpage_test_bitmap_all_set(fs_info, folio, name)              \
+({                                                                     \
+       struct btrfs_subpage *subpage = folio_get_private(folio);       \
+       const unsigned int blocks_per_folio =                           \
+                               btrfs_blocks_per_folio(fs_info, folio); \
+                                                                       \
        bitmap_test_range_all_set(subpage->bitmaps,                     \
-                       fs_info->sectors_per_page * btrfs_bitmap_nr_##name, \
-                       fs_info->sectors_per_page)
+                       blocks_per_folio * btrfs_bitmap_nr_##name,      \
+                       blocks_per_folio);                              \
+})
 
-#define subpage_test_bitmap_all_zero(fs_info, subpage, name)           \
+#define subpage_test_bitmap_all_zero(fs_info, folio, name)             \
+({                                                                     \
+       struct btrfs_subpage *subpage = folio_get_private(folio);       \
+       const unsigned int blocks_per_folio =                           \
+                               btrfs_blocks_per_folio(fs_info, folio); \
+                                                                       \
        bitmap_test_range_all_zero(subpage->bitmaps,                    \
-                       fs_info->sectors_per_page * btrfs_bitmap_nr_##name, \
-                       fs_info->sectors_per_page)
+                       blocks_per_folio * btrfs_bitmap_nr_##name,      \
+                       blocks_per_folio);                              \
+})
 
 void btrfs_subpage_set_uptodate(const struct btrfs_fs_info *fs_info,
                                struct folio *folio, u64 start, u32 len)
 
        spin_lock_irqsave(&subpage->lock, flags);
        bitmap_set(subpage->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
-       if (subpage_test_bitmap_all_set(fs_info, subpage, uptodate))
+       if (subpage_test_bitmap_all_set(fs_info, folio, uptodate))
                folio_mark_uptodate(folio);
        spin_unlock_irqrestore(&subpage->lock, flags);
 }
 
        spin_lock_irqsave(&subpage->lock, flags);
        bitmap_clear(subpage->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
-       if (subpage_test_bitmap_all_zero(fs_info, subpage, dirty))
+       if (subpage_test_bitmap_all_zero(fs_info, folio, dirty))
                last = true;
        spin_unlock_irqrestore(&subpage->lock, flags);
        return last;
 
        spin_lock_irqsave(&subpage->lock, flags);
        bitmap_clear(subpage->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
-       if (subpage_test_bitmap_all_zero(fs_info, subpage, writeback)) {
+       if (subpage_test_bitmap_all_zero(fs_info, folio, writeback)) {
                ASSERT(folio_test_writeback(folio));
                folio_end_writeback(folio);
        }
 
        spin_lock_irqsave(&subpage->lock, flags);
        bitmap_clear(subpage->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
-       if (subpage_test_bitmap_all_zero(fs_info, subpage, ordered))
+       if (subpage_test_bitmap_all_zero(fs_info, folio, ordered))
                folio_clear_ordered(folio);
        spin_unlock_irqrestore(&subpage->lock, flags);
 }
 
        spin_lock_irqsave(&subpage->lock, flags);
        bitmap_set(subpage->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
-       if (subpage_test_bitmap_all_set(fs_info, subpage, checked))
+       if (subpage_test_bitmap_all_set(fs_info, folio, checked))
                folio_set_checked(folio);
        spin_unlock_irqrestore(&subpage->lock, flags);
 }
 IMPLEMENT_BTRFS_PAGE_OPS(checked, folio_set_checked, folio_clear_checked,
                         folio_test_checked);
 
-#define GET_SUBPAGE_BITMAP(subpage, fs_info, name, dst)                        \
+#define GET_SUBPAGE_BITMAP(fs_info, folio, name, dst)                  \
 {                                                                      \
-       const int sectors_per_page = fs_info->sectors_per_page;         \
+       const unsigned int blocks_per_folio =                           \
+                               btrfs_blocks_per_folio(fs_info, folio); \
+       const struct btrfs_subpage *subpage = folio_get_private(folio); \
                                                                        \
-       ASSERT(sectors_per_page < BITS_PER_LONG);                       \
+       ASSERT(blocks_per_folio < BITS_PER_LONG);                       \
        *dst = bitmap_read(subpage->bitmaps,                            \
-                          sectors_per_page * btrfs_bitmap_nr_##name,   \
-                          sectors_per_page);                           \
+                          blocks_per_folio * btrfs_bitmap_nr_##name,   \
+                          blocks_per_folio);                           \
 }
 
 #define SUBPAGE_DUMP_BITMAP(fs_info, folio, name, start, len)          \
 {                                                                      \
-       const struct btrfs_subpage *subpage = folio_get_private(folio); \
        unsigned long bitmap;                                           \
+       const unsigned int blocks_per_folio =                           \
+                               btrfs_blocks_per_folio(fs_info, folio); \
                                                                        \
-       GET_SUBPAGE_BITMAP(subpage, fs_info, name, &bitmap);            \
+       GET_SUBPAGE_BITMAP(fs_info, folio, name, &bitmap);              \
        btrfs_warn(fs_info,                                             \
        "dumpping bitmap start=%llu len=%u folio=%llu " #name "_bitmap=%*pbl", \
                   start, len, folio_pos(folio),                        \
-                  fs_info->sectors_per_page, &bitmap);                 \
+                  blocks_per_folio, &bitmap);                          \
 }
 
 /*
        }
        bitmap_set(subpage->bitmaps, start_bit, nbits);
        ret = atomic_add_return(nbits, &subpage->nr_locked);
-       ASSERT(ret <= fs_info->sectors_per_page);
+       ASSERT(ret <= btrfs_blocks_per_folio(fs_info, folio));
        spin_unlock_irqrestore(&subpage->lock, flags);
 }
 
                                      struct folio *folio, u64 start, u32 len)
 {
        struct btrfs_subpage *subpage;
-       const u32 sectors_per_page = fs_info->sectors_per_page;
+       const unsigned int blocks_per_folio = btrfs_blocks_per_folio(fs_info, folio);
        unsigned long uptodate_bitmap;
        unsigned long dirty_bitmap;
        unsigned long writeback_bitmap;
        unsigned long flags;
 
        ASSERT(folio_test_private(folio) && folio_get_private(folio));
-       ASSERT(sectors_per_page > 1);
+       ASSERT(blocks_per_folio > 1);
        subpage = folio_get_private(folio);
 
        spin_lock_irqsave(&subpage->lock, flags);
-       GET_SUBPAGE_BITMAP(subpage, fs_info, uptodate, &uptodate_bitmap);
-       GET_SUBPAGE_BITMAP(subpage, fs_info, dirty, &dirty_bitmap);
-       GET_SUBPAGE_BITMAP(subpage, fs_info, writeback, &writeback_bitmap);
-       GET_SUBPAGE_BITMAP(subpage, fs_info, ordered, &ordered_bitmap);
-       GET_SUBPAGE_BITMAP(subpage, fs_info, checked, &checked_bitmap);
-       GET_SUBPAGE_BITMAP(subpage, fs_info, locked, &locked_bitmap);
+       GET_SUBPAGE_BITMAP(fs_info, folio, uptodate, &uptodate_bitmap);
+       GET_SUBPAGE_BITMAP(fs_info, folio, dirty, &dirty_bitmap);
+       GET_SUBPAGE_BITMAP(fs_info, folio, writeback, &writeback_bitmap);
+       GET_SUBPAGE_BITMAP(fs_info, folio, ordered, &ordered_bitmap);
+       GET_SUBPAGE_BITMAP(fs_info, folio, checked, &checked_bitmap);
+       GET_SUBPAGE_BITMAP(fs_info, folio, locked, &locked_bitmap);
        spin_unlock_irqrestore(&subpage->lock, flags);
 
        dump_page(folio_page(folio, 0), "btrfs subpage dump");
        btrfs_warn(fs_info,
 "start=%llu len=%u page=%llu, bitmaps uptodate=%*pbl dirty=%*pbl locked=%*pbl writeback=%*pbl ordered=%*pbl checked=%*pbl",
                    start, len, folio_pos(folio),
-                   sectors_per_page, &uptodate_bitmap,
-                   sectors_per_page, &dirty_bitmap,
-                   sectors_per_page, &locked_bitmap,
-                   sectors_per_page, &writeback_bitmap,
-                   sectors_per_page, &ordered_bitmap,
-                   sectors_per_page, &checked_bitmap);
+                   blocks_per_folio, &uptodate_bitmap,
+                   blocks_per_folio, &dirty_bitmap,
+                   blocks_per_folio, &locked_bitmap,
+                   blocks_per_folio, &writeback_bitmap,
+                   blocks_per_folio, &ordered_bitmap,
+                   blocks_per_folio, &checked_bitmap);
 }
 
 void btrfs_get_subpage_dirty_bitmap(struct btrfs_fs_info *fs_info,
        unsigned long flags;
 
        ASSERT(folio_test_private(folio) && folio_get_private(folio));
-       ASSERT(fs_info->sectors_per_page > 1);
+       ASSERT(btrfs_blocks_per_folio(fs_info, folio) > 1);
        subpage = folio_get_private(folio);
 
        spin_lock_irqsave(&subpage->lock, flags);
-       GET_SUBPAGE_BITMAP(subpage, fs_info, dirty, ret_bitmap);
+       GET_SUBPAGE_BITMAP(fs_info, folio, dirty, ret_bitmap);
        spin_unlock_irqrestore(&subpage->lock, flags);
 }