diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 03337fa7a61c..bfb8e98d8c02 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -480,13 +480,15 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, ASSERT(size <= sectorsize); /* - * The compressed size also needs to be no larger than a sector. - * That's also why we only need one page as the parameter. + * The compressed size also needs to be no larger than a page. + * That's also why we only need one folio as the parameter. */ - if (compressed_folio) + if (compressed_folio) { ASSERT(compressed_size <= sectorsize); - else + ASSERT(compressed_size <= PAGE_SIZE); + } else { ASSERT(compressed_size == 0); + } if (compressed_size && compressed_folio) cur_size = compressed_size; @@ -573,6 +575,18 @@ static bool can_cow_file_range_inline(struct btrfs_inode *inode, if (offset != 0) return false; + /* + * Even for bs > ps cases, cow_file_range_inline() can only accept a + * single folio. + * + * This can be problematic and cause access beyond page boundary if a + * page sized folio is passed into that function. + * And encoded write is doing exactly that. + * So here limits the inlined extent size to PAGE_SIZE. + */ + if (size > PAGE_SIZE || compressed_size > PAGE_SIZE) + return false; + /* Inline extents are limited to sectorsize. */ if (size > fs_info->sectorsize) return false;