Skip to contentSkip to conversation

Patch "[PATCH 117/135] btrfs: Continue write in case of can_not_nocow" has been added to the 4.4-stable tree

PATCH [email protected] 1 participant 1 message Sep 9, 2016

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

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 0994008d55c250e6b9106bae4b01cce793fbdfb2 Mon 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