Commit 8dd9872d authored by Omar Sandoval's avatar Omar Sandoval Committed by David Sterba

btrfs: clean up cow_file_range_inline()

The start parameter to cow_file_range_inline() (and
insert_inline_extent()) is always 0, so get rid of it and simplify the
logic in those two functions. Pass btrfs_inode to insert_inline_extent()
and remove the redundant root parameter. Also document the requirements
for creating an inline extent. No functional change.
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 28c9b1e7
...@@ -239,12 +239,13 @@ static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, ...@@ -239,12 +239,13 @@ static int btrfs_init_inode_security(struct btrfs_trans_handle *trans,
* no overlapping inline items exist in the btree * no overlapping inline items exist in the btree
*/ */
static int insert_inline_extent(struct btrfs_trans_handle *trans, static int insert_inline_extent(struct btrfs_trans_handle *trans,
struct btrfs_path *path, bool extent_inserted, struct btrfs_path *path,
struct btrfs_root *root, struct inode *inode, struct btrfs_inode *inode, bool extent_inserted,
u64 start, size_t size, size_t compressed_size, size_t size, size_t compressed_size,
int compress_type, int compress_type,
struct page **compressed_pages) struct page **compressed_pages)
{ {
struct btrfs_root *root = inode->root;
struct extent_buffer *leaf; struct extent_buffer *leaf;
struct page *page = NULL; struct page *page = NULL;
char *kaddr; char *kaddr;
...@@ -252,7 +253,6 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, ...@@ -252,7 +253,6 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
struct btrfs_file_extent_item *ei; struct btrfs_file_extent_item *ei;
int ret; int ret;
size_t cur_size = size; size_t cur_size = size;
unsigned long offset;
ASSERT((compressed_size > 0 && compressed_pages) || ASSERT((compressed_size > 0 && compressed_pages) ||
(compressed_size == 0 && !compressed_pages)); (compressed_size == 0 && !compressed_pages));
...@@ -264,8 +264,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, ...@@ -264,8 +264,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
struct btrfs_key key; struct btrfs_key key;
size_t datasize; size_t datasize;
key.objectid = btrfs_ino(BTRFS_I(inode)); key.objectid = btrfs_ino(inode);
key.offset = start; key.offset = 0;
key.type = BTRFS_EXTENT_DATA_KEY; key.type = BTRFS_EXTENT_DATA_KEY;
datasize = btrfs_file_extent_calc_inline_size(cur_size); datasize = btrfs_file_extent_calc_inline_size(cur_size);
...@@ -303,12 +303,10 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, ...@@ -303,12 +303,10 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
btrfs_set_file_extent_compression(leaf, ei, btrfs_set_file_extent_compression(leaf, ei,
compress_type); compress_type);
} else { } else {
page = find_get_page(inode->i_mapping, page = find_get_page(inode->vfs_inode.i_mapping, 0);
start >> PAGE_SHIFT);
btrfs_set_file_extent_compression(leaf, ei, 0); btrfs_set_file_extent_compression(leaf, ei, 0);
kaddr = kmap_atomic(page); kaddr = kmap_atomic(page);
offset = offset_in_page(start); write_extent_buffer(leaf, kaddr, ptr, size);
write_extent_buffer(leaf, kaddr + offset, ptr, size);
kunmap_atomic(kaddr); kunmap_atomic(kaddr);
put_page(page); put_page(page);
} }
...@@ -319,8 +317,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, ...@@ -319,8 +317,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
* We align size to sectorsize for inline extents just for simplicity * We align size to sectorsize for inline extents just for simplicity
* sake. * sake.
*/ */
size = ALIGN(size, root->fs_info->sectorsize); ret = btrfs_inode_set_file_extent_range(inode, 0,
ret = btrfs_inode_set_file_extent_range(BTRFS_I(inode), start, size); ALIGN(size, root->fs_info->sectorsize));
if (ret) if (ret)
goto fail; goto fail;
...@@ -333,7 +331,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, ...@@ -333,7 +331,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
* before we unlock the pages. Otherwise we * before we unlock the pages. Otherwise we
* could end up racing with unlink. * could end up racing with unlink.
*/ */
BTRFS_I(inode)->disk_i_size = inode->i_size; inode->disk_i_size = i_size_read(&inode->vfs_inode);
fail: fail:
return ret; return ret;
} }
...@@ -344,8 +343,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans, ...@@ -344,8 +343,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
* does the checks required to make sure the data is small enough * does the checks required to make sure the data is small enough
* to fit as an inline extent. * to fit as an inline extent.
*/ */
static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start, static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
u64 end, size_t compressed_size, size_t compressed_size,
int compress_type, int compress_type,
struct page **compressed_pages) struct page **compressed_pages)
{ {
...@@ -353,26 +352,21 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start, ...@@ -353,26 +352,21 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
struct btrfs_root *root = inode->root; struct btrfs_root *root = inode->root;
struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
u64 isize = i_size_read(&inode->vfs_inode); u64 data_len = (compressed_size ?: size);
u64 actual_end = min(end + 1, isize);
u64 inline_len = actual_end - start;
u64 aligned_end = ALIGN(end, fs_info->sectorsize);
u64 data_len = inline_len;
int ret; int ret;
struct btrfs_path *path; struct btrfs_path *path;
if (compressed_size) /*
data_len = compressed_size; * We can create an inline extent if it ends at or beyond the current
* i_size, is no larger than a sector (decompressed), and the (possibly
if (start > 0 || * compressed) data fits in a leaf and the configured maximum inline
actual_end > fs_info->sectorsize || * size.
*/
if (size < i_size_read(&inode->vfs_inode) ||
size > fs_info->sectorsize ||
data_len > BTRFS_MAX_INLINE_DATA_SIZE(fs_info) || data_len > BTRFS_MAX_INLINE_DATA_SIZE(fs_info) ||
(!compressed_size && data_len > fs_info->max_inline)
(actual_end & (fs_info->sectorsize - 1)) == 0) ||
end + 1 < isize ||
data_len > fs_info->max_inline) {
return 1; return 1;
}
path = btrfs_alloc_path(); path = btrfs_alloc_path();
if (!path) if (!path)
...@@ -386,30 +380,20 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start, ...@@ -386,30 +380,20 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
trans->block_rsv = &inode->block_rsv; trans->block_rsv = &inode->block_rsv;
drop_args.path = path; drop_args.path = path;
drop_args.start = start; drop_args.start = 0;
drop_args.end = aligned_end; drop_args.end = fs_info->sectorsize;
drop_args.drop_cache = true; drop_args.drop_cache = true;
drop_args.replace_extent = true; drop_args.replace_extent = true;
drop_args.extent_item_size = btrfs_file_extent_calc_inline_size(data_len);
if (compressed_size && compressed_pages)
drop_args.extent_item_size = btrfs_file_extent_calc_inline_size(
compressed_size);
else
drop_args.extent_item_size = btrfs_file_extent_calc_inline_size(
inline_len);
ret = btrfs_drop_extents(trans, root, inode, &drop_args); ret = btrfs_drop_extents(trans, root, inode, &drop_args);
if (ret) { if (ret) {
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
goto out; goto out;
} }
if (isize > actual_end) ret = insert_inline_extent(trans, path, inode, drop_args.extent_inserted,
inline_len = min_t(u64, isize, actual_end); size, compressed_size, compress_type,
ret = insert_inline_extent(trans, path, drop_args.extent_inserted, compressed_pages);
root, &inode->vfs_inode, start,
inline_len, compressed_size,
compress_type, compressed_pages);
if (ret && ret != -ENOSPC) { if (ret && ret != -ENOSPC) {
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
goto out; goto out;
...@@ -418,7 +402,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start, ...@@ -418,7 +402,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 start,
goto out; goto out;
} }
btrfs_update_inode_bytes(inode, inline_len, drop_args.bytes_found); btrfs_update_inode_bytes(inode, size, drop_args.bytes_found);
ret = btrfs_update_inode(trans, root, inode); ret = btrfs_update_inode(trans, root, inode);
if (ret && ret != -ENOSPC) { if (ret && ret != -ENOSPC) {
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
...@@ -739,12 +723,12 @@ static noinline int compress_file_range(struct async_chunk *async_chunk) ...@@ -739,12 +723,12 @@ static noinline int compress_file_range(struct async_chunk *async_chunk)
/* we didn't compress the entire range, try /* we didn't compress the entire range, try
* to make an uncompressed inline extent. * to make an uncompressed inline extent.
*/ */
ret = cow_file_range_inline(BTRFS_I(inode), start, end, ret = cow_file_range_inline(BTRFS_I(inode), actual_end,
0, BTRFS_COMPRESS_NONE, 0, BTRFS_COMPRESS_NONE,
NULL); NULL);
} else { } else {
/* try making a compressed inline extent */ /* try making a compressed inline extent */
ret = cow_file_range_inline(BTRFS_I(inode), start, end, ret = cow_file_range_inline(BTRFS_I(inode), actual_end,
total_compressed, total_compressed,
compress_type, pages); compress_type, pages);
} }
...@@ -1159,8 +1143,11 @@ static noinline int cow_file_range(struct btrfs_inode *inode, ...@@ -1159,8 +1143,11 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
* So here we skip inline extent creation completely. * So here we skip inline extent creation completely.
*/ */
if (start == 0 && fs_info->sectorsize == PAGE_SIZE) { if (start == 0 && fs_info->sectorsize == PAGE_SIZE) {
u64 actual_end = min_t(u64, i_size_read(&inode->vfs_inode),
end + 1);
/* lets try to make an inline extent */ /* lets try to make an inline extent */
ret = cow_file_range_inline(inode, start, end, 0, ret = cow_file_range_inline(inode, actual_end, 0,
BTRFS_COMPRESS_NONE, NULL); BTRFS_COMPRESS_NONE, NULL);
if (ret == 0) { if (ret == 0) {
/* /*
......
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