From: Greg Kroah-Hartman Date: Fri, 24 Feb 2017 08:27:47 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.52~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=230409cea370abf5c3b236720dc70a3777ed0358;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: xfs-clear-delalloc-and-cache-on-buffered-write-failure.patch --- diff --git a/queue-4.9/series b/queue-4.9/series index 0691bc174e6..0e2df40a17c 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -29,3 +29,4 @@ netfilter-nf_ct_helper-warn-when-not-applying-default-helper-assignment.patch acpica-linuxize-restore-and-fix-intel-compiler-build.patch block-fix-double-free-in-the-failure-path-of-cgwb_bdi_init.patch rtlwifi-rtl_usb-fix-for-urb-leaking-when-doing-ifconfig-up-down.patch +xfs-clear-delalloc-and-cache-on-buffered-write-failure.patch diff --git a/queue-4.9/xfs-clear-delalloc-and-cache-on-buffered-write-failure.patch b/queue-4.9/xfs-clear-delalloc-and-cache-on-buffered-write-failure.patch new file mode 100644 index 00000000000..9f982cc6e4e --- /dev/null +++ b/queue-4.9/xfs-clear-delalloc-and-cache-on-buffered-write-failure.patch @@ -0,0 +1,66 @@ +From fa7f138ac4c70dc00519c124cf7cd4862a0a5b0e Mon Sep 17 00:00:00 2001 +From: Brian Foster +Date: Thu, 16 Feb 2017 17:19:12 -0800 +Subject: xfs: clear delalloc and cache on buffered write failure + +From: Brian Foster + +commit fa7f138ac4c70dc00519c124cf7cd4862a0a5b0e upstream. + +The buffered write failure handling code in +xfs_file_iomap_end_delalloc() has a couple minor problems. First, if +written == 0, start_fsb is not rounded down and it fails to kill off a +delalloc block if the start offset is block unaligned. This results in a +lingering delalloc block and broken delalloc block accounting detected +at unmount time. Fix this by rounding down start_fsb in the unlikely +event that written == 0. + +Second, it is possible for a failed overwrite of a delalloc extent to +leave dirty pagecache around over a hole in the file. This is because is +possible to hit ->iomap_end() on write failure before the iomap code has +attempted to allocate pagecache, and thus has no need to clean it up. If +the targeted delalloc extent was successfully written by a previous +write, however, then it does still have dirty pages when ->iomap_end() +punches out the underlying blocks. This ultimately results in writeback +over a hole. To fix this problem, unconditionally punch out the +pagecache from XFS before the associated delalloc range. + +Signed-off-by: Brian Foster +Reviewed-by: Christoph Hellwig +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_iomap.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +--- a/fs/xfs/xfs_iomap.c ++++ b/fs/xfs/xfs_iomap.c +@@ -1068,7 +1068,15 @@ xfs_file_iomap_end_delalloc( + xfs_fileoff_t end_fsb; + int error = 0; + +- start_fsb = XFS_B_TO_FSB(mp, offset + written); ++ /* ++ * start_fsb refers to the first unused block after a short write. If ++ * nothing was written, round offset down to point at the first block in ++ * the range. ++ */ ++ if (unlikely(!written)) ++ start_fsb = XFS_B_TO_FSBT(mp, offset); ++ else ++ start_fsb = XFS_B_TO_FSB(mp, offset + written); + end_fsb = XFS_B_TO_FSB(mp, offset + length); + + /* +@@ -1080,6 +1088,9 @@ xfs_file_iomap_end_delalloc( + * blocks in the range, they are ours. + */ + if (start_fsb < end_fsb) { ++ truncate_pagecache_range(VFS_I(ip), XFS_FSB_TO_B(mp, start_fsb), ++ XFS_FSB_TO_B(mp, end_fsb) - 1); ++ + xfs_ilock(ip, XFS_ILOCK_EXCL); + error = xfs_bmap_punch_delalloc_range(ip, start_fsb, + end_fsb - start_fsb);