summaryrefslogtreecommitdiff |
diff options
author | Denis Kirjanov <dkirjanov@suse.com> | 2019-10-18 16:41:51 +0300 |
---|---|---|
committer | Denis Kirjanov <dkirjanov@suse.com> | 2019-10-18 16:41:51 +0300 |
commit | 933ecdcfd37595709c6f12580d294523ff2867b4 (patch) | |
tree | f304753b0bc8f83bfe637d80d814e24dea551476 | |
parent | d1476095b8ed29f304b445f4127ec9e47e6484a5 (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.c | 35 |
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. */ |