From: Greg Kroah-Hartman Date: Tue, 28 Mar 2023 13:54:20 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.15.105~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9e7dd97ff4b580905f5d2c8f1fc27e22966311ff;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: ocfs2-fix-data-corruption-after-failed-write.patch --- diff --git a/queue-5.4/ocfs2-fix-data-corruption-after-failed-write.patch b/queue-5.4/ocfs2-fix-data-corruption-after-failed-write.patch new file mode 100644 index 00000000000..f65ec43eec9 --- /dev/null +++ b/queue-5.4/ocfs2-fix-data-corruption-after-failed-write.patch @@ -0,0 +1,67 @@ +From 90410bcf873cf05f54a32183afff0161f44f9715 Mon Sep 17 00:00:00 2001 +From: Jan Kara via Ocfs2-devel +Date: Thu, 2 Mar 2023 16:38:43 +0100 +Subject: ocfs2: fix data corruption after failed write + +From: Jan Kara via Ocfs2-devel + +commit 90410bcf873cf05f54a32183afff0161f44f9715 upstream. + +When buffered write fails to copy data into underlying page cache page, +ocfs2_write_end_nolock() just zeroes out and dirties the page. This can +leave dirty page beyond EOF and if page writeback tries to write this page +before write succeeds and expands i_size, page gets into inconsistent +state where page dirty bit is clear but buffer dirty bits stay set +resulting in page data never getting written and so data copied to the +page is lost. Fix the problem by invalidating page beyond EOF after +failed write. + +Link: https://lkml.kernel.org/r/20230302153843.18499-1-jack@suse.cz +Fixes: 6dbf7bb55598 ("fs: Don't invalidate page buffers in block_write_full_page()") +Signed-off-by: Jan Kara +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Gang He +Cc: Jun Piao +Cc: +Signed-off-by: Andrew Morton +[ replace block_invalidate_folio to block_invalidatepage ] +Signed-off-by: Joseph Qi +Signed-off-by: Greg Kroah-Hartman +--- + fs/ocfs2/aops.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +--- a/fs/ocfs2/aops.c ++++ b/fs/ocfs2/aops.c +@@ -1990,11 +1990,25 @@ int ocfs2_write_end_nolock(struct addres + } + + if (unlikely(copied < len) && wc->w_target_page) { ++ loff_t new_isize; ++ + if (!PageUptodate(wc->w_target_page)) + copied = 0; + +- ocfs2_zero_new_buffers(wc->w_target_page, start+copied, +- start+len); ++ new_isize = max_t(loff_t, i_size_read(inode), pos + copied); ++ if (new_isize > page_offset(wc->w_target_page)) ++ ocfs2_zero_new_buffers(wc->w_target_page, start+copied, ++ start+len); ++ else { ++ /* ++ * When page is fully beyond new isize (data copy ++ * failed), do not bother zeroing the page. Invalidate ++ * it instead so that writeback does not get confused ++ * put page & buffer dirty bits into inconsistent ++ * state. ++ */ ++ block_invalidatepage(wc->w_target_page, 0, PAGE_SIZE); ++ } + } + if (wc->w_target_page) + flush_dcache_page(wc->w_target_page); diff --git a/queue-5.4/series b/queue-5.4/series index 090973fa25a..f8b83bd1b77 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -57,3 +57,4 @@ dm-crypt-add-cond_resched-to-dmcrypt_write.patch sched-fair-sanitize-vruntime-of-entity-being-placed.patch sched-fair-sanitize-vruntime-of-entity-being-migrated.patch tun-avoid-double-free-in-tun_free_netdev.patch +ocfs2-fix-data-corruption-after-failed-write.patch