btrfs: optionally extend i_size in cow_file_range_inline()
Currently, an inline extent is always created after i_size is extended from btrfs_dirty_pages(). However, for encoded writes, we only want to update i_size after we successfully created the inline extent. Add an update_i_size parameter to cow_file_range_inline() and insert_inline_extent() and pass in the size of the extent rather than determining it from i_size. Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Omar Sandoval <osandov@fb.com> Reviewed-by: David Sterba <dsterba@suse.com> [ reformat comment ] Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
8dd9872d2e
commit
d9496e8aba
@ -243,7 +243,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_inode *inode, bool extent_inserted,
|
||||
size_t size, size_t compressed_size,
|
||||
int compress_type,
|
||||
struct page **compressed_pages)
|
||||
struct page **compressed_pages,
|
||||
bool update_i_size)
|
||||
{
|
||||
struct btrfs_root *root = inode->root;
|
||||
struct extent_buffer *leaf;
|
||||
@ -253,6 +254,7 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_file_extent_item *ei;
|
||||
int ret;
|
||||
size_t cur_size = size;
|
||||
u64 i_size;
|
||||
|
||||
ASSERT((compressed_size > 0 && compressed_pages) ||
|
||||
(compressed_size == 0 && !compressed_pages));
|
||||
@ -323,15 +325,18 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* we're an inline extent, so nobody can
|
||||
* extend the file past i_size without locking
|
||||
* a page we already have locked.
|
||||
* We're an inline extent, so nobody can extend the file past i_size
|
||||
* without locking a page we already have locked.
|
||||
*
|
||||
* We must do any isize and inode updates
|
||||
* before we unlock the pages. Otherwise we
|
||||
* could end up racing with unlink.
|
||||
* We must do any i_size and inode updates before we unlock the pages.
|
||||
* Otherwise we could end up racing with unlink.
|
||||
*/
|
||||
inode->disk_i_size = i_size_read(&inode->vfs_inode);
|
||||
i_size = i_size_read(&inode->vfs_inode);
|
||||
if (update_i_size && size > i_size) {
|
||||
i_size_write(&inode->vfs_inode, size);
|
||||
i_size = size;
|
||||
}
|
||||
inode->disk_i_size = i_size;
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
@ -346,7 +351,8 @@ fail:
|
||||
static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
|
||||
size_t compressed_size,
|
||||
int compress_type,
|
||||
struct page **compressed_pages)
|
||||
struct page **compressed_pages,
|
||||
bool update_i_size)
|
||||
{
|
||||
struct btrfs_drop_extents_args drop_args = { 0 };
|
||||
struct btrfs_root *root = inode->root;
|
||||
@ -393,7 +399,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
|
||||
|
||||
ret = insert_inline_extent(trans, path, inode, drop_args.extent_inserted,
|
||||
size, compressed_size, compress_type,
|
||||
compressed_pages);
|
||||
compressed_pages, update_i_size);
|
||||
if (ret && ret != -ENOSPC) {
|
||||
btrfs_abort_transaction(trans, ret);
|
||||
goto out;
|
||||
@ -725,12 +731,13 @@ cont:
|
||||
*/
|
||||
ret = cow_file_range_inline(BTRFS_I(inode), actual_end,
|
||||
0, BTRFS_COMPRESS_NONE,
|
||||
NULL);
|
||||
NULL, false);
|
||||
} else {
|
||||
/* try making a compressed inline extent */
|
||||
ret = cow_file_range_inline(BTRFS_I(inode), actual_end,
|
||||
total_compressed,
|
||||
compress_type, pages);
|
||||
compress_type, pages,
|
||||
false);
|
||||
}
|
||||
if (ret <= 0) {
|
||||
unsigned long clear_flags = EXTENT_DELALLOC |
|
||||
@ -1148,7 +1155,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
|
||||
|
||||
/* lets try to make an inline extent */
|
||||
ret = cow_file_range_inline(inode, actual_end, 0,
|
||||
BTRFS_COMPRESS_NONE, NULL);
|
||||
BTRFS_COMPRESS_NONE, NULL, false);
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* We use DO_ACCOUNTING here because we need the
|
||||
|
Loading…
Reference in New Issue
Block a user