Home Home > GIT Browse > SLE12-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Kirjanov <dkirjanov@suse.com>2019-10-18 16:41:51 +0300
committerDenis Kirjanov <dkirjanov@suse.com>2019-10-18 16:41:51 +0300
commit227b3e20460e3e4a0bc993a9b22aa91255923472 (patch)
treecccce0a0f61c5bcf4e0f2405b1f50dafd4eb2a43
parent05b72cb22b0bc12412db5017426639f4602437a3 (diff)
Btrfs: check for the full sync flag while holding the inoderpm-4.12.14-119--sle12-sp5-garpm-4.12.14-119
lock during fsync (bsc#1153713).
-rw-r--r--patches.suse/Btrfs-check-for-the-full-sync-flag-while-holding-the.patch86
-rw-r--r--series.conf1
2 files changed, 87 insertions, 0 deletions
diff --git a/patches.suse/Btrfs-check-for-the-full-sync-flag-while-holding-the.patch b/patches.suse/Btrfs-check-for-the-full-sync-flag-while-holding-the.patch
new file mode 100644
index 0000000000..dac2fb9f3e
--- /dev/null
+++ b/patches.suse/Btrfs-check-for-the-full-sync-flag-while-holding-the.patch
@@ -0,0 +1,86 @@
+From: Filipe Manana <fdmanana@suse.com>
+Date: Wed, 16 Oct 2019 17:28:50 +0100
+Patch-mainline: submitted upstream, https://patchwork.kernel.org/patch/11193633/
+References: bsc#1153713
+Subject: [PATCH] Btrfs: check for the full sync flag while holding the inode
+ lock during fsync
+
+We were checking for the full fsync flag in the inode before locking the
+inode, which is racy, since at that that time it might not be set but
+after we acquire the inode lock some other task set it. One case where
+this can happen is on a system low on memory and some concurrent task
+failed to allocate an extent map and therefore set the full sync flag on
+the inode, to force the next fsync to work in full mode.
+
+A consequence of missing the full fsync flag set is hitting the problems
+fixed by commit 0c713cbab620 ("Btrfs: fix race between ranged fsync and
+writeback of adjacent ranges"), BUG_ON() when dropping extents from a log
+tree, hitting assertion failures at tree-log.c:copy_items() or all sorts
+of weird inconsistencies after replaying a log due to file extents items
+representing ranges that overlap.
+
+So just move the check such that it's done after locking the inode and
+before starting writeback again.
+
+Fixes: 0c713cbab620 ("Btrfs: fix race between ranged fsync and writeback of adjacent ranges")
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+---
+ fs/btrfs/file.c | 35 ++++++++++++++++++-----------------
+ 1 file changed, 18 insertions(+), 17 deletions(-)
+
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 320b01580f2e..901aeb7ee81b 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -2059,23 +2059,6 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ bool full_sync = 0;
+ u64 len;
+
+- /*
+- * If the inode needs a full sync, make sure we use a full range to
+- * avoid log tree corruption, due to hole detection racing with ordered
+- * extent completion for adjacent ranges, and assertion failures during
+- * hole detection.
+- */
+- if (test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+- &BTRFS_I(inode)->runtime_flags)) {
+- start = 0;
+- end = LLONG_MAX;
+- }
+-
+- /*
+- * The range length can be represented by u64, we have to do the typecasts
+- * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
+- */
+- len = (u64)end - (u64)start + 1;
+ trace_btrfs_sync_file(file, datasync);
+
+ /*
+@@ -2092,6 +2075,24 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
+ atomic_inc(&root->log_batch);
+ full_sync = test_bit(BTRFS_INODE_NEEDS_FULL_SYNC,
+ &BTRFS_I(inode)->runtime_flags);
++ /*
++ * If the inode needs a full sync, make sure we use a full range to
++ * avoid log tree corruption, due to hole detection racing with ordered
++ * extent completion for adjacent ranges, and assertion failures during
++ * hole detection. Do this while holding the inode lock, to avoid races
++ * with other tasks.
++ */
++ if (full_sync) {
++ start = 0;
++ end = LLONG_MAX;
++ }
++
++ /*
++ * The range length can be represented by u64, we have to do the typecasts
++ * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
++ */
++ len = (u64)end - (u64)start + 1;
++
+ /*
+ * We might have have had more pages made dirty after calling
+ * start_ordered_ops and before acquiring the inode's i_mutex.
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index 5072598746..adc0d8d73f 100644
--- a/series.conf
+++ b/series.conf
@@ -49918,6 +49918,7 @@
patches.suse/powerpc-fadump-when-fadump-is-supported-register-the.patch
patches.suse/powerpc-papr_scm-Fix-an-off-by-one-check-in-papr_scm_meta_-get-set.patch
patches.suse/0001-b2c2-flexcop-usb-add-sanity-checking.patch
+ patches.suse/Btrfs-check-for-the-full-sync-flag-while-holding-the.patch
########################################################
# end of sorted patches