File btrfs-progs-convert-fix-inline-file-extent-creation-condition.patch of Package btrfsprogs.5036
From: Qu Wenruo <wqu@suse.com>
Subject: btrfs-progs: convert: Fix inline file extent creation condition
Git-commit: e02049d964e77d22348bf940a7027a1aff558f18
Patch-mainline: v4.16
References: bsc#1042369
[Bug]
On btrfs converted from ext*, one user reported the following kernel
warning:
------------[ cut here ]------------
BTRFS: Transaction aborted (error -95)
WARNING: CPU: 0 PID: 324 at fs/btrfs/inode.c:3042 btrfs_finish_ordered_io+0x7ab/0x850 [btrfs]
Workqueue: btrfs-endio-write btrfs_endio_write_helper [btrfs]
RIP: 0010:btrfs_finish_ordered_io+0x7ab/0x850 [btrfs]
...
Call Trace:
normal_work_helper+0x39/0x370 [btrfs]
process_one_work+0x1ce/0x410
worker_thread+0x2b/0x3d0
? process_one_work+0x410/0x410
kthread+0x113/0x130
? kthread_create_on_node+0x70/0x70
? do_syscall_64+0x74/0x190
? SyS_exit_group+0x10/0x10
ret_from_fork+0x35/0x40
---[ end trace c8ed62ff6a525901 ]---
BTRFS: error (device dm-2) in
btrfs_finish_ordered_io:3042: errno=-95 unknown
BTRFS info (device dm-2): forced readonly
BTRFS error (device dm-2): pending csums is 6447104
[Cause]
The call trace and the unique return value points to
__btrfs_drop_extents(), when we tries to drop pages of an inline extent,
we will trigger such -EOPNOTSUPP.
However kernel has limitation on the size of inline file extent
(sector size for ram size and sector size - 1 for on-disk size),
btrfs-convert doesn't have the same limitation, resulting much larger
file extent.
The lack of correct inline extent size check dates back to 2008 when
btrfs-convert is added into btrfs-progs.
[Fix]
Fix the inline extent creation condition, not only using
BTRFS_MAX_INLINE_DATA_SIZE(), which is only the maximum size of inline
data according to nodesize, but also limit it against sector size.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Acked-by: Jeff Mahoney <jeffm@suse.com>
---
convert/source-ext2.c | 2 +-
convert/source-reiserfs.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/btrfs-convert.c b/btrfs-convert.c
index 070126ec..a2af1212 100644
--- a/btrfs-convert.c
+++ b/btrfs-convert.c
@@ -310,6 +310,7 @@ static int ext2_create_file_extents(struct btrfs_trans_handle *trans,
if (ret)
goto fail;
if (packing && data.first_block == 0 && data.num_blocks > 0 &&
+ inode_size < sectorsize &&
inode_size <= BTRFS_MAX_INLINE_DATA_SIZE(root)) {
u64 num_bytes = data.num_blocks * sectorsize;
u64 disk_bytenr = data.disk_block * sectorsize;
@@ -376,7 +376,8 @@ static int reiserfs_convert_tail(struct btrfs_trans_handle *trans,
goto fail;
}
if (data.inline_length) {
- if (data.inline_length < BTRFS_MAX_INLINE_DATA_SIZE(root)) {
+ if (data.inline_length < BTRFS_MAX_INLINE_DATA_SIZE(root) &&
+ data.inline_length < root->sectorsize) {
int isize;
ret = btrfs_insert_inline_extent(trans, root,
objectid,