* [PATCH 0/5] btrfs: prepare for larger folios support
@ 2025-02-20 9:22 Qu Wenruo
2025-02-20 9:22 ` [PATCH 1/5] btrfs: prepare subpage.c " Qu Wenruo
` (5 more replies)
0 siblings, 6 replies; 19+ messages in thread
From: Qu Wenruo @ 2025-02-20 9:22 UTC (permalink / raw)
To: linux-btrfs
This means:
- Our subpage routine should check against the folio size other than
PAGE_SIZE
- Make functions handling filemap folios to use folio_size() other than
PAGE_SIZE
The most common paths are:
* Buffered reads/writes
* Uncompressed folio writeback
Already handled pretty well
* Compressed read
* Compressed write
To take full advantage of larger folios, we should use folio_iter
other than bvec_iter.
This will be a dedicated patchset, and the existing bvec_iter can
still handle larger folios.
Internal usages can still use page sized folios, or even pages,
including:
* Encoded reads/writes
* Compressed folios
* RAID56 internal pages
* Scrub internal pages
This patchset will handle the above mentioned points by:
- Prepare the subpage routine to handle larger folios
This will introduce a small overhead, as all checks are against folio
sizes, even on x86_64 we can no longer skip subpage completely.
This is done in the first patch.
- Convert straightforward PAGE_SIZE users to use folio_size()
This is done in the remaining patches.
Currently this patchset is not a exhaustive conversion, I'm pretty sure
there are other complex situations which can cause problems.
Those problems can only be exposed and fixed after switching on the
experimental larger folios support later.
Qu Wenruo (5):
btrfs: prepare subpage.c for larger folios support
btrfs: remove the PAGE_SIZE usage inside inline extent reads
btrfs: prepare btrfs_launcher_folio() for larger folios support
btrfs: prepare extent_io.c for future larger folio support
btrfs: prepare btrfs_page_mkwrite() for larger folios
fs/btrfs/extent_io.c | 50 +++++++++++++++++++++++++-------------------
fs/btrfs/file.c | 19 +++++++++--------
fs/btrfs/inode.c | 8 +++----
fs/btrfs/subpage.c | 36 +++++++++++++++----------------
fs/btrfs/subpage.h | 24 ++++++++-------------
5 files changed, 69 insertions(+), 68 deletions(-)
--
2.48.1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 1/5] btrfs: prepare subpage.c for larger folios support
2025-02-20 9:22 [PATCH 0/5] btrfs: prepare for larger folios support Qu Wenruo
@ 2025-02-20 9:22 ` Qu Wenruo
2025-02-21 12:06 ` Johannes Thumshirn
2025-02-20 9:22 ` [PATCH 2/5] btrfs: remove the PAGE_SIZE usage inside inline extent reads Qu Wenruo
` (4 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Qu Wenruo @ 2025-02-20 9:22 UTC (permalink / raw)
To: linux-btrfs
For the future of larger folio support, even if block size == page size,
we may still hit a larger folio and need to attach a subpage structure to
that larger folio.
In that case we can no longer assume we need to go subpage routine only
when block size < page size, but take folio size into the consideration.
Prepare for such future by:
- Use folio_size() instead of PAGE_SIZE
- Make btrfs_alloc_subpage() to handle different folio sizes
- Make btrfs_is_subpage() to do the check based on the folio
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/extent_io.c | 17 +++++++++--------
fs/btrfs/inode.c | 2 +-
fs/btrfs/subpage.c | 36 ++++++++++++++++++------------------
fs/btrfs/subpage.h | 24 +++++++++---------------
4 files changed, 37 insertions(+), 42 deletions(-)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index c023ea514f64..e1efb6419601 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -432,7 +432,7 @@ static void end_folio_read(struct folio *folio, bool uptodate, u64 start, u32 le
else
btrfs_folio_clear_uptodate(fs_info, folio, start, len);
- if (!btrfs_is_subpage(fs_info, folio->mapping))
+ if (!btrfs_is_subpage(fs_info, folio))
folio_unlock(folio);
else
btrfs_folio_end_lock(fs_info, folio, start, len);
@@ -488,7 +488,7 @@ static void end_bbio_data_write(struct btrfs_bio *bbio)
static void begin_folio_read(struct btrfs_fs_info *fs_info, struct folio *folio)
{
ASSERT(folio_test_locked(folio));
- if (!btrfs_is_subpage(fs_info, folio->mapping))
+ if (!btrfs_is_subpage(fs_info, folio))
return;
ASSERT(folio_test_private(folio));
@@ -870,7 +870,7 @@ int set_folio_extent_mapped(struct folio *folio)
fs_info = folio_to_fs_info(folio);
- if (btrfs_is_subpage(fs_info, folio->mapping))
+ if (btrfs_is_subpage(fs_info, folio))
return btrfs_attach_subpage(fs_info, folio, BTRFS_SUBPAGE_DATA);
folio_attach_private(folio, (void *)EXTENT_FOLIO_PRIVATE);
@@ -887,7 +887,7 @@ void clear_folio_extent_mapped(struct folio *folio)
return;
fs_info = folio_to_fs_info(folio);
- if (btrfs_is_subpage(fs_info, folio->mapping))
+ if (btrfs_is_subpage(fs_info, folio))
return btrfs_detach_subpage(fs_info, folio, BTRFS_SUBPAGE_DATA);
folio_detach_private(folio);
@@ -1329,7 +1329,7 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
{
struct btrfs_fs_info *fs_info = inode_to_fs_info(&inode->vfs_inode);
struct writeback_control *wbc = bio_ctrl->wbc;
- const bool is_subpage = btrfs_is_subpage(fs_info, folio->mapping);
+ const bool is_subpage = btrfs_is_subpage(fs_info, folio);
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);
@@ -1357,7 +1357,7 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
int bit;
/* 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)) {
+ if (is_subpage) {
ASSERT(blocks_per_folio > 1);
btrfs_get_subpage_dirty_bitmap(fs_info, folio, &bio_ctrl->submit_bitmap);
} else {
@@ -2387,7 +2387,7 @@ static int extent_write_cache_pages(struct address_space *mapping,
* regular submission.
*/
if (wbc->sync_mode != WB_SYNC_NONE ||
- btrfs_is_subpage(inode_to_fs_info(inode), mapping)) {
+ btrfs_is_subpage(inode_to_fs_info(inode), folio)) {
if (folio_test_writeback(folio))
submit_write_bio(bio_ctrl, 0);
folio_wait_writeback(folio);
@@ -3245,7 +3245,8 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,
* manually if we exit earlier.
*/
if (btrfs_meta_is_subpage(fs_info)) {
- prealloc = btrfs_alloc_subpage(fs_info, BTRFS_SUBPAGE_METADATA);
+ prealloc = btrfs_alloc_subpage(fs_info, PAGE_SIZE,
+ BTRFS_SUBPAGE_METADATA);
if (IS_ERR(prealloc)) {
ret = PTR_ERR(prealloc);
goto out;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 7796e81dbb9d..3af74f3c5d75 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7246,7 +7246,7 @@ static void wait_subpage_spinlock(struct folio *folio)
struct btrfs_fs_info *fs_info = folio_to_fs_info(folio);
struct btrfs_subpage *subpage;
- if (!btrfs_is_subpage(fs_info, folio->mapping))
+ if (!btrfs_is_subpage(fs_info, folio))
return;
ASSERT(folio_test_private(folio) && folio_get_private(folio));
diff --git a/fs/btrfs/subpage.c b/fs/btrfs/subpage.c
index 4d7600e14286..afaa1f381a74 100644
--- a/fs/btrfs/subpage.c
+++ b/fs/btrfs/subpage.c
@@ -84,10 +84,10 @@ int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
return 0;
if (type == BTRFS_SUBPAGE_METADATA && !btrfs_meta_is_subpage(fs_info))
return 0;
- if (type == BTRFS_SUBPAGE_DATA && !btrfs_is_subpage(fs_info, folio->mapping))
+ if (type == BTRFS_SUBPAGE_DATA && !btrfs_is_subpage(fs_info, folio))
return 0;
- subpage = btrfs_alloc_subpage(fs_info, type);
+ subpage = btrfs_alloc_subpage(fs_info, folio_size(folio), type);
if (IS_ERR(subpage))
return PTR_ERR(subpage);
@@ -105,7 +105,7 @@ void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, struct folio *fol
return;
if (type == BTRFS_SUBPAGE_METADATA && !btrfs_meta_is_subpage(fs_info))
return;
- if (type == BTRFS_SUBPAGE_DATA && !btrfs_is_subpage(fs_info, folio->mapping))
+ if (type == BTRFS_SUBPAGE_DATA && !btrfs_is_subpage(fs_info, folio))
return;
subpage = folio_detach_private(folio);
@@ -114,16 +114,16 @@ void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, struct folio *fol
}
struct btrfs_subpage *btrfs_alloc_subpage(const struct btrfs_fs_info *fs_info,
- enum btrfs_subpage_type type)
+ size_t fsize, enum btrfs_subpage_type type)
{
struct btrfs_subpage *ret;
unsigned int real_size;
- ASSERT(fs_info->sectorsize < PAGE_SIZE);
+ ASSERT(fs_info->sectorsize < fsize);
real_size = struct_size(ret, bitmaps,
BITS_TO_LONGS(btrfs_bitmap_nr_max *
- (PAGE_SIZE >> fs_info->sectorsize_bits)));
+ (fsize >> fs_info->sectorsize_bits)));
ret = kzalloc(real_size, GFP_NOFS);
if (!ret)
return ERR_PTR(-ENOMEM);
@@ -195,7 +195,7 @@ static void btrfs_subpage_assert(const struct btrfs_fs_info *fs_info,
*/
if (folio->mapping)
ASSERT(folio_pos(folio) <= start &&
- start + len <= folio_pos(folio) + PAGE_SIZE);
+ start + len <= folio_pos(folio) + folio_size(folio));
}
#define subpage_calc_start_bit(fs_info, folio, name, start, len) \
@@ -224,7 +224,7 @@ static void btrfs_subpage_clamp_range(struct folio *folio, u64 *start, u32 *len)
if (folio_pos(folio) >= orig_start + orig_len)
*len = 0;
else
- *len = min_t(u64, folio_pos(folio) + PAGE_SIZE,
+ *len = min_t(u64, folio_pos(folio) + folio_size(folio),
orig_start + orig_len) - *start;
}
@@ -287,7 +287,7 @@ void btrfs_folio_end_lock(const struct btrfs_fs_info *fs_info,
ASSERT(folio_test_locked(folio));
- if (unlikely(!fs_info) || !btrfs_is_subpage(fs_info, folio->mapping)) {
+ if (unlikely(!fs_info) || !btrfs_is_subpage(fs_info, folio)) {
folio_unlock(folio);
return;
}
@@ -321,7 +321,7 @@ void btrfs_folio_end_lock_bitmap(const struct btrfs_fs_info *fs_info,
int cleared = 0;
int bit;
- if (!btrfs_is_subpage(fs_info, folio->mapping)) {
+ if (!btrfs_is_subpage(fs_info, folio)) {
folio_unlock(folio);
return;
}
@@ -573,7 +573,7 @@ void btrfs_folio_set_##name(const struct btrfs_fs_info *fs_info, \
struct folio *folio, u64 start, u32 len) \
{ \
if (unlikely(!fs_info) || \
- !btrfs_is_subpage(fs_info, folio->mapping)) { \
+ !btrfs_is_subpage(fs_info, folio)) { \
folio_set_func(folio); \
return; \
} \
@@ -583,7 +583,7 @@ void btrfs_folio_clear_##name(const struct btrfs_fs_info *fs_info, \
struct folio *folio, u64 start, u32 len) \
{ \
if (unlikely(!fs_info) || \
- !btrfs_is_subpage(fs_info, folio->mapping)) { \
+ !btrfs_is_subpage(fs_info, folio)) { \
folio_clear_func(folio); \
return; \
} \
@@ -593,7 +593,7 @@ bool btrfs_folio_test_##name(const struct btrfs_fs_info *fs_info, \
struct folio *folio, u64 start, u32 len) \
{ \
if (unlikely(!fs_info) || \
- !btrfs_is_subpage(fs_info, folio->mapping)) \
+ !btrfs_is_subpage(fs_info, folio)) \
return folio_test_func(folio); \
return btrfs_subpage_test_##name(fs_info, folio, start, len); \
} \
@@ -601,7 +601,7 @@ void btrfs_folio_clamp_set_##name(const struct btrfs_fs_info *fs_info, \
struct folio *folio, u64 start, u32 len) \
{ \
if (unlikely(!fs_info) || \
- !btrfs_is_subpage(fs_info, folio->mapping)) { \
+ !btrfs_is_subpage(fs_info, folio)) { \
folio_set_func(folio); \
return; \
} \
@@ -612,7 +612,7 @@ void btrfs_folio_clamp_clear_##name(const struct btrfs_fs_info *fs_info, \
struct folio *folio, u64 start, u32 len) \
{ \
if (unlikely(!fs_info) || \
- !btrfs_is_subpage(fs_info, folio->mapping)) { \
+ !btrfs_is_subpage(fs_info, folio)) { \
folio_clear_func(folio); \
return; \
} \
@@ -623,7 +623,7 @@ bool btrfs_folio_clamp_test_##name(const struct btrfs_fs_info *fs_info, \
struct folio *folio, u64 start, u32 len) \
{ \
if (unlikely(!fs_info) || \
- !btrfs_is_subpage(fs_info, folio->mapping)) \
+ !btrfs_is_subpage(fs_info, folio)) \
return folio_test_func(folio); \
btrfs_subpage_clamp_range(folio, &start, &len); \
return btrfs_subpage_test_##name(fs_info, folio, start, len); \
@@ -704,7 +704,7 @@ void btrfs_folio_assert_not_dirty(const struct btrfs_fs_info *fs_info,
if (!IS_ENABLED(CONFIG_BTRFS_ASSERT))
return;
- if (!btrfs_is_subpage(fs_info, folio->mapping)) {
+ if (!btrfs_is_subpage(fs_info, folio)) {
ASSERT(!folio_test_dirty(folio));
return;
}
@@ -739,7 +739,7 @@ void btrfs_folio_set_lock(const struct btrfs_fs_info *fs_info,
int ret;
ASSERT(folio_test_locked(folio));
- if (unlikely(!fs_info) || !btrfs_is_subpage(fs_info, folio->mapping))
+ if (unlikely(!fs_info) || !btrfs_is_subpage(fs_info, folio))
return;
subpage = folio_get_private(folio);
diff --git a/fs/btrfs/subpage.h b/fs/btrfs/subpage.h
index e10a1d308f32..f8d1efa1a227 100644
--- a/fs/btrfs/subpage.h
+++ b/fs/btrfs/subpage.h
@@ -84,27 +84,21 @@ static inline bool btrfs_meta_is_subpage(const struct btrfs_fs_info *fs_info)
{
return fs_info->nodesize < PAGE_SIZE;
}
-static inline bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info,
- struct address_space *mapping)
-{
- if (mapping && mapping->host)
- ASSERT(is_data_inode(BTRFS_I(mapping->host)));
- return fs_info->sectorsize < PAGE_SIZE;
-}
#else
static inline bool btrfs_meta_is_subpage(const struct btrfs_fs_info *fs_info)
{
return false;
}
-static inline bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info,
- struct address_space *mapping)
-{
- if (mapping && mapping->host)
- ASSERT(is_data_inode(BTRFS_I(mapping->host)));
- return false;
-}
#endif
+static inline bool btrfs_is_subpage(const struct btrfs_fs_info *fs_info,
+ struct folio *folio)
+{
+ if (folio_mapped(folio) && folio->mapping && folio->mapping->host)
+ ASSERT(is_data_inode(BTRFS_I(folio->mapping->host)));
+ return fs_info->sectorsize < folio_size(folio);
+}
+
int btrfs_attach_subpage(const struct btrfs_fs_info *fs_info,
struct folio *folio, enum btrfs_subpage_type type);
void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, struct folio *folio,
@@ -112,7 +106,7 @@ void btrfs_detach_subpage(const struct btrfs_fs_info *fs_info, struct folio *fol
/* Allocate additional data where page represents more than one sector */
struct btrfs_subpage *btrfs_alloc_subpage(const struct btrfs_fs_info *fs_info,
- enum btrfs_subpage_type type);
+ size_t fsize, enum btrfs_subpage_type type);
void btrfs_free_subpage(struct btrfs_subpage *subpage);
void btrfs_folio_inc_eb_refs(const struct btrfs_fs_info *fs_info, struct folio *folio);
--
2.48.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 2/5] btrfs: remove the PAGE_SIZE usage inside inline extent reads
2025-02-20 9:22 [PATCH 0/5] btrfs: prepare for larger folios support Qu Wenruo
2025-02-20 9:22 ` [PATCH 1/5] btrfs: prepare subpage.c " Qu Wenruo
@ 2025-02-20 9:22 ` Qu Wenruo
2025-02-21 11:37 ` Johannes Thumshirn
2025-02-20 9:22 ` [PATCH 3/5] btrfs: prepare btrfs_launcher_folio() for larger folios support Qu Wenruo
` (3 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Qu Wenruo @ 2025-02-20 9:22 UTC (permalink / raw)
To: linux-btrfs
The inline extent ram size should never exceed btrfs block size, there
is no need to clamp the size against PAGE_SIZE.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/inode.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3af74f3c5d75..d9ca92d1b927 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6784,7 +6784,7 @@ static noinline int uncompress_inline(struct btrfs_path *path,
read_extent_buffer(leaf, tmp, ptr, inline_size);
- max_size = min_t(unsigned long, PAGE_SIZE, max_size);
+ max_size = min_t(unsigned long, sectorsize, max_size);
ret = btrfs_decompress(compress_type, tmp, folio, 0, inline_size,
max_size);
@@ -6820,7 +6820,7 @@ static int read_inline_extent(struct btrfs_fs_info *fs_info,
if (btrfs_file_extent_compression(path->nodes[0], fi) != BTRFS_COMPRESS_NONE)
return uncompress_inline(path, folio, fi);
- copy_size = min_t(u64, PAGE_SIZE,
+ copy_size = min_t(u64, sectorsize,
btrfs_file_extent_ram_bytes(path->nodes[0], fi));
kaddr = kmap_local_folio(folio, 0);
read_extent_buffer(path->nodes[0], kaddr,
--
2.48.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 3/5] btrfs: prepare btrfs_launcher_folio() for larger folios support
2025-02-20 9:22 [PATCH 0/5] btrfs: prepare for larger folios support Qu Wenruo
2025-02-20 9:22 ` [PATCH 1/5] btrfs: prepare subpage.c " Qu Wenruo
2025-02-20 9:22 ` [PATCH 2/5] btrfs: remove the PAGE_SIZE usage inside inline extent reads Qu Wenruo
@ 2025-02-20 9:22 ` Qu Wenruo
2025-02-21 12:08 ` Johannes Thumshirn
2025-02-20 9:22 ` [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support Qu Wenruo
` (2 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: Qu Wenruo @ 2025-02-20 9:22 UTC (permalink / raw)
To: linux-btrfs
That function is only calling btrfs_qgroup_free_data(), which doesn't
care the size of the folio.
Just replace the fixed PAGE_SIZE with folio_size().
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/inode.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d9ca92d1b927..c88aa961af51 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7270,7 +7270,7 @@ static void wait_subpage_spinlock(struct folio *folio)
static int btrfs_launder_folio(struct folio *folio)
{
return btrfs_qgroup_free_data(folio_to_inode(folio), NULL, folio_pos(folio),
- PAGE_SIZE, NULL);
+ folio_size(folio), NULL);
}
static bool __btrfs_release_folio(struct folio *folio, gfp_t gfp_flags)
--
2.48.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support
2025-02-20 9:22 [PATCH 0/5] btrfs: prepare for larger folios support Qu Wenruo
` (2 preceding siblings ...)
2025-02-20 9:22 ` [PATCH 3/5] btrfs: prepare btrfs_launcher_folio() for larger folios support Qu Wenruo
@ 2025-02-20 9:22 ` Qu Wenruo
2025-02-21 11:12 ` kernel test robot
` (3 more replies)
2025-02-20 9:22 ` [PATCH 5/5] btrfs: prepare btrfs_page_mkwrite() for larger folios Qu Wenruo
2025-02-21 11:23 ` [PATCH 0/5] btrfs: prepare for larger folios support Johannes Thumshirn
5 siblings, 4 replies; 19+ messages in thread
From: Qu Wenruo @ 2025-02-20 9:22 UTC (permalink / raw)
To: linux-btrfs
When we're handling folios from filemap, we can no longer assume all
folios are page sized.
Thus for call sites assuming the folio is page sized, change the
PAGE_SIZE usage to folio_size() instead.
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/extent_io.c | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index e1efb6419601..88bac9a32919 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -425,7 +425,7 @@ static void end_folio_read(struct folio *folio, bool uptodate, u64 start, u32 le
struct btrfs_fs_info *fs_info = folio_to_fs_info(folio);
ASSERT(folio_pos(folio) <= start &&
- start + len <= folio_pos(folio) + PAGE_SIZE);
+ start + len <= folio_pos(folio) + folio_size(folio));
if (uptodate && btrfs_verify_folio(folio, start, len))
btrfs_folio_set_uptodate(fs_info, folio, start, len);
@@ -492,7 +492,7 @@ static void begin_folio_read(struct btrfs_fs_info *fs_info, struct folio *folio)
return;
ASSERT(folio_test_private(folio));
- btrfs_folio_set_lock(fs_info, folio, folio_pos(folio), PAGE_SIZE);
+ btrfs_folio_set_lock(fs_info, folio, folio_pos(folio), folio_size(folio));
}
/*
@@ -753,7 +753,7 @@ static void submit_extent_folio(struct btrfs_bio_ctrl *bio_ctrl,
{
struct btrfs_inode *inode = folio_to_inode(folio);
- ASSERT(pg_offset + size <= PAGE_SIZE);
+ ASSERT(pg_offset + size <= folio_size(folio));
ASSERT(bio_ctrl->end_io_func);
if (bio_ctrl->bbio &&
@@ -935,7 +935,7 @@ static int btrfs_do_readpage(struct folio *folio, struct extent_map **em_cached,
struct inode *inode = folio->mapping->host;
struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
u64 start = folio_pos(folio);
- const u64 end = start + PAGE_SIZE - 1;
+ const u64 end = start + folio_size(folio) - 1;
u64 cur = start;
u64 extent_offset;
u64 last_byte = i_size_read(inode);
@@ -1277,7 +1277,7 @@ static void set_delalloc_bitmap(struct folio *folio, unsigned long *delalloc_bit
unsigned int start_bit;
unsigned int nbits;
- ASSERT(start >= folio_start && start + len <= folio_start + PAGE_SIZE);
+ ASSERT(start >= folio_start && start + len <= folio_start + folio_size(folio));
start_bit = (start - folio_start) >> fs_info->sectorsize_bits;
nbits = len >> fs_info->sectorsize_bits;
ASSERT(bitmap_test_range_all_zero(delalloc_bitmap, start_bit, nbits));
@@ -1295,7 +1295,7 @@ static bool find_next_delalloc_bitmap(struct folio *folio,
unsigned int first_zero;
unsigned int first_set;
- ASSERT(start >= folio_start && start < folio_start + PAGE_SIZE);
+ ASSERT(start >= folio_start && start < folio_start + folio_size(folio));
start_bit = (start - folio_start) >> fs_info->sectorsize_bits;
first_set = find_next_bit(delalloc_bitmap, bitmap_size, start_bit);
@@ -1497,10 +1497,10 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
delalloc_end = page_end;
/*
* delalloc_end is already one less than the total length, so
- * we don't subtract one from PAGE_SIZE
+ * we don't subtract one from folio_size().
*/
delalloc_to_write +=
- DIV_ROUND_UP(delalloc_end + 1 - page_start, PAGE_SIZE);
+ DIV_ROUND_UP(delalloc_end + 1 - page_start, folio_size(folio));
/*
* If all ranges are submitted asynchronously, we just need to account
@@ -1737,7 +1737,7 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl
goto done;
ret = extent_writepage_io(inode, folio, folio_pos(folio),
- PAGE_SIZE, bio_ctrl, i_size);
+ folio_size(folio), bio_ctrl, i_size);
if (ret == 1)
return 0;
if (ret < 0)
@@ -2468,8 +2468,8 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
ASSERT(IS_ALIGNED(start, sectorsize) && IS_ALIGNED(end + 1, sectorsize));
while (cur <= end) {
- u64 cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
- u32 cur_len = cur_end + 1 - cur;
+ u64 cur_end;
+ u32 cur_len;
struct folio *folio;
folio = filemap_get_folio(mapping, cur >> PAGE_SHIFT);
@@ -2479,13 +2479,18 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
* code is just in case, but shouldn't actually be run.
*/
if (IS_ERR(folio)) {
+ cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
+ cur_len = cur_end + 1 - cur;
btrfs_mark_ordered_io_finished(BTRFS_I(inode), NULL,
cur, cur_len, false);
mapping_set_error(mapping, PTR_ERR(folio));
- cur = cur_end + 1;
+ cur = cur_end;
continue;
}
+ cur_end = min(folio_pos(folio) + folio_size(folio) - 1, end);
+ cur_len = cur_end + 1 - cur;
+
ASSERT(folio_test_locked(folio));
if (pages_dirty && folio != locked_folio)
ASSERT(folio_test_dirty(folio));
@@ -2597,7 +2602,7 @@ static bool try_release_extent_state(struct extent_io_tree *tree,
struct folio *folio)
{
u64 start = folio_pos(folio);
- u64 end = start + PAGE_SIZE - 1;
+ u64 end = start + folio_size(folio) - 1;
bool ret;
if (test_range_bit_exists(tree, start, end, EXTENT_LOCKED)) {
@@ -2635,7 +2640,7 @@ static bool try_release_extent_state(struct extent_io_tree *tree,
bool try_release_extent_mapping(struct folio *folio, gfp_t mask)
{
u64 start = folio_pos(folio);
- u64 end = start + PAGE_SIZE - 1;
+ u64 end = start + folio_size(folio) - 1;
struct btrfs_inode *inode = folio_to_inode(folio);
struct extent_io_tree *io_tree = &inode->io_tree;
--
2.48.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [PATCH 5/5] btrfs: prepare btrfs_page_mkwrite() for larger folios
2025-02-20 9:22 [PATCH 0/5] btrfs: prepare for larger folios support Qu Wenruo
` (3 preceding siblings ...)
2025-02-20 9:22 ` [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support Qu Wenruo
@ 2025-02-20 9:22 ` Qu Wenruo
2025-02-21 12:22 ` Johannes Thumshirn
2025-02-21 11:23 ` [PATCH 0/5] btrfs: prepare for larger folios support Johannes Thumshirn
5 siblings, 1 reply; 19+ messages in thread
From: Qu Wenruo @ 2025-02-20 9:22 UTC (permalink / raw)
To: linux-btrfs
This changes the assumption that the folio is always page sized.
(Although the ASSERT() for folio order is still kept as-is).
Just replace the PAGE_SIZE with folio_size().
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
fs/btrfs/file.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 05a70e50ed40..cebe5cb86a8c 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1783,6 +1783,7 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
struct extent_changeset *data_reserved = NULL;
unsigned long zero_start;
loff_t size;
+ size_t fsize = folio_size(folio);
vm_fault_t ret;
int ret2;
int reserved = 0;
@@ -1793,7 +1794,7 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
ASSERT(folio_order(folio) == 0);
- reserved_space = PAGE_SIZE;
+ reserved_space = fsize;
sb_start_pagefault(inode->i_sb);
page_start = folio_pos(folio);
@@ -1847,7 +1848,7 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
* We can't set the delalloc bits if there are pending ordered
* extents. Drop our locks and wait for them to finish.
*/
- ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), page_start, PAGE_SIZE);
+ ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), page_start, fsize);
if (ordered) {
unlock_extent(io_tree, page_start, page_end, &cached_state);
folio_unlock(folio);
@@ -1859,11 +1860,11 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
if (folio->index == ((size - 1) >> PAGE_SHIFT)) {
reserved_space = round_up(size - page_start, fs_info->sectorsize);
- if (reserved_space < PAGE_SIZE) {
+ if (reserved_space < fsize) {
end = page_start + reserved_space - 1;
btrfs_delalloc_release_space(BTRFS_I(inode),
data_reserved, page_start,
- PAGE_SIZE - reserved_space, true);
+ fsize - reserved_space, true);
}
}
@@ -1890,12 +1891,12 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
if (page_start + folio_size(folio) > size)
zero_start = offset_in_folio(folio, size);
else
- zero_start = PAGE_SIZE;
+ zero_start = fsize;
- if (zero_start != PAGE_SIZE)
+ if (zero_start != fsize)
folio_zero_range(folio, zero_start, folio_size(folio) - zero_start);
- btrfs_folio_clear_checked(fs_info, folio, page_start, PAGE_SIZE);
+ btrfs_folio_clear_checked(fs_info, folio, page_start, fsize);
btrfs_folio_set_dirty(fs_info, folio, page_start, end + 1 - page_start);
btrfs_folio_set_uptodate(fs_info, folio, page_start, end + 1 - page_start);
@@ -1904,7 +1905,7 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
unlock_extent(io_tree, page_start, page_end, &cached_state);
up_read(&BTRFS_I(inode)->i_mmap_lock);
- btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+ btrfs_delalloc_release_extents(BTRFS_I(inode), fsize);
sb_end_pagefault(inode->i_sb);
extent_changeset_free(data_reserved);
return VM_FAULT_LOCKED;
@@ -1913,7 +1914,7 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
folio_unlock(folio);
up_read(&BTRFS_I(inode)->i_mmap_lock);
out:
- btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+ btrfs_delalloc_release_extents(BTRFS_I(inode), fsize);
btrfs_delalloc_release_space(BTRFS_I(inode), data_reserved, page_start,
reserved_space, (ret != 0));
out_noreserve:
--
2.48.1
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support
2025-02-20 9:22 ` [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support Qu Wenruo
@ 2025-02-21 11:12 ` kernel test robot
2025-02-21 11:34 ` kernel test robot
` (2 subsequent siblings)
3 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2025-02-21 11:12 UTC (permalink / raw)
To: Qu Wenruo; +Cc: oe-kbuild-all
Hi Qu,
kernel test robot noticed the following build errors:
[auto build test ERROR on kdave/for-next]
[also build test ERROR on next-20250221]
[cannot apply to linus/master v6.14-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Qu-Wenruo/btrfs-prepare-subpage-c-for-larger-folios-support/20250220-172912
base: https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
patch link: https://lore.kernel.org/r/19dfc0e42dce6416b66df114513d18d93b830d17.1740043233.git.wqu%40suse.com
patch subject: [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support
config: arc-randconfig-002-20250221 (https://download.01.org/0day-ci/archive/20250221/202502211908.aCcQQyEY-lkp@intel.com/config)
compiler: arceb-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250221/202502211908.aCcQQyEY-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502211908.aCcQQyEY-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from <command-line>:
fs/btrfs/extent_io.c: In function 'extent_write_locked_range':
>> include/linux/compiler_types.h:542:45: error: call to '__compiletime_assert_439' declared with attribute error: min(folio_pos(folio) + folio_size(folio) - 1, end) signedness error
542 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^
include/linux/compiler_types.h:523:25: note: in definition of macro '__compiletime_assert'
523 | prefix ## suffix(); \
| ^~~~~~
include/linux/compiler_types.h:542:9: note: in expansion of macro '_compiletime_assert'
542 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/minmax.h:93:9: note: in expansion of macro 'BUILD_BUG_ON_MSG'
93 | BUILD_BUG_ON_MSG(!__types_ok(ux, uy), \
| ^~~~~~~~~~~~~~~~
include/linux/minmax.h:98:9: note: in expansion of macro '__careful_cmp_once'
98 | __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_))
| ^~~~~~~~~~~~~~~~~~
include/linux/minmax.h:105:25: note: in expansion of macro '__careful_cmp'
105 | #define min(x, y) __careful_cmp(min, x, y)
| ^~~~~~~~~~~~~
fs/btrfs/extent_io.c:2327:27: note: in expansion of macro 'min'
2327 | cur_end = min(folio_pos(folio) + folio_size(folio) - 1, end);
| ^~~
--
In file included from <command-line>:
extent_io.c: In function 'extent_write_locked_range':
>> include/linux/compiler_types.h:542:45: error: call to '__compiletime_assert_439' declared with attribute error: min(folio_pos(folio) + folio_size(folio) - 1, end) signedness error
542 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^
include/linux/compiler_types.h:523:25: note: in definition of macro '__compiletime_assert'
523 | prefix ## suffix(); \
| ^~~~~~
include/linux/compiler_types.h:542:9: note: in expansion of macro '_compiletime_assert'
542 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/build_bug.h:39:37: note: in expansion of macro 'compiletime_assert'
39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
| ^~~~~~~~~~~~~~~~~~
include/linux/minmax.h:93:9: note: in expansion of macro 'BUILD_BUG_ON_MSG'
93 | BUILD_BUG_ON_MSG(!__types_ok(ux, uy), \
| ^~~~~~~~~~~~~~~~
include/linux/minmax.h:98:9: note: in expansion of macro '__careful_cmp_once'
98 | __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_))
| ^~~~~~~~~~~~~~~~~~
include/linux/minmax.h:105:25: note: in expansion of macro '__careful_cmp'
105 | #define min(x, y) __careful_cmp(min, x, y)
| ^~~~~~~~~~~~~
extent_io.c:2327:27: note: in expansion of macro 'min'
2327 | cur_end = min(folio_pos(folio) + folio_size(folio) - 1, end);
| ^~~
vim +/__compiletime_assert_439 +542 include/linux/compiler_types.h
eb5c2d4b45e3d2 Will Deacon 2020-07-21 528
eb5c2d4b45e3d2 Will Deacon 2020-07-21 529 #define _compiletime_assert(condition, msg, prefix, suffix) \
eb5c2d4b45e3d2 Will Deacon 2020-07-21 530 __compiletime_assert(condition, msg, prefix, suffix)
eb5c2d4b45e3d2 Will Deacon 2020-07-21 531
eb5c2d4b45e3d2 Will Deacon 2020-07-21 532 /**
eb5c2d4b45e3d2 Will Deacon 2020-07-21 533 * compiletime_assert - break build and emit msg if condition is false
eb5c2d4b45e3d2 Will Deacon 2020-07-21 534 * @condition: a compile-time constant condition to check
eb5c2d4b45e3d2 Will Deacon 2020-07-21 535 * @msg: a message to emit if condition is false
eb5c2d4b45e3d2 Will Deacon 2020-07-21 536 *
eb5c2d4b45e3d2 Will Deacon 2020-07-21 537 * In tradition of POSIX assert, this macro will break the build if the
eb5c2d4b45e3d2 Will Deacon 2020-07-21 538 * supplied condition is *false*, emitting the supplied error message if the
eb5c2d4b45e3d2 Will Deacon 2020-07-21 539 * compiler has support to do so.
eb5c2d4b45e3d2 Will Deacon 2020-07-21 540 */
eb5c2d4b45e3d2 Will Deacon 2020-07-21 541 #define compiletime_assert(condition, msg) \
eb5c2d4b45e3d2 Will Deacon 2020-07-21 @542 _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
eb5c2d4b45e3d2 Will Deacon 2020-07-21 543
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/5] btrfs: prepare for larger folios support
2025-02-20 9:22 [PATCH 0/5] btrfs: prepare for larger folios support Qu Wenruo
` (4 preceding siblings ...)
2025-02-20 9:22 ` [PATCH 5/5] btrfs: prepare btrfs_page_mkwrite() for larger folios Qu Wenruo
@ 2025-02-21 11:23 ` Johannes Thumshirn
2025-02-21 12:34 ` Filipe Manana
2025-02-21 22:33 ` Qu Wenruo
5 siblings, 2 replies; 19+ messages in thread
From: Johannes Thumshirn @ 2025-02-21 11:23 UTC (permalink / raw)
To: WenRuo Qu, linux-btrfs@vger.kernel.org
On 20.02.25 10:26, Qu Wenruo wrote:
> Qu Wenruo (5):
> btrfs: prepare subpage.c for larger folios support
> btrfs: remove the PAGE_SIZE usage inside inline extent reads
> btrfs: prepare btrfs_launcher_folio() for larger folios support
> btrfs: prepare extent_io.c for future larger folio support
> btrfs: prepare btrfs_page_mkwrite() for larger folios
>
> fs/btrfs/extent_io.c | 50 +++++++++++++++++++++++++-------------------
> fs/btrfs/file.c | 19 +++++++++--------
> fs/btrfs/inode.c | 8 +++----
> fs/btrfs/subpage.c | 36 +++++++++++++++----------------
> fs/btrfs/subpage.h | 24 ++++++++-------------
> 5 files changed, 69 insertions(+), 68 deletions(-)
>
Hi Qu,
What am I doing wrong?
Applying: btrfs: prepare subpage.c for larger folios support
Applying: btrfs: remove the PAGE_SIZE usage inside inline extent reads
In file included from ./include/linux/kernel.h:28,
from ./include/linux/cpumask.h:11,
from ./include/linux/smp.h:13,
from ./include/linux/lockdep.h:14,
from ./include/linux/spinlock.h:63,
from ./include/linux/swait.h:7,
from ./include/linux/completion.h:12,
from ./include/linux/crypto.h:15,
from ./include/crypto/hash.h:12,
from fs/btrfs/inode.c:6:
fs/btrfs/inode.c: In function ‘uncompress_inline’:
fs/btrfs/inode.c:6807:41: error: ‘sectorsize’ undeclared (first use in
this function); did you mean ‘sector_t’?
6807 | max_size = min_t(unsigned long, sectorsize, max_size);
| ^~~~~~~~~~
./include/linux/minmax.h:86:23: note: in definition of macro
‘__cmp_once_unique’
86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
| ^
./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
| ^~~~~~~~~~
fs/btrfs/inode.c:6807:20: note: in expansion of macro ‘min_t’
6807 | max_size = min_t(unsigned long, sectorsize, max_size);
| ^~~~~
fs/btrfs/inode.c:6807:41: note: each undeclared identifier is reported
only once for each function it appears in
6807 | max_size = min_t(unsigned long, sectorsize, max_size);
| ^~~~~~~~~~
./include/linux/minmax.h:86:23: note: in definition of macro
‘__cmp_once_unique’
86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
| ^
./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
| ^~~~~~~~~~
fs/btrfs/inode.c:6807:20: note: in expansion of macro ‘min_t’
6807 | max_size = min_t(unsigned long, sectorsize, max_size);
| ^~~~~
fs/btrfs/inode.c: In function ‘read_inline_extent’:
fs/btrfs/inode.c:6841:32: error: ‘sectorsize’ undeclared (first use in
this function); did you mean ‘sector_t’?
6841 | copy_size = min_t(u64, sectorsize,
| ^~~~~~~~~~
./include/linux/minmax.h:86:23: note: in definition of macro
‘__cmp_once_unique’
86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
| ^
./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
| ^~~~~~~~~~
fs/btrfs/inode.c:6841:21: note: in expansion of macro ‘min_t’
6841 | copy_size = min_t(u64, sectorsize,
| ^~~~~
make[4]: *** [scripts/Makefile.build:207: fs/btrfs/inode.o] Error 1
make[3]: *** [scripts/Makefile.build:465: fs/btrfs] Error 2
make[2]: *** [scripts/Makefile.build:465: fs] Error 2
make[1]: *** [/home/johannes/src/linux/Makefile:1989: .] Error 2
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support
2025-02-20 9:22 ` [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support Qu Wenruo
2025-02-21 11:12 ` kernel test robot
@ 2025-02-21 11:34 ` kernel test robot
2025-02-21 12:12 ` Johannes Thumshirn
2025-02-25 18:41 ` Nathan Chancellor
3 siblings, 0 replies; 19+ messages in thread
From: kernel test robot @ 2025-02-21 11:34 UTC (permalink / raw)
To: Qu Wenruo; +Cc: llvm, oe-kbuild-all
Hi Qu,
kernel test robot noticed the following build errors:
[auto build test ERROR on kdave/for-next]
[also build test ERROR on next-20250221]
[cannot apply to linus/master v6.14-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Qu-Wenruo/btrfs-prepare-subpage-c-for-larger-folios-support/20250220-172912
base: https://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git for-next
patch link: https://lore.kernel.org/r/19dfc0e42dce6416b66df114513d18d93b830d17.1740043233.git.wqu%40suse.com
patch subject: [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support
config: arm-randconfig-004-20250221 (https://download.01.org/0day-ci/archive/20250221/202502211912.nOgvIfZ9-lkp@intel.com/config)
compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project 204dcafec0ecf0db81d420d2de57b02ada6b09ec)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250221/202502211912.nOgvIfZ9-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202502211912.nOgvIfZ9-lkp@intel.com/
All errors (new ones prefixed by >>):
>> fs/btrfs/extent_io.c:2327:13: error: call to '__compiletime_assert_713' declared with 'error' attribute: min(folio_pos(folio) + folio_size(folio) - 1, end) signedness error
2327 | cur_end = min(folio_pos(folio) + folio_size(folio) - 1, end);
| ^
include/linux/minmax.h:105:19: note: expanded from macro 'min'
105 | #define min(x, y) __careful_cmp(min, x, y)
| ^
include/linux/minmax.h:98:2: note: expanded from macro '__careful_cmp'
98 | __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_))
| ^
include/linux/minmax.h:93:2: note: expanded from macro '__careful_cmp_once'
93 | BUILD_BUG_ON_MSG(!__types_ok(ux, uy), \
| ^
note: (skipping 2 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all)
include/linux/compiler_types.h:530:2: note: expanded from macro '_compiletime_assert'
530 | __compiletime_assert(condition, msg, prefix, suffix)
| ^
include/linux/compiler_types.h:523:4: note: expanded from macro '__compiletime_assert'
523 | prefix ## suffix(); \
| ^
<scratch space>:2:1: note: expanded from here
2 | __compiletime_assert_713
| ^
1 error generated.
vim +2327 fs/btrfs/extent_io.c
2279
2280 /*
2281 * Submit the pages in the range to bio for call sites which delalloc range has
2282 * already been ran (aka, ordered extent inserted) and all pages are still
2283 * locked.
2284 */
2285 void extent_write_locked_range(struct inode *inode, const struct folio *locked_folio,
2286 u64 start, u64 end, struct writeback_control *wbc,
2287 bool pages_dirty)
2288 {
2289 bool found_error = false;
2290 int ret = 0;
2291 struct address_space *mapping = inode->i_mapping;
2292 struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
2293 const u32 sectorsize = fs_info->sectorsize;
2294 loff_t i_size = i_size_read(inode);
2295 u64 cur = start;
2296 struct btrfs_bio_ctrl bio_ctrl = {
2297 .wbc = wbc,
2298 .opf = REQ_OP_WRITE | wbc_to_write_flags(wbc),
2299 };
2300
2301 if (wbc->no_cgroup_owner)
2302 bio_ctrl.opf |= REQ_BTRFS_CGROUP_PUNT;
2303
2304 ASSERT(IS_ALIGNED(start, sectorsize) && IS_ALIGNED(end + 1, sectorsize));
2305
2306 while (cur <= end) {
2307 u64 cur_end;
2308 u32 cur_len;
2309 struct folio *folio;
2310
2311 folio = filemap_get_folio(mapping, cur >> PAGE_SHIFT);
2312
2313 /*
2314 * This shouldn't happen, the pages are pinned and locked, this
2315 * code is just in case, but shouldn't actually be run.
2316 */
2317 if (IS_ERR(folio)) {
2318 cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
2319 cur_len = cur_end + 1 - cur;
2320 btrfs_mark_ordered_io_finished(BTRFS_I(inode), NULL,
2321 cur, cur_len, false);
2322 mapping_set_error(mapping, PTR_ERR(folio));
2323 cur = cur_end;
2324 continue;
2325 }
2326
> 2327 cur_end = min(folio_pos(folio) + folio_size(folio) - 1, end);
2328 cur_len = cur_end + 1 - cur;
2329
2330 ASSERT(folio_test_locked(folio));
2331 if (pages_dirty && folio != locked_folio)
2332 ASSERT(folio_test_dirty(folio));
2333
2334 /*
2335 * Set the submission bitmap to submit all sectors.
2336 * extent_writepage_io() will do the truncation correctly.
2337 */
2338 bio_ctrl.submit_bitmap = (unsigned long)-1;
2339 ret = extent_writepage_io(BTRFS_I(inode), folio, cur, cur_len,
2340 &bio_ctrl, i_size);
2341 if (ret == 1)
2342 goto next_page;
2343
2344 if (ret)
2345 mapping_set_error(mapping, ret);
2346 btrfs_folio_end_lock(fs_info, folio, cur, cur_len);
2347 if (ret < 0)
2348 found_error = true;
2349 next_page:
2350 folio_put(folio);
2351 cur = cur_end + 1;
2352 }
2353
2354 submit_write_bio(&bio_ctrl, found_error ? ret : 0);
2355 }
2356
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/5] btrfs: remove the PAGE_SIZE usage inside inline extent reads
2025-02-20 9:22 ` [PATCH 2/5] btrfs: remove the PAGE_SIZE usage inside inline extent reads Qu Wenruo
@ 2025-02-21 11:37 ` Johannes Thumshirn
0 siblings, 0 replies; 19+ messages in thread
From: Johannes Thumshirn @ 2025-02-21 11:37 UTC (permalink / raw)
To: WenRuo Qu, linux-btrfs@vger.kernel.org
On 20.02.25 10:25, Qu Wenruo wrote:
> The inline extent ram size should never exceed btrfs block size, there
> is no need to clamp the size against PAGE_SIZE.
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
> fs/btrfs/inode.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
> index 3af74f3c5d75..d9ca92d1b927 100644
> --- a/fs/btrfs/inode.c
> +++ b/fs/btrfs/inode.c
> @@ -6784,7 +6784,7 @@ static noinline int uncompress_inline(struct btrfs_path *path,
>
> read_extent_buffer(leaf, tmp, ptr, inline_size);
>
> - max_size = min_t(unsigned long, PAGE_SIZE, max_size);
> + max_size = min_t(unsigned long, sectorsize, max_size);
> ret = btrfs_decompress(compress_type, tmp, folio, 0, inline_size,
> max_size);
>
> @@ -6820,7 +6820,7 @@ static int read_inline_extent(struct btrfs_fs_info *fs_info,
> if (btrfs_file_extent_compression(path->nodes[0], fi) != BTRFS_COMPRESS_NONE)
> return uncompress_inline(path, folio, fi);
>
> - copy_size = min_t(u64, PAGE_SIZE,
> + copy_size = min_t(u64, sectorsize,
> btrfs_file_extent_ram_bytes(path->nodes[0], fi));
> kaddr = kmap_local_folio(folio, 0);
> read_extent_buffer(path->nodes[0], kaddr,
That'll make it compile:
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f94b80d4433d..f64869fad466 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -6788,6 +6788,7 @@ static noinline int uncompress_inline(struct btrfs_path *path,
{
int ret;
struct extent_buffer *leaf = path->nodes[0];
+ u32 sectorsize = leaf->fs_info->sectorsize;
char *tmp;
size_t max_size;
unsigned long inline_size;
@@ -6825,6 +6826,7 @@ static noinline int uncompress_inline(struct btrfs_path *path,
static int read_inline_extent(struct btrfs_path *path, struct folio *folio)
{
struct btrfs_file_extent_item *fi;
+ u32 sectorsize;
void *kaddr;
size_t copy_size;
@@ -6832,6 +6834,7 @@ static int read_inline_extent(struct btrfs_path *path, struct folio *folio)
return 0;
ASSERT(folio_pos(folio) == 0);
+ sectorsize = folio_to_fs_info(folio)->sectorsize;
fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
struct btrfs_file_extent_item);
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 1/5] btrfs: prepare subpage.c for larger folios support
2025-02-20 9:22 ` [PATCH 1/5] btrfs: prepare subpage.c " Qu Wenruo
@ 2025-02-21 12:06 ` Johannes Thumshirn
2025-02-22 5:03 ` Qu Wenruo
0 siblings, 1 reply; 19+ messages in thread
From: Johannes Thumshirn @ 2025-02-21 12:06 UTC (permalink / raw)
To: WenRuo Qu, linux-btrfs@vger.kernel.org
On 20.02.25 10:24, Qu Wenruo wrote:
> For the future of larger folio support, even if block size == page size,
> we may still hit a larger folio and need to attach a subpage structure to
> that larger folio.
>
> In that case we can no longer assume we need to go subpage routine only
> when block size < page size, but take folio size into the consideration.
>
> Prepare for such future by:
>
> - Use folio_size() instead of PAGE_SIZE
> - Make btrfs_alloc_subpage() to handle different folio sizes
> - Make btrfs_is_subpage() to do the check based on the folio
I personally would split this patch in 3 doing the above. Or at least
split out the brtfs_is_subpage() part in another patch.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 3/5] btrfs: prepare btrfs_launcher_folio() for larger folios support
2025-02-20 9:22 ` [PATCH 3/5] btrfs: prepare btrfs_launcher_folio() for larger folios support Qu Wenruo
@ 2025-02-21 12:08 ` Johannes Thumshirn
0 siblings, 0 replies; 19+ messages in thread
From: Johannes Thumshirn @ 2025-02-21 12:08 UTC (permalink / raw)
To: WenRuo Qu, linux-btrfs@vger.kernel.org
On 20.02.25 10:26, Qu Wenruo wrote:
> That function is only calling btrfs_qgroup_free_data(), which doesn't
> care the size of the folio.
about~^
> Just replace the fixed PAGE_SIZE with folio_size().
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support
2025-02-20 9:22 ` [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support Qu Wenruo
2025-02-21 11:12 ` kernel test robot
2025-02-21 11:34 ` kernel test robot
@ 2025-02-21 12:12 ` Johannes Thumshirn
2025-02-22 5:02 ` Qu Wenruo
2025-02-25 18:41 ` Nathan Chancellor
3 siblings, 1 reply; 19+ messages in thread
From: Johannes Thumshirn @ 2025-02-21 12:12 UTC (permalink / raw)
To: WenRuo Qu, linux-btrfs@vger.kernel.org
On 20.02.25 10:24, Qu Wenruo wrote:
> @@ -2468,8 +2468,8 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
> ASSERT(IS_ALIGNED(start, sectorsize) && IS_ALIGNED(end + 1, sectorsize));
>
> while (cur <= end) {
> - u64 cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
> - u32 cur_len = cur_end + 1 - cur;
> + u64 cur_end;
> + u32 cur_len;
> struct folio *folio;
>
> folio = filemap_get_folio(mapping, cur >> PAGE_SHIFT);
> @@ -2479,13 +2479,18 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
> * code is just in case, but shouldn't actually be run.
> */
> if (IS_ERR(folio)) {
> + cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
> + cur_len = cur_end + 1 - cur;
Why is it still using PAGE_SIZE here?
> btrfs_mark_ordered_io_finished(BTRFS_I(inode), NULL,
> cur, cur_len, false);
> mapping_set_error(mapping, PTR_ERR(folio));
> - cur = cur_end + 1;
> + cur = cur_end;
> continue;
> }
>
> + cur_end = min(folio_pos(folio) + folio_size(folio) - 1, end);
> + cur_len = cur_end + 1 - cur;
> +
> ASSERT(folio_test_locked(folio));
> if (pages_dirty && folio != locked_folio)
> ASSERT(folio_test_dirty(folio));
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 5/5] btrfs: prepare btrfs_page_mkwrite() for larger folios
2025-02-20 9:22 ` [PATCH 5/5] btrfs: prepare btrfs_page_mkwrite() for larger folios Qu Wenruo
@ 2025-02-21 12:22 ` Johannes Thumshirn
0 siblings, 0 replies; 19+ messages in thread
From: Johannes Thumshirn @ 2025-02-21 12:22 UTC (permalink / raw)
To: WenRuo Qu, linux-btrfs@vger.kernel.org
Looks good to me,
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/5] btrfs: prepare for larger folios support
2025-02-21 11:23 ` [PATCH 0/5] btrfs: prepare for larger folios support Johannes Thumshirn
@ 2025-02-21 12:34 ` Filipe Manana
2025-02-21 22:33 ` Qu Wenruo
1 sibling, 0 replies; 19+ messages in thread
From: Filipe Manana @ 2025-02-21 12:34 UTC (permalink / raw)
To: Johannes Thumshirn; +Cc: WenRuo Qu, linux-btrfs@vger.kernel.org
On Fri, Feb 21, 2025 at 11:23 AM Johannes Thumshirn
<Johannes.Thumshirn@wdc.com> wrote:
>
> On 20.02.25 10:26, Qu Wenruo wrote:
> > Qu Wenruo (5):
> > btrfs: prepare subpage.c for larger folios support
> > btrfs: remove the PAGE_SIZE usage inside inline extent reads
> > btrfs: prepare btrfs_launcher_folio() for larger folios support
> > btrfs: prepare extent_io.c for future larger folio support
> > btrfs: prepare btrfs_page_mkwrite() for larger folios
> >
> > fs/btrfs/extent_io.c | 50 +++++++++++++++++++++++++-------------------
> > fs/btrfs/file.c | 19 +++++++++--------
> > fs/btrfs/inode.c | 8 +++----
> > fs/btrfs/subpage.c | 36 +++++++++++++++----------------
> > fs/btrfs/subpage.h | 24 ++++++++-------------
> > 5 files changed, 69 insertions(+), 68 deletions(-)
> >
>
> Hi Qu,
> What am I doing wrong?
>
> Applying: btrfs: prepare subpage.c for larger folios support
> Applying: btrfs: remove the PAGE_SIZE usage inside inline extent reads
> In file included from ./include/linux/kernel.h:28,
> from ./include/linux/cpumask.h:11,
> from ./include/linux/smp.h:13,
> from ./include/linux/lockdep.h:14,
> from ./include/linux/spinlock.h:63,
> from ./include/linux/swait.h:7,
> from ./include/linux/completion.h:12,
> from ./include/linux/crypto.h:15,
> from ./include/crypto/hash.h:12,
> from fs/btrfs/inode.c:6:
> fs/btrfs/inode.c: In function ‘uncompress_inline’:
> fs/btrfs/inode.c:6807:41: error: ‘sectorsize’ undeclared (first use in
> this function); did you mean ‘sector_t’?
So this seems to depend on this patchset which introduces that variable:
https://lore.kernel.org/linux-btrfs/cover.1739608189.git.wqu@suse.com/
But that patset depends on other unmerged patches, so not easy to
follow and review.
I was just trying to review that patchset.
> 6807 | max_size = min_t(unsigned long, sectorsize, max_size);
> | ^~~~~~~~~~
> ./include/linux/minmax.h:86:23: note: in definition of macro
> ‘__cmp_once_unique’
> 86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
> | ^
> ./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
> 161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
> | ^~~~~~~~~~
> fs/btrfs/inode.c:6807:20: note: in expansion of macro ‘min_t’
> 6807 | max_size = min_t(unsigned long, sectorsize, max_size);
> | ^~~~~
> fs/btrfs/inode.c:6807:41: note: each undeclared identifier is reported
> only once for each function it appears in
> 6807 | max_size = min_t(unsigned long, sectorsize, max_size);
> | ^~~~~~~~~~
> ./include/linux/minmax.h:86:23: note: in definition of macro
> ‘__cmp_once_unique’
> 86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
> | ^
> ./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
> 161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
> | ^~~~~~~~~~
> fs/btrfs/inode.c:6807:20: note: in expansion of macro ‘min_t’
> 6807 | max_size = min_t(unsigned long, sectorsize, max_size);
> | ^~~~~
> fs/btrfs/inode.c: In function ‘read_inline_extent’:
> fs/btrfs/inode.c:6841:32: error: ‘sectorsize’ undeclared (first use in
> this function); did you mean ‘sector_t’?
> 6841 | copy_size = min_t(u64, sectorsize,
> | ^~~~~~~~~~
> ./include/linux/minmax.h:86:23: note: in definition of macro
> ‘__cmp_once_unique’
> 86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
> | ^
> ./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
> 161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
> | ^~~~~~~~~~
> fs/btrfs/inode.c:6841:21: note: in expansion of macro ‘min_t’
> 6841 | copy_size = min_t(u64, sectorsize,
> | ^~~~~
> make[4]: *** [scripts/Makefile.build:207: fs/btrfs/inode.o] Error 1
> make[3]: *** [scripts/Makefile.build:465: fs/btrfs] Error 2
> make[2]: *** [scripts/Makefile.build:465: fs] Error 2
> make[1]: *** [/home/johannes/src/linux/Makefile:1989: .] Error 2
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 0/5] btrfs: prepare for larger folios support
2025-02-21 11:23 ` [PATCH 0/5] btrfs: prepare for larger folios support Johannes Thumshirn
2025-02-21 12:34 ` Filipe Manana
@ 2025-02-21 22:33 ` Qu Wenruo
1 sibling, 0 replies; 19+ messages in thread
From: Qu Wenruo @ 2025-02-21 22:33 UTC (permalink / raw)
To: Johannes Thumshirn, WenRuo Qu, linux-btrfs@vger.kernel.org
在 2025/2/21 21:53, Johannes Thumshirn 写道:
> On 20.02.25 10:26, Qu Wenruo wrote:
>> Qu Wenruo (5):
>> btrfs: prepare subpage.c for larger folios support
>> btrfs: remove the PAGE_SIZE usage inside inline extent reads
>> btrfs: prepare btrfs_launcher_folio() for larger folios support
>> btrfs: prepare extent_io.c for future larger folio support
>> btrfs: prepare btrfs_page_mkwrite() for larger folios
>>
>> fs/btrfs/extent_io.c | 50 +++++++++++++++++++++++++-------------------
>> fs/btrfs/file.c | 19 +++++++++--------
>> fs/btrfs/inode.c | 8 +++----
>> fs/btrfs/subpage.c | 36 +++++++++++++++----------------
>> fs/btrfs/subpage.h | 24 ++++++++-------------
>> 5 files changed, 69 insertions(+), 68 deletions(-)
>>
>
> Hi Qu,
> What am I doing wrong?
>
> Applying: btrfs: prepare subpage.c for larger folios support
> Applying: btrfs: remove the PAGE_SIZE usage inside inline extent reads
I believe it's missing some dependency.
In fact it looks like it's missing the following patch:
https://lore.kernel.org/linux-btrfs/4e0368b2d4ab74e1a2cef76000ea75cb3198696a.1739608189.git.wqu@suse.com/
I'm sorry but there are too many pending subpage patches, thus it's
harder and harder to properly trace them...
Thanks,
Qu
> In file included from ./include/linux/kernel.h:28,
> from ./include/linux/cpumask.h:11,
> from ./include/linux/smp.h:13,
> from ./include/linux/lockdep.h:14,
> from ./include/linux/spinlock.h:63,
> from ./include/linux/swait.h:7,
> from ./include/linux/completion.h:12,
> from ./include/linux/crypto.h:15,
> from ./include/crypto/hash.h:12,
> from fs/btrfs/inode.c:6:
> fs/btrfs/inode.c: In function ‘uncompress_inline’:
> fs/btrfs/inode.c:6807:41: error: ‘sectorsize’ undeclared (first use in
> this function); did you mean ‘sector_t’?
> 6807 | max_size = min_t(unsigned long, sectorsize, max_size);
> | ^~~~~~~~~~
> ./include/linux/minmax.h:86:23: note: in definition of macro
> ‘__cmp_once_unique’
> 86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
> | ^
> ./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
> 161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
> | ^~~~~~~~~~
> fs/btrfs/inode.c:6807:20: note: in expansion of macro ‘min_t’
> 6807 | max_size = min_t(unsigned long, sectorsize, max_size);
> | ^~~~~
> fs/btrfs/inode.c:6807:41: note: each undeclared identifier is reported
> only once for each function it appears in
> 6807 | max_size = min_t(unsigned long, sectorsize, max_size);
> | ^~~~~~~~~~
> ./include/linux/minmax.h:86:23: note: in definition of macro
> ‘__cmp_once_unique’
> 86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
> | ^
> ./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
> 161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
> | ^~~~~~~~~~
> fs/btrfs/inode.c:6807:20: note: in expansion of macro ‘min_t’
> 6807 | max_size = min_t(unsigned long, sectorsize, max_size);
> | ^~~~~
> fs/btrfs/inode.c: In function ‘read_inline_extent’:
> fs/btrfs/inode.c:6841:32: error: ‘sectorsize’ undeclared (first use in
> this function); did you mean ‘sector_t’?
> 6841 | copy_size = min_t(u64, sectorsize,
> | ^~~~~~~~~~
> ./include/linux/minmax.h:86:23: note: in definition of macro
> ‘__cmp_once_unique’
> 86 | ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); })
> | ^
> ./include/linux/minmax.h:161:27: note: in expansion of macro ‘__cmp_once’
> 161 | #define min_t(type, x, y) __cmp_once(min, type, x, y)
> | ^~~~~~~~~~
> fs/btrfs/inode.c:6841:21: note: in expansion of macro ‘min_t’
> 6841 | copy_size = min_t(u64, sectorsize,
> | ^~~~~
> make[4]: *** [scripts/Makefile.build:207: fs/btrfs/inode.o] Error 1
> make[3]: *** [scripts/Makefile.build:465: fs/btrfs] Error 2
> make[2]: *** [scripts/Makefile.build:465: fs] Error 2
> make[1]: *** [/home/johannes/src/linux/Makefile:1989: .] Error 2
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support
2025-02-21 12:12 ` Johannes Thumshirn
@ 2025-02-22 5:02 ` Qu Wenruo
0 siblings, 0 replies; 19+ messages in thread
From: Qu Wenruo @ 2025-02-22 5:02 UTC (permalink / raw)
To: Johannes Thumshirn, WenRuo Qu, linux-btrfs@vger.kernel.org
在 2025/2/21 22:42, Johannes Thumshirn 写道:
> On 20.02.25 10:24, Qu Wenruo wrote:
>> @@ -2468,8 +2468,8 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
>> ASSERT(IS_ALIGNED(start, sectorsize) && IS_ALIGNED(end + 1, sectorsize));
>>
>> while (cur <= end) {
>> - u64 cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
>> - u32 cur_len = cur_end + 1 - cur;
>> + u64 cur_end;
>> + u32 cur_len;
>> struct folio *folio;
>>
>> folio = filemap_get_folio(mapping, cur >> PAGE_SHIFT);
>> @@ -2479,13 +2479,18 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
>> * code is just in case, but shouldn't actually be run.
>> */
>> if (IS_ERR(folio)) {
>> + cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
>> + cur_len = cur_end + 1 - cur;
>
> Why is it still using PAGE_SIZE here?
This is because we are at a failure path where there is no folio.
But we still want to skip to the next slot (may or may not exist
though), so we have to increase the bytenr by the minimal unit of
filemap, which is still a page.
Thanks,
Qu
>
>> btrfs_mark_ordered_io_finished(BTRFS_I(inode), NULL,
>> cur, cur_len, false);
>> mapping_set_error(mapping, PTR_ERR(folio));
>> - cur = cur_end + 1;
>> + cur = cur_end;
>> continue;
>> }
>>
>> + cur_end = min(folio_pos(folio) + folio_size(folio) - 1, end);
>> + cur_len = cur_end + 1 - cur;
>> +
>> ASSERT(folio_test_locked(folio));
>> if (pages_dirty && folio != locked_folio)
>> ASSERT(folio_test_dirty(folio));
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/5] btrfs: prepare subpage.c for larger folios support
2025-02-21 12:06 ` Johannes Thumshirn
@ 2025-02-22 5:03 ` Qu Wenruo
0 siblings, 0 replies; 19+ messages in thread
From: Qu Wenruo @ 2025-02-22 5:03 UTC (permalink / raw)
To: Johannes Thumshirn, WenRuo Qu, linux-btrfs@vger.kernel.org
在 2025/2/21 22:36, Johannes Thumshirn 写道:
> On 20.02.25 10:24, Qu Wenruo wrote:
>> For the future of larger folio support, even if block size == page size,
>> we may still hit a larger folio and need to attach a subpage structure to
>> that larger folio.
>>
>> In that case we can no longer assume we need to go subpage routine only
>> when block size < page size, but take folio size into the consideration.
>>
>> Prepare for such future by:
>>
>> - Use folio_size() instead of PAGE_SIZE
>> - Make btrfs_alloc_subpage() to handle different folio sizes
>> - Make btrfs_is_subpage() to do the check based on the folio
>
> I personally would split this patch in 3 doing the above. Or at least
> split out the brtfs_is_subpage() part in another patch.
>
Sure, and the next update will only be sent after all the dependency got
merged into for-next branch.
Thanks,
Qu
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support
2025-02-20 9:22 ` [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support Qu Wenruo
` (2 preceding siblings ...)
2025-02-21 12:12 ` Johannes Thumshirn
@ 2025-02-25 18:41 ` Nathan Chancellor
3 siblings, 0 replies; 19+ messages in thread
From: Nathan Chancellor @ 2025-02-25 18:41 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
On Thu, Feb 20, 2025 at 07:52:25PM +1030, Qu Wenruo wrote:
> When we're handling folios from filemap, we can no longer assume all
> folios are page sized.
>
> Thus for call sites assuming the folio is page sized, change the
> PAGE_SIZE usage to folio_size() instead.
>
> Signed-off-by: Qu Wenruo <wqu@suse.com>
> ---
> fs/btrfs/extent_io.c | 33 +++++++++++++++++++--------------
> 1 file changed, 19 insertions(+), 14 deletions(-)
>
> diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
> index e1efb6419601..88bac9a32919 100644
> --- a/fs/btrfs/extent_io.c
> +++ b/fs/btrfs/extent_io.c
> @@ -425,7 +425,7 @@ static void end_folio_read(struct folio *folio, bool uptodate, u64 start, u32 le
> struct btrfs_fs_info *fs_info = folio_to_fs_info(folio);
>
> ASSERT(folio_pos(folio) <= start &&
> - start + len <= folio_pos(folio) + PAGE_SIZE);
> + start + len <= folio_pos(folio) + folio_size(folio));
>
> if (uptodate && btrfs_verify_folio(folio, start, len))
> btrfs_folio_set_uptodate(fs_info, folio, start, len);
> @@ -492,7 +492,7 @@ static void begin_folio_read(struct btrfs_fs_info *fs_info, struct folio *folio)
> return;
>
> ASSERT(folio_test_private(folio));
> - btrfs_folio_set_lock(fs_info, folio, folio_pos(folio), PAGE_SIZE);
> + btrfs_folio_set_lock(fs_info, folio, folio_pos(folio), folio_size(folio));
> }
>
> /*
> @@ -753,7 +753,7 @@ static void submit_extent_folio(struct btrfs_bio_ctrl *bio_ctrl,
> {
> struct btrfs_inode *inode = folio_to_inode(folio);
>
> - ASSERT(pg_offset + size <= PAGE_SIZE);
> + ASSERT(pg_offset + size <= folio_size(folio));
> ASSERT(bio_ctrl->end_io_func);
>
> if (bio_ctrl->bbio &&
> @@ -935,7 +935,7 @@ static int btrfs_do_readpage(struct folio *folio, struct extent_map **em_cached,
> struct inode *inode = folio->mapping->host;
> struct btrfs_fs_info *fs_info = inode_to_fs_info(inode);
> u64 start = folio_pos(folio);
> - const u64 end = start + PAGE_SIZE - 1;
> + const u64 end = start + folio_size(folio) - 1;
> u64 cur = start;
> u64 extent_offset;
> u64 last_byte = i_size_read(inode);
> @@ -1277,7 +1277,7 @@ static void set_delalloc_bitmap(struct folio *folio, unsigned long *delalloc_bit
> unsigned int start_bit;
> unsigned int nbits;
>
> - ASSERT(start >= folio_start && start + len <= folio_start + PAGE_SIZE);
> + ASSERT(start >= folio_start && start + len <= folio_start + folio_size(folio));
> start_bit = (start - folio_start) >> fs_info->sectorsize_bits;
> nbits = len >> fs_info->sectorsize_bits;
> ASSERT(bitmap_test_range_all_zero(delalloc_bitmap, start_bit, nbits));
> @@ -1295,7 +1295,7 @@ static bool find_next_delalloc_bitmap(struct folio *folio,
> unsigned int first_zero;
> unsigned int first_set;
>
> - ASSERT(start >= folio_start && start < folio_start + PAGE_SIZE);
> + ASSERT(start >= folio_start && start < folio_start + folio_size(folio));
>
> start_bit = (start - folio_start) >> fs_info->sectorsize_bits;
> first_set = find_next_bit(delalloc_bitmap, bitmap_size, start_bit);
> @@ -1497,10 +1497,10 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
> delalloc_end = page_end;
> /*
> * delalloc_end is already one less than the total length, so
> - * we don't subtract one from PAGE_SIZE
> + * we don't subtract one from folio_size().
> */
> delalloc_to_write +=
> - DIV_ROUND_UP(delalloc_end + 1 - page_start, PAGE_SIZE);
> + DIV_ROUND_UP(delalloc_end + 1 - page_start, folio_size(folio));
>
> /*
> * If all ranges are submitted asynchronously, we just need to account
> @@ -1737,7 +1737,7 @@ static int extent_writepage(struct folio *folio, struct btrfs_bio_ctrl *bio_ctrl
> goto done;
>
> ret = extent_writepage_io(inode, folio, folio_pos(folio),
> - PAGE_SIZE, bio_ctrl, i_size);
> + folio_size(folio), bio_ctrl, i_size);
> if (ret == 1)
> return 0;
> if (ret < 0)
> @@ -2468,8 +2468,8 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
> ASSERT(IS_ALIGNED(start, sectorsize) && IS_ALIGNED(end + 1, sectorsize));
>
> while (cur <= end) {
> - u64 cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
> - u32 cur_len = cur_end + 1 - cur;
> + u64 cur_end;
> + u32 cur_len;
> struct folio *folio;
>
> folio = filemap_get_folio(mapping, cur >> PAGE_SHIFT);
> @@ -2479,13 +2479,18 @@ void extent_write_locked_range(struct inode *inode, const struct folio *locked_f
> * code is just in case, but shouldn't actually be run.
> */
> if (IS_ERR(folio)) {
> + cur_end = min(round_down(cur, PAGE_SIZE) + PAGE_SIZE - 1, end);
> + cur_len = cur_end + 1 - cur;
> btrfs_mark_ordered_io_finished(BTRFS_I(inode), NULL,
> cur, cur_len, false);
> mapping_set_error(mapping, PTR_ERR(folio));
> - cur = cur_end + 1;
> + cur = cur_end;
> continue;
> }
>
> + cur_end = min(folio_pos(folio) + folio_size(folio) - 1, end);
As the kernel test robot points out, this breaks the build for 32-bit
targets in -next because folio_pos() returns loff_t and folio_size()
returns size_t, which is 'unsigned int' for 32-bit instead of 'unsigned
long', so the whole expression gets promoted to 'long long' from the
loff_t, mismatching the sign of end. I just silenced it with a cast to
u64 before folio_pos() but that is likely incorrect as a formal fix,
hence just the extra comment.
> + cur_len = cur_end + 1 - cur;
> +
> ASSERT(folio_test_locked(folio));
> if (pages_dirty && folio != locked_folio)
> ASSERT(folio_test_dirty(folio));
> @@ -2597,7 +2602,7 @@ static bool try_release_extent_state(struct extent_io_tree *tree,
> struct folio *folio)
> {
> u64 start = folio_pos(folio);
> - u64 end = start + PAGE_SIZE - 1;
> + u64 end = start + folio_size(folio) - 1;
> bool ret;
>
> if (test_range_bit_exists(tree, start, end, EXTENT_LOCKED)) {
> @@ -2635,7 +2640,7 @@ static bool try_release_extent_state(struct extent_io_tree *tree,
> bool try_release_extent_mapping(struct folio *folio, gfp_t mask)
> {
> u64 start = folio_pos(folio);
> - u64 end = start + PAGE_SIZE - 1;
> + u64 end = start + folio_size(folio) - 1;
> struct btrfs_inode *inode = folio_to_inode(folio);
> struct extent_io_tree *io_tree = &inode->io_tree;
>
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2025-02-25 18:41 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-20 9:22 [PATCH 0/5] btrfs: prepare for larger folios support Qu Wenruo
2025-02-20 9:22 ` [PATCH 1/5] btrfs: prepare subpage.c " Qu Wenruo
2025-02-21 12:06 ` Johannes Thumshirn
2025-02-22 5:03 ` Qu Wenruo
2025-02-20 9:22 ` [PATCH 2/5] btrfs: remove the PAGE_SIZE usage inside inline extent reads Qu Wenruo
2025-02-21 11:37 ` Johannes Thumshirn
2025-02-20 9:22 ` [PATCH 3/5] btrfs: prepare btrfs_launcher_folio() for larger folios support Qu Wenruo
2025-02-21 12:08 ` Johannes Thumshirn
2025-02-20 9:22 ` [PATCH 4/5] btrfs: prepare extent_io.c for future larger folio support Qu Wenruo
2025-02-21 11:12 ` kernel test robot
2025-02-21 11:34 ` kernel test robot
2025-02-21 12:12 ` Johannes Thumshirn
2025-02-22 5:02 ` Qu Wenruo
2025-02-25 18:41 ` Nathan Chancellor
2025-02-20 9:22 ` [PATCH 5/5] btrfs: prepare btrfs_page_mkwrite() for larger folios Qu Wenruo
2025-02-21 12:22 ` Johannes Thumshirn
2025-02-21 11:23 ` [PATCH 0/5] btrfs: prepare for larger folios support Johannes Thumshirn
2025-02-21 12:34 ` Filipe Manana
2025-02-21 22:33 ` Qu Wenruo
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.