[3.16.y-ckt stable] Patch "btrfs: skip waiting on ordered range for special files" has been added to staging queue

Kamal Mostafa kamal at canonical.com
Mon Oct 26 21:14:06 UTC 2015


This is a note to let you know that I have just added a patch titled

    btrfs: skip waiting on ordered range for special files

to the linux-3.16.y-queue branch of the 3.16.y-ckt extended stable tree 
which can be found at:

    http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.16.y-queue

This patch is scheduled to be released in version 3.19.8-ckt9.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.16.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

>From a6d10b34a45210bdb5e84dd2bab45ba932d6301c Mon Sep 17 00:00:00 2001
From: Jeff Mahoney <jeffm at suse.com>
Date: Fri, 11 Sep 2015 21:44:17 -0400
Subject: btrfs: skip waiting on ordered range for special files

commit a30e577c96f59b1e1678ea5462432b09bf7d5cbc upstream.

In btrfs_evict_inode, we properly truncate the page cache for evicted
inodes but then we call btrfs_wait_ordered_range for every inode as well.
It's the right thing to do for regular files but results in incorrect
behavior for device inodes for block devices.

filemap_fdatawrite_range gets called with inode->i_mapping which gets
resolved to the block device inode before getting passed to
wbc_attach_fdatawrite_inode and ultimately to inode_to_bdi.  What happens
next depends on whether there's an open file handle associated with the
inode.  If there is, we write to the block device, which is unexpected
behavior.  If there isn't, we through normally and inode->i_data is used.
We can also end up racing against open/close which can result in crashes
when i_mapping points to a block device inode that has been closed.

Since there can't be any page cache associated with special file inodes,
it's safe to skip the btrfs_wait_ordered_range call entirely and avoid
the problem.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=100911
Tested-by: Christoph Biedl <linux-kernel.bfrz at manchmal.in-ulm.de>
Signed-off-by: Jeff Mahoney <jeffm at suse.com>
Reviewed-by: Filipe Manana <fdmanana at suse.com>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
 fs/btrfs/inode.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 35911f0..fbcd590 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4854,7 +4854,8 @@ void btrfs_evict_inode(struct inode *inode)
 		goto no_delete;
 	}
 	/* do we really want it for ->i_nlink > 0 and zero btrfs_root_refs? */
-	btrfs_wait_ordered_range(inode, 0, (u64)-1);
+	if (!special_file(inode->i_mode))
+		btrfs_wait_ordered_range(inode, 0, (u64)-1);

 	btrfs_free_io_failure_record(inode, 0, (u64)-1);

--
1.9.1





More information about the kernel-team mailing list