Home Home > GIT Browse > SLE15-SP1
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
commit933ecdcfd37595709c6f12580d294523ff2867b4 (patch)
treef304753b0bc8f83bfe637d80d814e24dea551476
parentd1476095b8ed29f304b445f4127ec9e47e6484a5 (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). suse-commit: 227b3e20460e3e4a0bc993a9b22aa91255923472
-rw-r--r--fs/btrfs/file.c35
1 files 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);
/*
@@ -2093,6 +2076,24 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
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.
*/