const void *ptr, unsigned long off)      \
 {                                                                      \
        const unsigned long member_offset = (unsigned long)ptr + off;   \
-       const unsigned long idx = get_eb_page_index(member_offset);     \
-       const unsigned long oip = get_eb_offset_in_page(token->eb,      \
-                                                       member_offset); \
+       const unsigned long idx = get_eb_folio_index(token->eb, member_offset); \
+       const unsigned long oil = get_eb_offset_in_folio(token->eb,     \
+                                                        member_offset);\
+       const int unit_size = folio_size(token->eb->folios[0]);         \
+       const int unit_shift = folio_shift(token->eb->folios[0]);       \
        const int size = sizeof(u##bits);                               \
        u8 lebytes[sizeof(u##bits)];                                    \
-       const int part = PAGE_SIZE - oip;                               \
+       const int part = unit_size - oil;                               \
                                                                        \
        ASSERT(token);                                                  \
        ASSERT(token->kaddr);                                           \
        ASSERT(check_setget_bounds(token->eb, ptr, off, size));         \
        if (token->offset <= member_offset &&                           \
-           member_offset + size <= token->offset + PAGE_SIZE) {        \
-               return get_unaligned_le##bits(token->kaddr + oip);      \
+           member_offset + size <= token->offset + unit_size) {        \
+               return get_unaligned_le##bits(token->kaddr + oil);      \
        }                                                               \
        token->kaddr = folio_address(token->eb->folios[idx]);           \
-       token->offset = idx << PAGE_SHIFT;                              \
-       if (INLINE_EXTENT_BUFFER_PAGES == 1 || oip + size <= PAGE_SIZE ) \
-               return get_unaligned_le##bits(token->kaddr + oip);      \
+       token->offset = idx << unit_shift;                              \
+       if (INLINE_EXTENT_BUFFER_PAGES == 1 || oil + size <= unit_size) \
+               return get_unaligned_le##bits(token->kaddr + oil);      \
                                                                        \
-       memcpy(lebytes, token->kaddr + oip, part);                      \
+       memcpy(lebytes, token->kaddr + oil, part);                      \
        token->kaddr = folio_address(token->eb->folios[idx + 1]);       \
-       token->offset = (idx + 1) << PAGE_SHIFT;                        \
+       token->offset = (idx + 1) << unit_shift;                        \
        memcpy(lebytes + part, token->kaddr, size - part);              \
        return get_unaligned_le##bits(lebytes);                         \
 }                                                                      \
                         const void *ptr, unsigned long off)            \
 {                                                                      \
        const unsigned long member_offset = (unsigned long)ptr + off;   \
-       const unsigned long oip = get_eb_offset_in_page(eb, member_offset); \
-       const unsigned long idx = get_eb_page_index(member_offset);     \
+       const unsigned long idx = get_eb_folio_index(eb, member_offset);\
+       const unsigned long oil = get_eb_offset_in_folio(eb,            \
+                                                        member_offset);\
+       const int unit_size = folio_size(eb->folios[0]);                \
        char *kaddr = folio_address(eb->folios[idx]);                   \
        const int size = sizeof(u##bits);                               \
-       const int part = PAGE_SIZE - oip;                               \
+       const int part = unit_size - oil;                               \
        u8 lebytes[sizeof(u##bits)];                                    \
                                                                        \
        ASSERT(check_setget_bounds(eb, ptr, off, size));                \
-       if (INLINE_EXTENT_BUFFER_PAGES == 1 || oip + size <= PAGE_SIZE) \
-               return get_unaligned_le##bits(kaddr + oip);             \
+       if (INLINE_EXTENT_BUFFER_PAGES == 1 || oil + size <= unit_size) \
+               return get_unaligned_le##bits(kaddr + oil);             \
                                                                        \
-       memcpy(lebytes, kaddr + oip, part);                             \
+       memcpy(lebytes, kaddr + oil, part);                             \
        kaddr = folio_address(eb->folios[idx + 1]);                     \
        memcpy(lebytes + part, kaddr, size - part);                     \
        return get_unaligned_le##bits(lebytes);                         \
                            u##bits val)                                \
 {                                                                      \
        const unsigned long member_offset = (unsigned long)ptr + off;   \
-       const unsigned long idx = get_eb_page_index(member_offset);     \
-       const unsigned long oip = get_eb_offset_in_page(token->eb,      \
-                                                       member_offset); \
+       const unsigned long idx = get_eb_folio_index(token->eb, member_offset); \
+       const unsigned long oil = get_eb_offset_in_folio(token->eb,     \
+                                                        member_offset);\
+       const int unit_size = folio_size(token->eb->folios[0]);         \
+       const int unit_shift = folio_shift(token->eb->folios[0]);       \
        const int size = sizeof(u##bits);                               \
        u8 lebytes[sizeof(u##bits)];                                    \
-       const int part = PAGE_SIZE - oip;                               \
+       const int part = unit_size - oil;                               \
                                                                        \
        ASSERT(token);                                                  \
        ASSERT(token->kaddr);                                           \
        ASSERT(check_setget_bounds(token->eb, ptr, off, size));         \
        if (token->offset <= member_offset &&                           \
-           member_offset + size <= token->offset + PAGE_SIZE) {        \
-               put_unaligned_le##bits(val, token->kaddr + oip);        \
+           member_offset + size <= token->offset + unit_size) {        \
+               put_unaligned_le##bits(val, token->kaddr + oil);        \
                return;                                                 \
        }                                                               \
        token->kaddr = folio_address(token->eb->folios[idx]);           \
-       token->offset = idx << PAGE_SHIFT;                              \
-       if (INLINE_EXTENT_BUFFER_PAGES == 1 || oip + size <= PAGE_SIZE) { \
-               put_unaligned_le##bits(val, token->kaddr + oip);        \
+       token->offset = idx << unit_shift;                              \
+       if (INLINE_EXTENT_BUFFER_PAGES == 1 ||                          \
+           oil + size <= unit_size) {                                  \
+               put_unaligned_le##bits(val, token->kaddr + oil);        \
                return;                                                 \
        }                                                               \
        put_unaligned_le##bits(val, lebytes);                           \
-       memcpy(token->kaddr + oip, lebytes, part);                      \
+       memcpy(token->kaddr + oil, lebytes, part);                      \
        token->kaddr = folio_address(token->eb->folios[idx + 1]);       \
-       token->offset = (idx + 1) << PAGE_SHIFT;                        \
+       token->offset = (idx + 1) << unit_shift;                        \
        memcpy(token->kaddr, lebytes + part, size - part);              \
 }                                                                      \
 void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr,       \
                      unsigned long off, u##bits val)                   \
 {                                                                      \
        const unsigned long member_offset = (unsigned long)ptr + off;   \
-       const unsigned long oip = get_eb_offset_in_page(eb, member_offset); \
-       const unsigned long idx = get_eb_page_index(member_offset);     \
+       const unsigned long idx = get_eb_folio_index(eb, member_offset);\
+       const unsigned long oil = get_eb_offset_in_folio(eb,            \
+                                                        member_offset);\
+       const int unit_size = folio_size(eb->folios[0]);                \
        char *kaddr = folio_address(eb->folios[idx]);                   \
        const int size = sizeof(u##bits);                               \
-       const int part = PAGE_SIZE - oip;                               \
+       const int part = unit_size - oil;                               \
        u8 lebytes[sizeof(u##bits)];                                    \
                                                                        \
        ASSERT(check_setget_bounds(eb, ptr, off, size));                \
-       if (INLINE_EXTENT_BUFFER_PAGES == 1 || oip + size <= PAGE_SIZE) { \
-               put_unaligned_le##bits(val, kaddr + oip);               \
+       if (INLINE_EXTENT_BUFFER_PAGES == 1 ||                          \
+           oil + size <= unit_size) {                                  \
+               put_unaligned_le##bits(val, kaddr + oil);               \
                return;                                                 \
        }                                                               \
                                                                        \
        put_unaligned_le##bits(val, lebytes);                           \
-       memcpy(kaddr + oip, lebytes, part);                             \
+       memcpy(kaddr + oil, lebytes, part);                             \
        kaddr = folio_address(eb->folios[idx + 1]);                     \
        memcpy(kaddr, lebytes + part, size - part);                     \
 }
 
 void read_extent_buffer(const struct extent_buffer *eb, void *dstv,
                        unsigned long start, unsigned long len)
 {
+       const int unit_size = folio_size(eb->folios[0]);
        size_t cur;
        size_t offset;
-       struct page *page;
-       char *kaddr;
        char *dst = (char *)dstv;
-       unsigned long i = get_eb_page_index(start);
+       unsigned long i = get_eb_folio_index(eb, start);
 
        if (check_eb_range(eb, start, len)) {
                /*
                return;
        }
 
-       offset = get_eb_offset_in_page(eb, start);
+       offset = get_eb_offset_in_folio(eb, start);
 
        while (len > 0) {
-               page = folio_page(eb->folios[i], 0);
+               char *kaddr;
 
-               cur = min(len, (PAGE_SIZE - offset));
-               kaddr = page_address(page);
+               cur = min(len, unit_size - offset);
+               kaddr = folio_address(eb->folios[i]);
                memcpy(dst, kaddr + offset, cur);
 
                dst += cur;
                                       void __user *dstv,
                                       unsigned long start, unsigned long len)
 {
+       const int unit_size = folio_size(eb->folios[0]);
        size_t cur;
        size_t offset;
-       struct page *page;
-       char *kaddr;
        char __user *dst = (char __user *)dstv;
-       unsigned long i = get_eb_page_index(start);
+       unsigned long i = get_eb_folio_index(eb, start);
        int ret = 0;
 
        WARN_ON(start > eb->len);
                return ret;
        }
 
-       offset = get_eb_offset_in_page(eb, start);
+       offset = get_eb_offset_in_folio(eb, start);
 
        while (len > 0) {
-               page = folio_page(eb->folios[i], 0);
+               char *kaddr;
 
-               cur = min(len, (PAGE_SIZE - offset));
-               kaddr = page_address(page);
+               cur = min(len, unit_size - offset);
+               kaddr = folio_address(eb->folios[i]);
                if (copy_to_user_nofault(dst, kaddr + offset, cur)) {
                        ret = -EFAULT;
                        break;
 int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv,
                         unsigned long start, unsigned long len)
 {
+       const int unit_size = folio_size(eb->folios[0]);
        size_t cur;
        size_t offset;
-       struct page *page;
        char *kaddr;
        char *ptr = (char *)ptrv;
-       unsigned long i = get_eb_page_index(start);
+       unsigned long i = get_eb_folio_index(eb, start);
        int ret = 0;
 
        if (check_eb_range(eb, start, len))
        if (eb->addr)
                return memcmp(ptrv, eb->addr + start, len);
 
-       offset = get_eb_offset_in_page(eb, start);
+       offset = get_eb_offset_in_folio(eb, start);
 
        while (len > 0) {
-               page = folio_page(eb->folios[i], 0);
-
-               cur = min(len, (PAGE_SIZE - offset));
-
-               kaddr = page_address(page);
+               cur = min(len, unit_size - offset);
+               kaddr = folio_address(eb->folios[i]);
                ret = memcmp(ptr, kaddr + offset, cur);
                if (ret)
                        break;
  * For regular sector size == PAGE_SIZE case, check if @page is uptodate.
  * For subpage case, check if the range covered by the eb has EXTENT_UPTODATE.
  */
-static void assert_eb_page_uptodate(const struct extent_buffer *eb,
-                                   struct page *page)
+static void assert_eb_folio_uptodate(const struct extent_buffer *eb, int i)
 {
        struct btrfs_fs_info *fs_info = eb->fs_info;
+       struct folio *folio = eb->folios[i];
+
+       ASSERT(folio);
 
        /*
         * If we are using the commit root we could potentially clear a page
                return;
 
        if (fs_info->nodesize < PAGE_SIZE) {
+               struct page *page = folio_page(folio, 0);
+
                if (WARN_ON(!btrfs_subpage_test_uptodate(fs_info, page,
                                                         eb->start, eb->len)))
                        btrfs_subpage_dump_bitmap(fs_info, page, eb->start, eb->len);
        } else {
-               WARN_ON(!PageUptodate(page));
+               WARN_ON(!folio_test_uptodate(folio));
        }
 }
 
                                  const void *srcv, unsigned long start,
                                  unsigned long len, bool use_memmove)
 {
+       const int unit_size = folio_size(eb->folios[0]);
        size_t cur;
        size_t offset;
-       struct page *page;
        char *kaddr;
        char *src = (char *)srcv;
-       unsigned long i = get_eb_page_index(start);
+       unsigned long i = get_eb_folio_index(eb, start);
        /* For unmapped (dummy) ebs, no need to check their uptodate status. */
        const bool check_uptodate = !test_bit(EXTENT_BUFFER_UNMAPPED, &eb->bflags);
 
                return;
        }
 
-       offset = get_eb_offset_in_page(eb, start);
+       offset = get_eb_offset_in_folio(eb, start);
 
        while (len > 0) {
-               page = folio_page(eb->folios[i], 0);
                if (check_uptodate)
-                       assert_eb_page_uptodate(eb, page);
+                       assert_eb_folio_uptodate(eb, i);
 
-               cur = min(len, PAGE_SIZE - offset);
-               kaddr = page_address(page);
+               cur = min(len, unit_size - offset);
+               kaddr = folio_address(eb->folios[i]);
                if (use_memmove)
                        memmove(kaddr + offset, src, cur);
                else
 static void memset_extent_buffer(const struct extent_buffer *eb, int c,
                                 unsigned long start, unsigned long len)
 {
+       const int unit_size = folio_size(eb->folios[0]);
        unsigned long cur = start;
 
        if (eb->addr) {
        }
 
        while (cur < start + len) {
-               unsigned long index = get_eb_page_index(cur);
-               unsigned int offset = get_eb_offset_in_page(eb, cur);
-               unsigned int cur_len = min(start + len - cur, PAGE_SIZE - offset);
-               struct page *page = folio_page(eb->folios[index], 0);
+               unsigned long index = get_eb_folio_index(eb, cur);
+               unsigned int offset = get_eb_offset_in_folio(eb, cur);
+               unsigned int cur_len = min(start + len - cur, unit_size - offset);
 
-               assert_eb_page_uptodate(eb, page);
-               memset_page(page, offset, c, cur_len);
+               assert_eb_folio_uptodate(eb, index);
+               memset(folio_address(eb->folios[index]) + offset, c, cur_len);
 
                cur += cur_len;
        }
 void copy_extent_buffer_full(const struct extent_buffer *dst,
                             const struct extent_buffer *src)
 {
+       const int unit_size = folio_size(src->folios[0]);
        unsigned long cur = 0;
 
        ASSERT(dst->len == src->len);
 
        while (cur < src->len) {
-               unsigned long index = get_eb_page_index(cur);
-               unsigned long offset = get_eb_offset_in_page(src, cur);
-               unsigned long cur_len = min(src->len, PAGE_SIZE - offset);
+               unsigned long index = get_eb_folio_index(src, cur);
+               unsigned long offset = get_eb_offset_in_folio(src, cur);
+               unsigned long cur_len = min(src->len, unit_size - offset);
                void *addr = folio_address(src->folios[index]) + offset;
 
                write_extent_buffer(dst, addr, cur, cur_len);
                        unsigned long dst_offset, unsigned long src_offset,
                        unsigned long len)
 {
+       const int unit_size = folio_size(dst->folios[0]);
        u64 dst_len = dst->len;
        size_t cur;
        size_t offset;
-       struct page *page;
        char *kaddr;
-       unsigned long i = get_eb_page_index(dst_offset);
+       unsigned long i = get_eb_folio_index(dst, dst_offset);
 
        if (check_eb_range(dst, dst_offset, len) ||
            check_eb_range(src, src_offset, len))
 
        WARN_ON(src->len != dst_len);
 
-       offset = get_eb_offset_in_page(dst, dst_offset);
+       offset = get_eb_offset_in_folio(dst, dst_offset);
 
        while (len > 0) {
-               page = folio_page(dst->folios[i], 0);
-               assert_eb_page_uptodate(dst, page);
+               assert_eb_folio_uptodate(dst, i);
 
-               cur = min(len, (unsigned long)(PAGE_SIZE - offset));
+               cur = min(len, (unsigned long)(unit_size - offset));
 
-               kaddr = page_address(page);
+               kaddr = folio_address(dst->folios[i]);
                read_extent_buffer(src, kaddr + offset, src_offset, cur);
 
                src_offset += cur;
 
        eb_bitmap_offset(eb, start, nr, &i, &offset);
        page = folio_page(eb->folios[i], 0);
-       assert_eb_page_uptodate(eb, page);
+       assert_eb_folio_uptodate(eb, i);
        kaddr = page_address(page);
        return 1U & (kaddr[offset] >> (nr & (BITS_PER_BYTE - 1)));
 }
 
 static u8 *extent_buffer_get_byte(const struct extent_buffer *eb, unsigned long bytenr)
 {
-       unsigned long index = get_eb_page_index(bytenr);
+       unsigned long index = get_eb_folio_index(eb, bytenr);
 
        if (check_eb_range(eb, bytenr, 1))
                return NULL;
-       return folio_address(eb->folios[index]) + get_eb_offset_in_page(eb, bytenr);
+       return folio_address(eb->folios[index]) + get_eb_offset_in_folio(eb, bytenr);
 }
 
 /*
                          unsigned long dst_offset, unsigned long src_offset,
                          unsigned long len)
 {
+       const int unit_size = folio_size(dst->folios[0]);
        unsigned long cur_off = 0;
 
        if (check_eb_range(dst, dst_offset, len) ||
 
        while (cur_off < len) {
                unsigned long cur_src = cur_off + src_offset;
-               unsigned long pg_index = get_eb_page_index(cur_src);
-               unsigned long pg_off = get_eb_offset_in_page(dst, cur_src);
+               unsigned long folio_index = get_eb_folio_index(dst, cur_src);
+               unsigned long folio_off = get_eb_offset_in_folio(dst, cur_src);
                unsigned long cur_len = min(src_offset + len - cur_src,
-                                           PAGE_SIZE - pg_off);
-               void *src_addr = folio_address(dst->folios[pg_index]) + pg_off;
+                                           unit_size - folio_off);
+               void *src_addr = folio_address(dst->folios[folio_index]) + folio_off;
                const bool use_memmove = areas_overlap(src_offset + cur_off,
                                                       dst_offset + cur_off, cur_len);
 
        while (len > 0) {
                unsigned long src_i;
                size_t cur;
-               size_t dst_off_in_page;
-               size_t src_off_in_page;
+               size_t dst_off_in_folio;
+               size_t src_off_in_folio;
                void *src_addr;
                bool use_memmove;
 
-               src_i = get_eb_page_index(src_end);
+               src_i = get_eb_folio_index(dst, src_end);
 
-               dst_off_in_page = get_eb_offset_in_page(dst, dst_end);
-               src_off_in_page = get_eb_offset_in_page(dst, src_end);
+               dst_off_in_folio = get_eb_offset_in_folio(dst, dst_end);
+               src_off_in_folio = get_eb_offset_in_folio(dst, src_end);
 
-               cur = min_t(unsigned long, len, src_off_in_page + 1);
-               cur = min(cur, dst_off_in_page + 1);
+               cur = min_t(unsigned long, len, src_off_in_folio + 1);
+               cur = min(cur, dst_off_in_folio + 1);
 
-               src_addr = folio_address(dst->folios[src_i]) + src_off_in_page -
+               src_addr = folio_address(dst->folios[src_i]) + src_off_in_folio -
                                         cur + 1;
                use_memmove = areas_overlap(src_end - cur + 1, dst_end - cur + 1,
                                            cur);
 
  *
  * Will handle both sectorsize == PAGE_SIZE and sectorsize < PAGE_SIZE cases.
  */
-static inline size_t get_eb_offset_in_page(const struct extent_buffer *eb,
-                                          unsigned long offset)
+static inline size_t get_eb_offset_in_folio(const struct extent_buffer *eb,
+                                           unsigned long offset)
 {
        /*
-        * For sectorsize == PAGE_SIZE case, eb->start will always be aligned
-        * to PAGE_SIZE, thus adding it won't cause any difference.
+        * 1) sectorsize == PAGE_SIZE and nodesize >= PAGE_SIZE case
+        *    1.1) One large folio covering the whole eb
+        *         The eb->start is aligned to folio size, thus adding it
+        *         won't cause any difference.
+        *    1.2) Several page sized folios
+        *         The eb->start is aligned to folio (page) size, thus
+        *         adding it won't cause any difference.
         *
-        * For sectorsize < PAGE_SIZE, we must only read the data that belongs
-        * to the eb, thus we have to take the eb->start into consideration.
+        * 2) sectorsize < PAGE_SIZE and nodesize < PAGE_SIZE case
+        *    In this case there would only be one page sized folio, and there
+        *    may be several different extent buffers in the page/folio.
+        *    We need to add eb->start to properly access the offset inside
+        *    that eb.
         */
-       return offset_in_page(offset + eb->start);
+       return offset_in_folio(eb->folios[0], offset + eb->start);
 }
 
-static inline unsigned long get_eb_page_index(unsigned long offset)
+static inline unsigned long get_eb_folio_index(const struct extent_buffer *eb,
+                                              unsigned long offset)
 {
        /*
-        * For sectorsize == PAGE_SIZE case, plain >> PAGE_SHIFT is enough.
+        * 1) sectorsize == PAGE_SIZE and nodesize >= PAGE_SIZE case
+        *    1.1) One large folio covering the whole eb.
+        *         the folio_shift would be large enough to always make us
+        *         return 0 as index.
+        *    1.2) Several page sized folios
+        *         The folio_shift() would be PAGE_SHIFT, giving us the correct
+        *         index.
         *
-        * For sectorsize < PAGE_SIZE case, we only support 64K PAGE_SIZE,
-        * and have ensured that all tree blocks are contained in one page,
-        * thus we always get index == 0.
+        * 2) sectorsize < PAGE_SIZE and nodesize < PAGE_SIZE case
+        *    The folio would only be page sized, and always give us 0 as index.
         */
-       return offset >> PAGE_SHIFT;
+       return offset >> folio_shift(eb->folios[0]);
 }
 
 /*