diff options
-rw-r--r-- | fs/btrfs/accessors.c | 20 | ||||
-rw-r--r-- | fs/btrfs/accessors.h | 4 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 2 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 19 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 125 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 7 | ||||
-rw-r--r-- | fs/btrfs/tests/extent-io-tests.c | 4 |
7 files changed, 104 insertions, 77 deletions
diff --git a/fs/btrfs/accessors.c b/fs/btrfs/accessors.c index 206cf1612c1d..8f7cbb7154d4 100644 --- a/fs/btrfs/accessors.c +++ b/fs/btrfs/accessors.c @@ -27,7 +27,7 @@ static bool check_setget_bounds(const struct extent_buffer *eb, void btrfs_init_map_token(struct btrfs_map_token *token, struct extent_buffer *eb) { token->eb = eb; - token->kaddr = page_address(eb->pages[0]); + token->kaddr = folio_address(eb->folios[0]); token->offset = 0; } @@ -50,7 +50,7 @@ void btrfs_init_map_token(struct btrfs_map_token *token, struct extent_buffer *e * an offset into the extent buffer page array, cast to a specific type. This * gives us all the type checking. * - * The extent buffer pages stored in the array pages do not form a contiguous + * The extent buffer pages stored in the array folios may not form a contiguous * phyusical range, but the API functions assume the linear offset to the range * from 0 to metadata node size. */ @@ -74,13 +74,13 @@ u##bits btrfs_get_token_##bits(struct btrfs_map_token *token, \ member_offset + size <= token->offset + PAGE_SIZE) { \ return get_unaligned_le##bits(token->kaddr + oip); \ } \ - token->kaddr = page_address(token->eb->pages[idx]); \ + 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); \ \ memcpy(lebytes, token->kaddr + oip, part); \ - token->kaddr = page_address(token->eb->pages[idx + 1]); \ + token->kaddr = folio_address(token->eb->folios[idx + 1]); \ token->offset = (idx + 1) << PAGE_SHIFT; \ memcpy(lebytes + part, token->kaddr, size - part); \ return get_unaligned_le##bits(lebytes); \ @@ -91,7 +91,7 @@ u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ 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); \ - char *kaddr = page_address(eb->pages[idx]); \ + char *kaddr = folio_address(eb->folios[idx]); \ const int size = sizeof(u##bits); \ const int part = PAGE_SIZE - oip; \ u8 lebytes[sizeof(u##bits)]; \ @@ -101,7 +101,7 @@ u##bits btrfs_get_##bits(const struct extent_buffer *eb, \ return get_unaligned_le##bits(kaddr + oip); \ \ memcpy(lebytes, kaddr + oip, part); \ - kaddr = page_address(eb->pages[idx + 1]); \ + kaddr = folio_address(eb->folios[idx + 1]); \ memcpy(lebytes + part, kaddr, size - part); \ return get_unaligned_le##bits(lebytes); \ } \ @@ -125,7 +125,7 @@ void btrfs_set_token_##bits(struct btrfs_map_token *token, \ put_unaligned_le##bits(val, token->kaddr + oip); \ return; \ } \ - token->kaddr = page_address(token->eb->pages[idx]); \ + 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); \ @@ -133,7 +133,7 @@ void btrfs_set_token_##bits(struct btrfs_map_token *token, \ } \ put_unaligned_le##bits(val, lebytes); \ memcpy(token->kaddr + oip, lebytes, part); \ - token->kaddr = page_address(token->eb->pages[idx + 1]); \ + token->kaddr = folio_address(token->eb->folios[idx + 1]); \ token->offset = (idx + 1) << PAGE_SHIFT; \ memcpy(token->kaddr, lebytes + part, size - part); \ } \ @@ -143,7 +143,7 @@ void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr, \ 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); \ - char *kaddr = page_address(eb->pages[idx]); \ + char *kaddr = folio_address(eb->folios[idx]); \ const int size = sizeof(u##bits); \ const int part = PAGE_SIZE - oip; \ u8 lebytes[sizeof(u##bits)]; \ @@ -156,7 +156,7 @@ void btrfs_set_##bits(const struct extent_buffer *eb, void *ptr, \ \ put_unaligned_le##bits(val, lebytes); \ memcpy(kaddr + oip, lebytes, part); \ - kaddr = page_address(eb->pages[idx + 1]); \ + kaddr = folio_address(eb->folios[idx + 1]); \ memcpy(kaddr, lebytes + part, size - part); \ } diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h index aa0844535644..ed7aa32972ad 100644 --- a/fs/btrfs/accessors.h +++ b/fs/btrfs/accessors.h @@ -90,14 +90,14 @@ static inline void btrfs_set_token_##name(struct btrfs_map_token *token,\ #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ static inline u##bits btrfs_##name(const struct extent_buffer *eb) \ { \ - const type *p = page_address(eb->pages[0]) + \ + const type *p = folio_address(eb->folios[0]) + \ offset_in_page(eb->start); \ return get_unaligned_le##bits(&p->member); \ } \ static inline void btrfs_set_##name(const struct extent_buffer *eb, \ u##bits val) \ { \ - type *p = page_address(eb->pages[0]) + offset_in_page(eb->start); \ + type *p = folio_address(eb->folios[0]) + offset_in_page(eb->start); \ put_unaligned_le##bits(val, &p->member); \ } diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 137c4eb24c28..e6c535cf3749 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -832,7 +832,7 @@ int btrfs_bin_search(struct extent_buffer *eb, int first_slot, if (oip + key_size <= PAGE_SIZE) { const unsigned long idx = get_eb_page_index(offset); - char *kaddr = page_address(eb->pages[idx]); + char *kaddr = folio_address(eb->folios[idx]); oip = get_eb_offset_in_page(eb, offset); tmp = (struct btrfs_disk_key *)(kaddr + oip); diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 1b6afff66c32..74ccf43d47bc 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -89,7 +89,7 @@ static void csum_tree_block(struct extent_buffer *buf, u8 *result) first_page_part = fs_info->nodesize; num_pages = 1; } else { - kaddr = page_address(buf->pages[0]); + kaddr = folio_address(buf->folios[0]); first_page_part = min_t(u32, PAGE_SIZE, fs_info->nodesize); num_pages = num_extent_pages(buf); } @@ -98,7 +98,7 @@ static void csum_tree_block(struct extent_buffer *buf, u8 *result) first_page_part - BTRFS_CSUM_SIZE); for (i = 1; i < num_pages && INLINE_EXTENT_BUFFER_PAGES > 1; i++) { - kaddr = page_address(buf->pages[i]); + kaddr = folio_address(buf->folios[i]); crypto_shash_update(shash, kaddr, PAGE_SIZE); } memset(result, 0, BTRFS_CSUM_SIZE); @@ -184,13 +184,14 @@ static int btrfs_repair_eb_io_failure(const struct extent_buffer *eb, return -EROFS; for (i = 0; i < num_pages; i++) { - struct page *p = eb->pages[i]; - u64 start = max_t(u64, eb->start, page_offset(p)); - u64 end = min_t(u64, eb->start + eb->len, page_offset(p) + PAGE_SIZE); + u64 start = max_t(u64, eb->start, folio_pos(eb->folios[i])); + u64 end = min_t(u64, eb->start + eb->len, + folio_pos(eb->folios[i]) + PAGE_SIZE); u32 len = end - start; ret = btrfs_repair_io_failure(fs_info, 0, start, len, - start, p, offset_in_page(start), mirror_num); + start, folio_page(eb->folios[i], 0), + offset_in_page(start), mirror_num); if (ret) break; } @@ -277,8 +278,8 @@ blk_status_t btree_csum_one_bio(struct btrfs_bio *bbio) if (WARN_ON_ONCE(found_start != eb->start)) return BLK_STS_IOERR; - if (WARN_ON(!btrfs_page_test_uptodate(fs_info, eb->pages[0], eb->start, - eb->len))) + if (WARN_ON(!btrfs_page_test_uptodate(fs_info, folio_page(eb->folios[0], 0), + eb->start, eb->len))) return BLK_STS_IOERR; ASSERT(memcmp_extent_buffer(eb, fs_info->fs_devices->metadata_uuid, @@ -387,7 +388,7 @@ int btrfs_validate_extent_buffer(struct extent_buffer *eb, } csum_tree_block(eb, result); - header_csum = page_address(eb->pages[0]) + + header_csum = folio_address(eb->folios[0]) + get_eb_offset_in_page(eb, offsetof(struct btrfs_header, csum)); if (memcmp(result, header_csum, csum_size) != 0) { diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index cecd8939e99a..557b9c65840e 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -712,6 +712,26 @@ int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array, return 0; } +/* + * Populate needed folios for the extent buffer. + * + * For now, the folios populated are always in order 0 (aka, single page). + */ +static int alloc_eb_folio_array(struct extent_buffer *eb, gfp_t extra_gfp) +{ + struct page *page_array[INLINE_EXTENT_BUFFER_PAGES] = { 0 }; + int num_pages = num_extent_pages(eb); + int ret; + + ret = btrfs_alloc_page_array(num_pages, page_array, extra_gfp); + if (ret < 0) + return ret; + + for (int i = 0; i < num_pages; i++) + eb->folios[i] = page_folio(page_array[i]); + return 0; +} + static bool btrfs_bio_is_contig(struct btrfs_bio_ctrl *bio_ctrl, struct page *page, u64 disk_bytenr, unsigned int pg_offset) @@ -1688,7 +1708,7 @@ static noinline_for_stack void write_one_eb(struct extent_buffer *eb, bbio->inode = BTRFS_I(eb->fs_info->btree_inode); bbio->file_offset = eb->start; if (fs_info->nodesize < PAGE_SIZE) { - struct page *p = eb->pages[0]; + struct page *p = folio_page(eb->folios[0], 0); lock_page(p); btrfs_subpage_set_writeback(fs_info, p, eb->start, eb->len); @@ -1702,7 +1722,7 @@ static noinline_for_stack void write_one_eb(struct extent_buffer *eb, unlock_page(p); } else { for (int i = 0; i < num_extent_pages(eb); i++) { - struct page *p = eb->pages[i]; + struct page *p = folio_page(eb->folios[i], 0); lock_page(p); clear_page_dirty_for_io(p); @@ -3160,7 +3180,7 @@ static void btrfs_release_extent_buffer_pages(struct extent_buffer *eb) num_pages = num_extent_pages(eb); for (i = 0; i < num_pages; i++) { - struct page *page = eb->pages[i]; + struct page *page = folio_page(eb->folios[i], 0); if (!page) continue; @@ -3222,7 +3242,7 @@ struct extent_buffer *btrfs_clone_extent_buffer(const struct extent_buffer *src) */ set_bit(EXTENT_BUFFER_UNMAPPED, &new->bflags); - ret = btrfs_alloc_page_array(num_pages, new->pages, 0); + ret = alloc_eb_folio_array(new, 0); if (ret) { btrfs_release_extent_buffer(new); return NULL; @@ -3230,7 +3250,7 @@ struct extent_buffer *btrfs_clone_extent_buffer(const struct extent_buffer *src) for (i = 0; i < num_pages; i++) { int ret; - struct page *p = new->pages[i]; + struct page *p = folio_page(new->folios[i], 0); ret = attach_extent_buffer_page(new, p, NULL); if (ret < 0) { @@ -3258,12 +3278,12 @@ struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, return NULL; num_pages = num_extent_pages(eb); - ret = btrfs_alloc_page_array(num_pages, eb->pages, 0); + ret = alloc_eb_folio_array(eb, 0); if (ret) goto err; for (i = 0; i < num_pages; i++) { - struct page *p = eb->pages[i]; + struct page *p = folio_page(eb->folios[i], 0); ret = attach_extent_buffer_page(eb, p, NULL); if (ret < 0) @@ -3277,9 +3297,9 @@ struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, return eb; err: for (i = 0; i < num_pages; i++) { - if (eb->pages[i]) { - detach_extent_buffer_page(eb, eb->pages[i]); - __free_page(eb->pages[i]); + if (eb->folios[i]) { + detach_extent_buffer_page(eb, folio_page(eb->folios[i], 0)); + __free_page(folio_page(eb->folios[i], 0)); } } __free_extent_buffer(eb); @@ -3337,7 +3357,7 @@ static void mark_extent_buffer_accessed(struct extent_buffer *eb, num_pages = num_extent_pages(eb); for (i = 0; i < num_pages; i++) { - struct page *p = eb->pages[i]; + struct page *p = folio_page(eb->folios[i], 0); if (p != accessed) mark_page_accessed(p); @@ -3480,8 +3500,8 @@ static int check_eb_alignment(struct btrfs_fs_info *fs_info, u64 start) /* - * Return 0 if eb->pages[i] is attached to btree inode successfully. - * Return >0 if there is already annother extent buffer for the range, + * Return 0 if eb->folios[i] is attached to btree inode successfully. + * Return >0 if there is already another extent buffer for the range, * and @found_eb_ret would be updated. */ static int attach_eb_page_to_filemap(struct extent_buffer *eb, int i, @@ -3496,11 +3516,11 @@ static int attach_eb_page_to_filemap(struct extent_buffer *eb, int i, ASSERT(found_eb_ret); - /* Caller should ensure the page exists. */ - ASSERT(eb->pages[i]); + /* Caller should ensure the folio exists. */ + ASSERT(eb->folios[i]); retry: - ret = filemap_add_folio(mapping, page_folio(eb->pages[i]), index + i, + ret = filemap_add_folio(mapping, eb->folios[i], index + i, GFP_NOFS | __GFP_NOFAIL); if (!ret) return 0; @@ -3518,8 +3538,8 @@ retry: * We're going to reuse the existing page, can drop our page * and subpage structure now. */ - __free_page(eb->pages[i]); - eb->pages[i] = folio_page(existing_folio, 0); + __free_page(folio_page(eb->folios[i], 0)); + eb->folios[i] = existing_folio; } else { struct extent_buffer *existing_eb; @@ -3533,8 +3553,8 @@ retry: return 1; } /* The extent buffer no longer exists, we can reuse the folio. */ - __free_page(eb->pages[i]); - eb->pages[i] = folio_page(existing_folio, 0); + __free_page(folio_page(eb->folios[i], 0)); + eb->folios[i] = existing_folio; } return 0; } @@ -3603,7 +3623,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, } /* Allocate all pages first. */ - ret = btrfs_alloc_page_array(num_pages, eb->pages, __GFP_NOFAIL); + ret = alloc_eb_folio_array(eb, __GFP_NOFAIL); if (ret < 0) { btrfs_free_subpage(prealloc); goto out; @@ -3621,11 +3641,11 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, attached++; /* - * Only after attach_eb_page_to_filemap(), eb->pages[] is + * Only after attach_eb_page_to_filemap(), eb->folios[] is * reliable, as we may choose to reuse the existing page cache * and free the allocated page. */ - p = eb->pages[i]; + p = folio_page(eb->folios[i], 0); spin_lock(&mapping->private_lock); /* Should not fail, as we have preallocated the memory */ ret = attach_extent_buffer_page(eb, p, prealloc); @@ -3648,7 +3668,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, * Check if the current page is physically contiguous with previous eb * page. */ - if (i && eb->pages[i - 1] + 1 != p) + if (i && folio_page(eb->folios[i - 1], 0) + 1 != p) page_contig = false; if (!btrfs_page_test_uptodate(fs_info, p, eb->start, eb->len)) @@ -3666,7 +3686,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); /* All pages are physically contiguous, can skip cross page handling. */ if (page_contig) - eb->addr = page_address(eb->pages[0]) + offset_in_page(eb->start); + eb->addr = folio_address(eb->folios[0]) + offset_in_page(eb->start); again: ret = radix_tree_preload(GFP_NOFS); if (ret) @@ -3695,15 +3715,15 @@ again: * live buffer and won't free them prematurely. */ for (int i = 0; i < num_pages; i++) - unlock_page(eb->pages[i]); + unlock_page(folio_page(eb->folios[i], 0)); return eb; out: WARN_ON(!atomic_dec_and_test(&eb->refs)); for (int i = 0; i < attached; i++) { - ASSERT(eb->pages[i]); - detach_extent_buffer_page(eb, eb->pages[i]); - unlock_page(eb->pages[i]); + ASSERT(eb->folios[i]); + detach_extent_buffer_page(eb, folio_page(eb->folios[i], 0)); + unlock_page(folio_page(eb->folios[i], 0)); } /* * Now all pages of that extent buffer is unmapped, set UNMAPPED flag, @@ -3822,7 +3842,7 @@ static void btree_clear_page_dirty(struct page *page) static void clear_subpage_extent_buffer_dirty(const struct extent_buffer *eb) { struct btrfs_fs_info *fs_info = eb->fs_info; - struct page *page = eb->pages[0]; + struct page *page = folio_page(eb->folios[0], 0); bool last; /* btree_clear_page_dirty() needs page locked */ @@ -3874,7 +3894,7 @@ void btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans, num_pages = num_extent_pages(eb); for (i = 0; i < num_pages; i++) { - page = eb->pages[i]; + page = folio_page(eb->folios[i], 0); if (!PageDirty(page)) continue; lock_page(page); @@ -3913,19 +3933,19 @@ void set_extent_buffer_dirty(struct extent_buffer *eb) * the above race. */ if (subpage) - lock_page(eb->pages[0]); + lock_page(folio_page(eb->folios[0], 0)); for (i = 0; i < num_pages; i++) - btrfs_page_set_dirty(eb->fs_info, eb->pages[i], + btrfs_page_set_dirty(eb->fs_info, folio_page(eb->folios[i], 0), eb->start, eb->len); if (subpage) - unlock_page(eb->pages[0]); + unlock_page(folio_page(eb->folios[0], 0)); percpu_counter_add_batch(&eb->fs_info->dirty_metadata_bytes, eb->len, eb->fs_info->dirty_metadata_batch); } #ifdef CONFIG_BTRFS_DEBUG for (i = 0; i < num_pages; i++) - ASSERT(PageDirty(eb->pages[i])); + ASSERT(PageDirty(folio_page(eb->folios[i], 0))); #endif } @@ -3939,7 +3959,7 @@ void clear_extent_buffer_uptodate(struct extent_buffer *eb) clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); num_pages = num_extent_pages(eb); for (i = 0; i < num_pages; i++) { - page = eb->pages[i]; + page = folio_page(eb->folios[i], 0); if (!page) continue; @@ -3965,7 +3985,7 @@ void set_extent_buffer_uptodate(struct extent_buffer *eb) set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); num_pages = num_extent_pages(eb); for (i = 0; i < num_pages; i++) { - page = eb->pages[i]; + page = folio_page(eb->folios[i], 0); /* * This is special handling for metadata subpage, as regular @@ -4056,11 +4076,12 @@ int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num, bbio->file_offset = eb->start; memcpy(&bbio->parent_check, check, sizeof(*check)); if (eb->fs_info->nodesize < PAGE_SIZE) { - __bio_add_page(&bbio->bio, eb->pages[0], eb->len, - eb->start - page_offset(eb->pages[0])); + __bio_add_page(&bbio->bio, folio_page(eb->folios[0], 0), eb->len, + eb->start - folio_pos(eb->folios[0])); } else { for (i = 0; i < num_pages; i++) - __bio_add_page(&bbio->bio, eb->pages[i], PAGE_SIZE, 0); + __bio_add_page(&bbio->bio, folio_page(eb->folios[i], 0), + PAGE_SIZE, 0); } btrfs_submit_bio(bbio, mirror_num); @@ -4131,7 +4152,7 @@ void read_extent_buffer(const struct extent_buffer *eb, void *dstv, offset = get_eb_offset_in_page(eb, start); while (len > 0) { - page = eb->pages[i]; + page = folio_page(eb->folios[i], 0); cur = min(len, (PAGE_SIZE - offset)); kaddr = page_address(page); @@ -4168,7 +4189,7 @@ int read_extent_buffer_to_user_nofault(const struct extent_buffer *eb, offset = get_eb_offset_in_page(eb, start); while (len > 0) { - page = eb->pages[i]; + page = folio_page(eb->folios[i], 0); cur = min(len, (PAGE_SIZE - offset)); kaddr = page_address(page); @@ -4206,7 +4227,7 @@ int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, offset = get_eb_offset_in_page(eb, start); while (len > 0) { - page = eb->pages[i]; + page = folio_page(eb->folios[i], 0); cur = min(len, (PAGE_SIZE - offset)); @@ -4281,7 +4302,7 @@ static void __write_extent_buffer(const struct extent_buffer *eb, offset = get_eb_offset_in_page(eb, start); while (len > 0) { - page = eb->pages[i]; + page = folio_page(eb->folios[i], 0); if (check_uptodate) assert_eb_page_uptodate(eb, page); @@ -4319,7 +4340,7 @@ static void memset_extent_buffer(const struct extent_buffer *eb, int c, 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 = eb->pages[index]; + struct page *page = folio_page(eb->folios[index], 0); assert_eb_page_uptodate(eb, page); memset_page(page, offset, c, cur_len); @@ -4347,7 +4368,7 @@ void copy_extent_buffer_full(const struct extent_buffer *dst, 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); - void *addr = page_address(src->pages[index]) + offset; + void *addr = folio_address(src->folios[index]) + offset; write_extent_buffer(dst, addr, cur, cur_len); @@ -4376,7 +4397,7 @@ void copy_extent_buffer(const struct extent_buffer *dst, offset = get_eb_offset_in_page(dst, dst_offset); while (len > 0) { - page = dst->pages[i]; + page = folio_page(dst->folios[i], 0); assert_eb_page_uptodate(dst, page); cur = min(len, (unsigned long)(PAGE_SIZE - offset)); @@ -4439,7 +4460,7 @@ int extent_buffer_test_bit(const struct extent_buffer *eb, unsigned long start, size_t offset; eb_bitmap_offset(eb, start, nr, &i, &offset); - page = eb->pages[i]; + page = folio_page(eb->folios[i], 0); assert_eb_page_uptodate(eb, page); kaddr = page_address(page); return 1U & (kaddr[offset] >> (nr & (BITS_PER_BYTE - 1))); @@ -4451,7 +4472,7 @@ static u8 *extent_buffer_get_byte(const struct extent_buffer *eb, unsigned long if (check_eb_range(eb, bytenr, 1)) return NULL; - return page_address(eb->pages[index]) + get_eb_offset_in_page(eb, bytenr); + return folio_address(eb->folios[index]) + get_eb_offset_in_page(eb, bytenr); } /* @@ -4558,7 +4579,7 @@ void memcpy_extent_buffer(const struct extent_buffer *dst, unsigned long pg_off = get_eb_offset_in_page(dst, cur_src); unsigned long cur_len = min(src_offset + len - cur_src, PAGE_SIZE - pg_off); - void *src_addr = page_address(dst->pages[pg_index]) + pg_off; + void *src_addr = folio_address(dst->folios[pg_index]) + pg_off; const bool use_memmove = areas_overlap(src_offset + cur_off, dst_offset + cur_off, cur_len); @@ -4605,8 +4626,8 @@ void memmove_extent_buffer(const struct extent_buffer *dst, cur = min_t(unsigned long, len, src_off_in_page + 1); cur = min(cur, dst_off_in_page + 1); - src_addr = page_address(dst->pages[src_i]) + src_off_in_page - - cur + 1; + src_addr = folio_address(dst->folios[src_i]) + src_off_in_page - + cur + 1; use_memmove = areas_overlap(src_end - cur + 1, dst_end - cur + 1, cur); diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index c73d53c22ec5..66c2e214b141 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -94,7 +94,12 @@ struct extent_buffer { struct rw_semaphore lock; - struct page *pages[INLINE_EXTENT_BUFFER_PAGES]; + /* + * Pointers to all the folios of the extent buffer. + * + * For now the folio is always order 0 (aka, a single page). + */ + struct folio *folios[INLINE_EXTENT_BUFFER_PAGES]; #ifdef CONFIG_BTRFS_DEBUG struct list_head leak_list; pid_t lock_owner; diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index 1cc86af97dc6..25b3349595e0 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c @@ -652,7 +652,7 @@ static void dump_eb_and_memory_contents(struct extent_buffer *eb, void *memory, const char *test_name) { for (int i = 0; i < eb->len; i++) { - struct page *page = eb->pages[i >> PAGE_SHIFT]; + struct page *page = folio_page(eb->folios[i >> PAGE_SHIFT], 0); void *addr = page_address(page) + offset_in_page(i); if (memcmp(addr, memory + i, 1) != 0) { @@ -668,7 +668,7 @@ static int verify_eb_and_memory(struct extent_buffer *eb, void *memory, const char *test_name) { for (int i = 0; i < (eb->len >> PAGE_SHIFT); i++) { - void *eb_addr = page_address(eb->pages[i]); + void *eb_addr = folio_address(eb->folios[i]); if (memcmp(memory + (i << PAGE_SHIFT), eb_addr, PAGE_SIZE) != 0) { dump_eb_and_memory_contents(eb, memory, test_name); |