Commit 41bd9ca4 authored by Miao Xie's avatar Miao Xie Committed by Josef Bacik

Btrfs: just do dirty page flush for the inode with compression before direct IO

As the comment in the btrfs_direct_IO says, only the compressed pages need be
flush again to make sure they are on the disk, but the common pages needn't,
so we add a if statement to check if the inode has compressed pages or not,
if no, skip the flush.

And in order to prevent the write ranges from intersecting, we need wait for
the running ordered extents. But the current code waits for them twice, one
is done before the direct IO starts (in btrfs_wait_ordered_range()), the other
is before we get the blocks, it is unnecessary. because we can do the direct
IO without holding i_mutex, it means that the intersected ordered extents may
happen during the direct IO, the first wait can not avoid this problem. So we
use filemap_fdatawrite_range() instead of btrfs_wait_ordered_range() to remove
the first wait.
Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarJosef Bacik <jbacik@fb.com>
parent af7a6509
...@@ -7422,15 +7422,15 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb, ...@@ -7422,15 +7422,15 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
smp_mb__after_atomic_inc(); smp_mb__after_atomic_inc();
/* /*
* The generic stuff only does filemap_write_and_wait_range, which isn't * The generic stuff only does filemap_write_and_wait_range, which
* enough if we've written compressed pages to this area, so we need to * isn't enough if we've written compressed pages to this area, so
* call btrfs_wait_ordered_range to make absolutely sure that any * we need to flush the dirty pages again to make absolutely sure
* outstanding dirty pages are on disk. * that any outstanding dirty pages are on disk.
*/ */
count = iov_length(iov, nr_segs); count = iov_length(iov, nr_segs);
ret = btrfs_wait_ordered_range(inode, offset, count); if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
if (ret) &BTRFS_I(inode)->runtime_flags))
return ret; filemap_fdatawrite_range(inode->i_mapping, offset, count);
if (rw & WRITE) { if (rw & WRITE) {
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment