Btrfs: Update metadata reservation for delayed allocation
Introduce metadata reservation context for delayed allocation and update various related functions. This patch also introduces EXTENT_FIRST_DELALLOC control bit for set/clear_extent_bit. It tells set/clear_bit_hook whether they are processing the first extent_state with EXTENT_DELALLOC bit set. This change is important if set/clear_extent_bit involves multiple extent_state. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
@@ -587,19 +587,9 @@ static int btrfs_defrag_file(struct file *file,
|
||||
if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
|
||||
BTRFS_I(inode)->force_compress = 1;
|
||||
|
||||
ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
|
||||
if (ret) {
|
||||
ret = -ENOSPC;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = btrfs_reserve_metadata_for_delalloc(root, inode, 1);
|
||||
if (ret) {
|
||||
btrfs_free_reserved_data_space(root, inode,
|
||||
PAGE_CACHE_SIZE);
|
||||
ret = -ENOSPC;
|
||||
break;
|
||||
}
|
||||
ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
|
||||
if (ret)
|
||||
goto err_unlock;
|
||||
again:
|
||||
if (inode->i_size == 0 ||
|
||||
i > ((inode->i_size - 1) >> PAGE_CACHE_SHIFT)) {
|
||||
@@ -608,8 +598,10 @@ again:
|
||||
}
|
||||
|
||||
page = grab_cache_page(inode->i_mapping, i);
|
||||
if (!page)
|
||||
if (!page) {
|
||||
ret = -ENOMEM;
|
||||
goto err_reservations;
|
||||
}
|
||||
|
||||
if (!PageUptodate(page)) {
|
||||
btrfs_readpage(NULL, page);
|
||||
@@ -617,6 +609,7 @@ again:
|
||||
if (!PageUptodate(page)) {
|
||||
unlock_page(page);
|
||||
page_cache_release(page);
|
||||
ret = -EIO;
|
||||
goto err_reservations;
|
||||
}
|
||||
}
|
||||
@@ -630,8 +623,7 @@ again:
|
||||
wait_on_page_writeback(page);
|
||||
|
||||
if (PageDirty(page)) {
|
||||
btrfs_free_reserved_data_space(root, inode,
|
||||
PAGE_CACHE_SIZE);
|
||||
btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE);
|
||||
goto loop_unlock;
|
||||
}
|
||||
|
||||
@@ -669,7 +661,6 @@ loop_unlock:
|
||||
page_cache_release(page);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
|
||||
btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
|
||||
balance_dirty_pages_ratelimited_nr(inode->i_mapping, 1);
|
||||
i++;
|
||||
}
|
||||
@@ -699,9 +690,9 @@ loop_unlock:
|
||||
return 0;
|
||||
|
||||
err_reservations:
|
||||
btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE);
|
||||
err_unlock:
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
|
||||
btrfs_unreserve_metadata_for_delalloc(root, inode, 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user