]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Btrfs: just do dirty page flush for the inode with compression before direct IO
authorMiao Xie <miaox@cn.fujitsu.com>
Thu, 6 Mar 2014 05:54:57 +0000 (13:54 +0800)
committerJosef Bacik <jbacik@fb.com>
Mon, 10 Mar 2014 19:17:24 +0000 (15:17 -0400)
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: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fb.com>
fs/btrfs/inode.c

index 53697a80b8498d82adf3db656a3972b02deddf7d..f5e623371bf387408820dbadec3ed9d5388cc76c 100644 (file)
@@ -7422,15 +7422,15 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
        smp_mb__after_atomic_inc();
 
        /*
-        * The generic stuff only does filemap_write_and_wait_range, which isn't
-        * enough if we've written compressed pages to this area, so we need to
-        * call btrfs_wait_ordered_range to make absolutely sure that any
-        * outstanding dirty pages are on disk.
+        * The generic stuff only does filemap_write_and_wait_range, which
+        * isn't enough if we've written compressed pages to this area, so
+        * we need to flush the dirty pages again to make absolutely sure
+        * that any outstanding dirty pages are on disk.
         */
        count = iov_length(iov, nr_segs);
-       ret = btrfs_wait_ordered_range(inode, offset, count);
-       if (ret)
-               return ret;
+       if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
+                    &BTRFS_I(inode)->runtime_flags))
+               filemap_fdatawrite_range(inode->i_mapping, offset, count);
 
        if (rw & WRITE) {
                /*