From: Zhihao Cheng chengzhihao1@huawei.com
hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IAHY3K
--------------------------------
Since commit 9aac777aaf94 ("filemap: Convert generic_perform_write() to support large folios"), write_begin() could get a range of data cross two pages, which triggers the WARNON in ext4_iomap_write_begin(): WARN_ON_ONCE(pos + len > folio_pos(folio) + folio_size(folio))
Since generic_perform_write() will cut the copy length within a page, fix the problem by cutting the data length within a page in ext4_iomap_write_begin(),
Fixes: 9aac777aaf94 ("filemap: Convert generic_perform_write() to support large folios") Signed-off-by: Zhihao Cheng chengzhihao1@huawei.com Signed-off-by: Liu Shixin liushixin2@huawei.com --- fs/ext4/inode.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index f9d5291db42b..270c4e3e820f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3976,18 +3976,19 @@ static int ext4_iomap_write_begin(struct file *file, *fsdata = delalloc ? (void *)0 : (void *)FALL_BACK_TO_NONDELALLOC;
retry: - iter.pos = pos; - iter.len = len; - folio = iomap_get_folio(&iter, pos, len); if (IS_ERR(folio)) return PTR_ERR(folio);
- WARN_ON_ONCE(pos + len > folio_pos(folio) + folio_size(folio)); + if (pos + len > folio_pos(folio) + folio_size(folio)) + len = folio_pos(folio) + folio_size(folio) - pos;
if (iomap_is_fully_dirty(folio, offset_in_folio(folio, pos), len)) goto out;
+ iter.pos = pos; + iter.len = len; + do { int length;