FAILED: patch "[PATCH] Btrfs: fix unexpected cow in run_delalloc_nocow" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
5811375325420052fcadd944792a416a43072b7fMon Sep 17 00:00:00 2001
From: Liu Bo <[email protected]>
Date: Wed, 31 Jan 2018 17:09:13 -0700
Subject: [PATCH] Btrfs: fix unexpected cow in run_delalloc_nocow
Fstests generic/475 provides a way to fail metadata reads while checking if checksum exists for the inode inside run_delalloc_nocow(), and csum_exist_in_range() interprets error (-EIO) as inode having checksum and makes its caller enter the cow path.
In case of free space inode, this ends up with a warning in cow_file_range().
The same problem applies to btrfs_cross_ref_exist() since it may also read metadata in between.
With this, run_delalloc_nocow() bails out when errors occur at the two places.
fs/btrfs/inode.c +32 -5
@@ -1256,6 +1256,8 @@ static noinline int csum_exist_in_range(struct btrfs_fs_info *fs_info,list_del (&sums->list);kfree (sums); } +if (ret <0 ) +return ret;return 1 ; }
@@ -1388,10 +1390,23 @@ static noinline int run_delalloc_nocow(struct inode *inode, goto out_check;if (btrfs_extent_readonly (fs_info, disk_bytenr)) goto out_check; -if (btrfs_cross_ref_exist (root, ino, - found_key.offset - - extent_offset, disk_bytenr)) + ret =btrfs_cross_ref_exist (root, ino, + found_key.offset - + extent_offset, disk_bytenr); +if (ret) { +/* +* ret could be -EIO if the above fails to read +* metadata. +*/ +if (ret <0 ) { +if (cow_start != (u64)-1 ) + cur_offset = cow_start; + goto error; + } + +WARN_ON_ONCE (nolock); goto out_check; + } disk_bytenr += extent_offset; disk_bytenr += cur_offset - found_key.offset; num_bytes =min (end +1 , extent_end) - cur_offset;
@@ -1409,10 +1424,22 @@ static noinline int run_delalloc_nocow(struct inode *inode,* this ensure that csum for a given extent are * either valid or do not exist. */ -if (csum_exist_in_range (fs_info, disk_bytenr, - num_bytes)) { + ret =csum_exist_in_range (fs_info, disk_bytenr, + num_bytes); +if (ret) {if (!nolock)btrfs_end_write_no_snapshotting (root); + +/* +* ret could be -EIO if the above fails to read +* metadata. +*/ +if (ret <0 ) { +if (cow_start != (u64)-1 ) + cur_offset = cow_start; + goto error; + } +WARN_ON_ONCE (nolock); goto out_check; }if (!btrfs_inc_nocow_writers (fs_info, disk_bytenr)) {
Hi Greg,
Quoted 5 lines · On Fri, Apr 06, 2018 at 09:12:20AM +0200, [email protected] wrote:
The patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
The attached backported patch should apply on v4.4-stable.
--
Regards
Sudip
Quoted 1 line
From
0d781e5d1dc8428439987ce853d294967e5d16afMon Sep 17 00:00:00 2001
From: Liu Bo <[email protected]>
Date: Wed, 31 Jan 2018 17:09:13 -0700
Subject: [PATCH] Btrfs: fix unexpected cow in run_delalloc_nocow
commit 5811375325420052fcadd944792a416a43072b7f upstream
Fstests generic/475 provides a way to fail metadata reads while checking if checksum exists for the inode inside run_delalloc_nocow(), and csum_exist_in_range() interprets error (-EIO) as inode having checksum and makes its caller enter the cow path.
In case of free space inode, this ends up with a warning in cow_file_range().
The same problem applies to btrfs_cross_ref_exist() since it may also read metadata in between.
With this, run_delalloc_nocow() bails out when errors occur at the two places.
--- fs/btrfs/inode.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-)
fs/btrfs/inode.c +30 -3
@@ -1202,6 +1202,8 @@ static noinline int csum_exist_in_range(struct btrfs_root *root,list_del (&sums->list);kfree (sums); } +if (ret <0 ) +return ret;return 1 ; }
@@ -1351,10 +1353,23 @@ next_slot: goto out_check;if (btrfs_extent_readonly (root, disk_bytenr)) goto out_check; -if (btrfs_cross_ref_exist (trans, root, ino, + ret =btrfs_cross_ref_exist (trans, root, ino, found_key.offset - - extent_offset, disk_bytenr)) + extent_offset, disk_bytenr); +if (ret) { +/* +* ret could be -EIO if the above fails to read +* metadata. +*/ +if (ret <0 ) { +if (cow_start != (u64)-1 ) + cur_offset = cow_start; + goto error; + } + +WARN_ON_ONCE (nolock); goto out_check; + } disk_bytenr += extent_offset; disk_bytenr += cur_offset - found_key.offset; num_bytes =min (end +1 , extent_end) - cur_offset;
@@ -1372,8 +1387,20 @@ next_slot:* this ensure that csum for a given extent are * either valid or do not exist. */ -if (csum_exist_in_range (root, disk_bytenr, num_bytes)) + ret =csum_exist_in_range (root, disk_bytenr, num_bytes); +if (ret) { +/* +* ret could be -EIO if the above fails to read +* metadata. +*/ +if (ret <0 ) { +if (cow_start != (u64)-1 ) + cur_offset = cow_start; + goto error; + } +WARN_ON_ONCE (nolock); goto out_check; + } nocow =1 ; }else if (extent_type ==BTRFS_FILE_EXTENT_INLINE ) { extent_end = found_key.offset +
Signature · 1 line
2.11.0
Greg KH
maintainerQuoted 10 lines · Sudip Mukherjee
Hi Greg,
Quoted 5 lines · On Fri, Apr 06, 2018 at 09:12:20AM +0200, [email protected] wrote:
The patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.The attached backported patch should apply on v4.4-stable.
Now applied, thanks.
greg k-h