aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2014-10-09 16:18:55 -0400
committerChris Mason <clm@fb.com>2014-11-20 20:14:27 -0500
commit075bdbdbe9f21d68950ba5b187f80a4a23105365 (patch)
tree7a8cee33816ea7de60795f985068a176340e660d
parentc44f649e281e93689827a206653696be9599a320 (diff)
Btrfs: correctly flush compressed data before/after direct IO
For compressed writes, after doing the first filemap_fdatawrite_range() we don't get the pages tagged for writeback immediately. Instead we create a workqueue task, which is run by other kthread, and keep the pages locked. That other kthread compresses data, creates the respective ordered extent/s, tags the pages for writeback and unlocks them. Therefore we need a second call to filemap_fdatawrite_range() if we have compressed writes, as this second call will wait for the pages to become unlocked, then see they became tagged for writeback and finally wait for the writeback to finish. Signed-off-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/file.c12
-rw-r--r--fs/btrfs/inode.c16
2 files changed, 24 insertions, 4 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index a18ceabd99a8..f5a868ab60f3 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1692,8 +1692,18 @@ static ssize_t __btrfs_direct_write(struct kiocb *iocb,
1692 err = written_buffered; 1692 err = written_buffered;
1693 goto out; 1693 goto out;
1694 } 1694 }
1695 /*
1696 * Ensure all data is persisted. We want the next direct IO read to be
1697 * able to read what was just written.
1698 */
1695 endbyte = pos + written_buffered - 1; 1699 endbyte = pos + written_buffered - 1;
1696 err = filemap_write_and_wait_range(file->f_mapping, pos, endbyte); 1700 err = filemap_fdatawrite_range(file->f_mapping, pos, endbyte);
1701 if (!err && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
1702 &BTRFS_I(file_inode(file))->runtime_flags))
1703 err = filemap_fdatawrite_range(file->f_mapping, pos, endbyte);
1704 if (err)
1705 goto out;
1706 err = filemap_fdatawait_range(file->f_mapping, pos, endbyte);
1697 if (err) 1707 if (err)
1698 goto out; 1708 goto out;
1699 written += written_buffered; 1709 written += written_buffered;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 5a8a749b7e6b..01d223e22bb1 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7015,9 +7015,19 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
7015 btrfs_put_ordered_extent(ordered); 7015 btrfs_put_ordered_extent(ordered);
7016 } else { 7016 } else {
7017 /* Screw you mmap */ 7017 /* Screw you mmap */
7018 ret = filemap_write_and_wait_range(inode->i_mapping, 7018 ret = filemap_fdatawrite_range(inode->i_mapping,
7019 lockstart, 7019 lockstart,
7020 lockend); 7020 lockend);
7021 if (!ret && test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
7022 &BTRFS_I(inode)->runtime_flags))
7023 ret = filemap_fdatawrite_range(inode->i_mapping,
7024 lockstart,
7025 lockend);
7026 if (ret)
7027 break;
7028 ret = filemap_fdatawait_range(inode->i_mapping,
7029 lockstart,
7030 lockend);
7021 if (ret) 7031 if (ret)
7022 break; 7032 break;
7023 7033