Skip to content

Commit d9496e8

Browse files
osandovkdave
authored andcommitted
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 <[email protected]> Signed-off-by: Omar Sandoval <[email protected]> Reviewed-by: David Sterba <[email protected]> [ reformat comment ] Signed-off-by: David Sterba <[email protected]>
1 parent 8dd9872 commit d9496e8

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

fs/btrfs/inode.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
243243
struct btrfs_inode *inode, bool extent_inserted,
244244
size_t size, size_t compressed_size,
245245
int compress_type,
246-
struct page **compressed_pages)
246+
struct page **compressed_pages,
247+
bool update_i_size)
247248
{
248249
struct btrfs_root *root = inode->root;
249250
struct extent_buffer *leaf;
@@ -253,6 +254,7 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
253254
struct btrfs_file_extent_item *ei;
254255
int ret;
255256
size_t cur_size = size;
257+
u64 i_size;
256258

257259
ASSERT((compressed_size > 0 && compressed_pages) ||
258260
(compressed_size == 0 && !compressed_pages));
@@ -323,15 +325,18 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
323325
goto fail;
324326

325327
/*
326-
* we're an inline extent, so nobody can
327-
* extend the file past i_size without locking
328-
* a page we already have locked.
328+
* We're an inline extent, so nobody can extend the file past i_size
329+
* without locking a page we already have locked.
329330
*
330-
* We must do any isize and inode updates
331-
* before we unlock the pages. Otherwise we
332-
* could end up racing with unlink.
331+
* We must do any i_size and inode updates before we unlock the pages.
332+
* Otherwise we could end up racing with unlink.
333333
*/
334-
inode->disk_i_size = i_size_read(&inode->vfs_inode);
334+
i_size = i_size_read(&inode->vfs_inode);
335+
if (update_i_size && size > i_size) {
336+
i_size_write(&inode->vfs_inode, size);
337+
i_size = size;
338+
}
339+
inode->disk_i_size = i_size;
335340

336341
fail:
337342
return ret;
@@ -346,7 +351,8 @@ static int insert_inline_extent(struct btrfs_trans_handle *trans,
346351
static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
347352
size_t compressed_size,
348353
int compress_type,
349-
struct page **compressed_pages)
354+
struct page **compressed_pages,
355+
bool update_i_size)
350356
{
351357
struct btrfs_drop_extents_args drop_args = { 0 };
352358
struct btrfs_root *root = inode->root;
@@ -393,7 +399,7 @@ static noinline int cow_file_range_inline(struct btrfs_inode *inode, u64 size,
393399

394400
ret = insert_inline_extent(trans, path, inode, drop_args.extent_inserted,
395401
size, compressed_size, compress_type,
396-
compressed_pages);
402+
compressed_pages, update_i_size);
397403
if (ret && ret != -ENOSPC) {
398404
btrfs_abort_transaction(trans, ret);
399405
goto out;
@@ -725,12 +731,13 @@ static noinline int compress_file_range(struct async_chunk *async_chunk)
725731
*/
726732
ret = cow_file_range_inline(BTRFS_I(inode), actual_end,
727733
0, BTRFS_COMPRESS_NONE,
728-
NULL);
734+
NULL, false);
729735
} else {
730736
/* try making a compressed inline extent */
731737
ret = cow_file_range_inline(BTRFS_I(inode), actual_end,
732738
total_compressed,
733-
compress_type, pages);
739+
compress_type, pages,
740+
false);
734741
}
735742
if (ret <= 0) {
736743
unsigned long clear_flags = EXTENT_DELALLOC |
@@ -1148,7 +1155,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
11481155

11491156
/* lets try to make an inline extent */
11501157
ret = cow_file_range_inline(inode, actual_end, 0,
1151-
BTRFS_COMPRESS_NONE, NULL);
1158+
BTRFS_COMPRESS_NONE, NULL, false);
11521159
if (ret == 0) {
11531160
/*
11541161
* We use DO_ACCOUNTING here because we need the

0 commit comments

Comments
 (0)