Btrfs: make sure the delalloc workers actually flush compressed writes
authorJosef Bacik <jbacik@fusionio.com>
Mon, 28 Oct 2013 19:03:41 +0000 (15:03 -0400)
committerChris Mason <chris.mason@fusionio.com>
Tue, 12 Nov 2013 03:08:22 +0000 (22:08 -0500)
When using delalloc workers in a non-waiting way (like for enospc handling) we
can end up not actually waiting for the dirty pages to be started if we have
compression.  We need to add an extra filemap flush to make sure any async
extents that have started are actually moved along before returning.  Thanks,

Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/inode.c

index 5916ad8681cd0011a88790c633ca7518d2ca4d66..c84adde530238df6ea0f009b7799bc61472bcd4f 100644 (file)
@@ -8163,18 +8163,24 @@ out_notrans:
 static void btrfs_run_delalloc_work(struct btrfs_work *work)
 {
        struct btrfs_delalloc_work *delalloc_work;
+       struct inode *inode;
 
        delalloc_work = container_of(work, struct btrfs_delalloc_work,
                                     work);
-       if (delalloc_work->wait)
-               btrfs_wait_ordered_range(delalloc_work->inode, 0, (u64)-1);
-       else
-               filemap_flush(delalloc_work->inode->i_mapping);
+       inode = delalloc_work->inode;
+       if (delalloc_work->wait) {
+               btrfs_wait_ordered_range(inode, 0, (u64)-1);
+       } else {
+               filemap_flush(inode->i_mapping);
+               if (test_bit(BTRFS_INODE_HAS_ASYNC_EXTENT,
+                            &BTRFS_I(inode)->runtime_flags))
+                       filemap_flush(inode->i_mapping);
+       }
 
        if (delalloc_work->delay_iput)
-               btrfs_add_delayed_iput(delalloc_work->inode);
+               btrfs_add_delayed_iput(inode);
        else
-               iput(delalloc_work->inode);
+               iput(inode);
        complete(&delalloc_work->completion);
 }