From: Greg Kroah-Hartman Date: Sat, 9 Jun 2018 14:43:56 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.17.1~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aa12a991abe342037ca335eeff0fac2eeca9ca32;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: xfs-fix-incorrect-log_flushed-on-fsync.patch --- diff --git a/queue-4.4/series b/queue-4.4/series index 6a36b41933f..a2af7375eb5 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -3,3 +3,4 @@ tpm-self-test-failure-should-not-cause-suspend-to-fail.patch mmap-introduce-sane-default-mmap-limits.patch mmap-relax-file-size-limit-for-regular-files.patch kconfig-avoid-format-overflow-warning-from-gcc-8.1.patch +xfs-fix-incorrect-log_flushed-on-fsync.patch diff --git a/queue-4.4/xfs-fix-incorrect-log_flushed-on-fsync.patch b/queue-4.4/xfs-fix-incorrect-log_flushed-on-fsync.patch new file mode 100644 index 00000000000..bf310b77f71 --- /dev/null +++ b/queue-4.4/xfs-fix-incorrect-log_flushed-on-fsync.patch @@ -0,0 +1,96 @@ +From 47c7d0b19502583120c3f396c7559e7a77288a68 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Wed, 30 Aug 2017 09:23:12 -0700 +Subject: xfs: fix incorrect log_flushed on fsync + +From: Amir Goldstein + +commit 47c7d0b19502583120c3f396c7559e7a77288a68 upstream. + +When calling into _xfs_log_force{,_lsn}() with a pointer +to log_flushed variable, log_flushed will be set to 1 if: +1. xlog_sync() is called to flush the active log buffer +AND/OR +2. xlog_wait() is called to wait on a syncing log buffers + +xfs_file_fsync() checks the value of log_flushed after +_xfs_log_force_lsn() call to optimize away an explicit +PREFLUSH request to the data block device after writing +out all the file's pages to disk. + +This optimization is incorrect in the following sequence of events: + + Task A Task B + ------------------------------------------------------- + xfs_file_fsync() + _xfs_log_force_lsn() + xlog_sync() + [submit PREFLUSH] + xfs_file_fsync() + file_write_and_wait_range() + [submit WRITE X] + [endio WRITE X] + _xfs_log_force_lsn() + xlog_wait() + [endio PREFLUSH] + +The write X is not guarantied to be on persistent storage +when PREFLUSH request in completed, because write A was submitted +after the PREFLUSH request, but xfs_file_fsync() of task A will +be notified of log_flushed=1 and will skip explicit flush. + +If the system crashes after fsync of task A, write X may not be +present on disk after reboot. + +This bug was discovered and demonstrated using Josef Bacik's +dm-log-writes target, which can be used to record block io operations +and then replay a subset of these operations onto the target device. +The test goes something like this: +- Use fsx to execute ops of a file and record ops on log device +- Every now and then fsync the file, store md5 of file and mark + the location in the log +- Then replay log onto device for each mark, mount fs and compare + md5 of file to stored value + +Cc: Christoph Hellwig +Cc: Josef Bacik +Cc: +Signed-off-by: Amir Goldstein +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman + +--- + fs/xfs/xfs_log.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/fs/xfs/xfs_log.c ++++ b/fs/xfs/xfs_log.c +@@ -3323,8 +3323,6 @@ maybe_sleep: + */ + if (iclog->ic_state & XLOG_STATE_IOERROR) + return -EIO; +- if (log_flushed) +- *log_flushed = 1; + } else { + + no_sleep: +@@ -3432,8 +3430,6 @@ try_again: + + xlog_wait(&iclog->ic_prev->ic_write_wait, + &log->l_icloglock); +- if (log_flushed) +- *log_flushed = 1; + already_slept = 1; + goto try_again; + } +@@ -3467,9 +3463,6 @@ try_again: + */ + if (iclog->ic_state & XLOG_STATE_IOERROR) + return -EIO; +- +- if (log_flushed) +- *log_flushed = 1; + } else { /* just return */ + spin_unlock(&log->l_icloglock); + }