Commit a3429ab7 authored by Chris Mason's avatar Chris Mason

Btrfs: delay clearing EXTENT_DELALLOC for compressed extents

When compression is on, the cow_file_range code is farmed off to
worker threads.  This allows us to do significant CPU work in parallel
on SMP machines.

But it is a delicate balance around when we clear flags and how.  In
the past we cleared the delalloc flag immediately, which was safe
because the pages stayed locked.

But this is causing problems with the newest ENOSPC code, and with the
recent extent state cleanups we can now clear the delalloc bit at the
same time the uncompressed code does.
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent a791e35e
...@@ -427,6 +427,7 @@ static noinline int compress_file_range(struct inode *inode, ...@@ -427,6 +427,7 @@ static noinline int compress_file_range(struct inode *inode,
&BTRFS_I(inode)->io_tree, &BTRFS_I(inode)->io_tree,
start, end, NULL, start, end, NULL,
EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY | EXTENT_CLEAR_UNLOCK_PAGE | EXTENT_CLEAR_DIRTY |
EXTENT_CLEAR_DELALLOC |
EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK); EXTENT_SET_WRITEBACK | EXTENT_END_WRITEBACK);
ret = 0; ret = 0;
goto free_pages_out; goto free_pages_out;
...@@ -644,6 +645,7 @@ static noinline int submit_compressed_extents(struct inode *inode, ...@@ -644,6 +645,7 @@ static noinline int submit_compressed_extents(struct inode *inode,
async_extent->ram_size - 1, async_extent->ram_size - 1,
NULL, EXTENT_CLEAR_UNLOCK_PAGE | NULL, EXTENT_CLEAR_UNLOCK_PAGE |
EXTENT_CLEAR_UNLOCK | EXTENT_CLEAR_UNLOCK |
EXTENT_CLEAR_DELALLOC |
EXTENT_CLEAR_DIRTY | EXTENT_SET_WRITEBACK); EXTENT_CLEAR_DIRTY | EXTENT_SET_WRITEBACK);
ret = btrfs_submit_compressed_write(inode, ret = btrfs_submit_compressed_write(inode,
...@@ -877,8 +879,8 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, ...@@ -877,8 +879,8 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
u64 cur_end; u64 cur_end;
int limit = 10 * 1024 * 1042; int limit = 10 * 1024 * 1042;
clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED | clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED,
EXTENT_DELALLOC, 1, 0, NULL, GFP_NOFS); 1, 0, NULL, GFP_NOFS);
while (start < end) { while (start < end) {
async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS);
async_cow->inode = inode; async_cow->inode = inode;
......
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