summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorTimofey Titovets <nefelim4ag@gmail.com>2017-10-24 01:29:48 +0300
committerDavid Sterba <dsterba@suse.com>2018-01-22 16:08:15 +0100
commite9679de3fdcb11a13cfe3873c9923b761c8067ab (patch)
treec20a5add02adb2c9e5d6c1aac95f64c5e09e9d34 /fs/btrfs/inode.c
parent440c840cb49f7de91e68a4cc7bca79a75cd298ae (diff)
downloadop-kernel-dev-e9679de3fdcb11a13cfe3873c9923b761c8067ab.zip
op-kernel-dev-e9679de3fdcb11a13cfe3873c9923b761c8067ab.tar.gz
Btrfs: compress_file_range() change page dirty status once
We need to call extent_range_clear_dirty_for_io() on compression range to prevent application from changing page content, while pages compressing. extent_range_clear_dirty_for_io() runs on each loop iteration, "(end - start)" can be much (up to 1024 times) bigger then compression range (BTRFS_MAX_UNCOMPRESSED). The start pointer is advanced each time we manage to compress part of the range. The end pointer does not change so we could redirty the remaining parts repeatedly. Fix that behaviour by call extent_range_clear_dirty_for_io() only once, the first time it happens. This is the safest but probably not the best behaviour. Previous iterations of the patch tried to redirty only the range that we were not able to compress. This has been refused by David for safety reasons, the writeout callchain is complex and there could be some path that relies on redirtying the entire unwritten range. Signed-off-by: Timofey Titovets <nefelim4ag@gmail.com> Reviewed-by: David Sterba <dsterba@suse.com> [ enhance changelog, the history and safety concerns, add comment ] Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 57785ea..e87ec11 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -536,9 +536,14 @@ again:
*
* If the compression fails for any reason, we set the pages
* dirty again later on.
+ *
+ * Note that the remaining part is redirtied, the start pointer
+ * has moved, the end is the original one.
*/
- extent_range_clear_dirty_for_io(inode, start, end);
- redirty = 1;
+ if (!redirty) {
+ extent_range_clear_dirty_for_io(inode, start, end);
+ redirty = 1;
+ }
/* Compression level is applied here and only here */
ret = btrfs_compress_pages(
OpenPOWER on IntegriCloud