Patch "[PATCH 117/135] btrfs: Continue write in case of can_not_nocow" has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
[PATCH 117/135] btrfs: Continue write in case of can_not_nocow
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
0117-btrfs-Continue-write-in-case-of-can_not_nocow.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
0994008d55c250e6b9106bae4b01cce793fbdfb2Mon Sep 17 00:00:00 2001
From: Zhao Lei <[email protected]>
Date: Fri, 27 May 2016 14:59:00 -0400
Subject: [PATCH 117/135] btrfs: Continue write in case of can_not_nocow
[ Upstream commit 4da2e26a2a32b174878744bd0f07db180c875f26 ]
btrfs failed in xfstests btrfs/080 with -o nodatacow.
Can be reproduced by following script:
DEV=/dev/vdg
MNT=/mnt/tmp
umount $DEV &>/dev/null
mkfs.btrfs -f $DEV
mount -o nodatacow $DEV $MNT
dd if=/dev/zero of=$MNT/test bs=1 count=2048 & btrfs subvolume snapshot -r $MNT $MNT/test_snap & wait
--
We can see dd failed on NO_SPACE.
Reason:
__btrfs_buffered_write should run cow write when no_cow impossible, and current code is designed with above logic.
But check_can_nocow() have 2 type of return value(0 and <0) on can_not_no_cow, and current code only continue write on first case, the second case happened in doing subvolume.
Fix:
Continue write when check_can_nocow() return 0 and <0.
--- fs/btrfs/file.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-)
fs/btrfs/file.c +17 -20
@@ -1526,27 +1526,24 @@ static noinline ssize_t __btrfs_buffered reserve_bytes = num_pages <<PAGE_CACHE_SHIFT ; -if (BTRFS_I (inode)->flags & (BTRFS_INODE_NODATACOW | -BTRFS_INODE_PREALLOC )) { - ret =check_can_nocow (inode, pos, &write_bytes); -if (ret <0 ) -break ; -if (ret >0 ) { -/* -* For nodata cow case, no need to reserve -* data space. -*/ - only_release_metadata = true; -/* -* our prealloc extent may be smaller than -* write_bytes, so scale down. -*/ - num_pages =DIV_ROUND_UP (write_bytes + offset, -PAGE_CACHE_SIZE ); - reserve_bytes = num_pages <<PAGE_CACHE_SHIFT ; - goto reserve_metadata; - } +if ((BTRFS_I (inode)->flags & (BTRFS_INODE_NODATACOW | +BTRFS_INODE_PREALLOC )) && +check_can_nocow (inode, pos, &write_bytes) >0 ) { +/* +* For nodata cow case, no need to reserve +* data space. +*/ + only_release_metadata = true; +/* +* our prealloc extent may be smaller than +* write_bytes, so scale down. +*/ + num_pages =DIV_ROUND_UP (write_bytes + offset, +PAGE_CACHE_SIZE ); + reserve_bytes = num_pages <<PAGE_CACHE_SHIFT ; + goto reserve_metadata; } + ret =btrfs_check_data_free_space (inode, pos, write_bytes);if (ret <0 )break ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/0117-btrfs-Continue-write-in-case-of-can_not_nocow.patch