Skip to content

Commit 28c9b1e

Browse files
osandovkdave
authored andcommitted
btrfs: support different disk extent size for delalloc
Currently, we always reserve the same extent size in the file and extent size on disk for delalloc because the former is the worst case for the latter. For BTRFS_IOC_ENCODED_WRITE writes, we know the exact size of the extent on disk, which may be less than or greater than (for bookends) the size in the file. Add a disk_num_bytes parameter to btrfs_delalloc_reserve_metadata() so that we can reserve the correct amount of csum bytes. No functional change. Reviewed-by: Nikolay Borisov <[email protected]> Reviewed-by: Josef Bacik <[email protected]> Signed-off-by: Omar Sandoval <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent cb36a9b commit 28c9b1e

File tree

5 files changed

+17
-13
lines changed

5 files changed

+17
-13
lines changed

fs/btrfs/ctree.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2887,7 +2887,8 @@ void btrfs_subvolume_release_metadata(struct btrfs_root *root,
28872887
struct btrfs_block_rsv *rsv);
28882888
void btrfs_delalloc_release_extents(struct btrfs_inode *inode, u64 num_bytes);
28892889

2890-
int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes);
2890+
int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes,
2891+
u64 disk_num_bytes);
28912892
u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo);
28922893
int btrfs_error_unpin_extent_range(struct btrfs_fs_info *fs_info,
28932894
u64 start, u64 end);

fs/btrfs/delalloc-space.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,11 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
270270
}
271271

272272
static void calc_inode_reservations(struct btrfs_fs_info *fs_info,
273-
u64 num_bytes, u64 *meta_reserve,
274-
u64 *qgroup_reserve)
273+
u64 num_bytes, u64 disk_num_bytes,
274+
u64 *meta_reserve, u64 *qgroup_reserve)
275275
{
276276
u64 nr_extents = count_max_extents(num_bytes);
277-
u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, num_bytes);
277+
u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes);
278278
u64 inode_update = btrfs_calc_metadata_size(fs_info, 1);
279279

280280
*meta_reserve = btrfs_calc_insert_metadata_size(fs_info,
@@ -288,7 +288,8 @@ static void calc_inode_reservations(struct btrfs_fs_info *fs_info,
288288
*qgroup_reserve = nr_extents * fs_info->nodesize;
289289
}
290290

291-
int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes)
291+
int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes,
292+
u64 disk_num_bytes)
292293
{
293294
struct btrfs_root *root = inode->root;
294295
struct btrfs_fs_info *fs_info = root->fs_info;
@@ -318,6 +319,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes)
318319
}
319320

320321
num_bytes = ALIGN(num_bytes, fs_info->sectorsize);
322+
disk_num_bytes = ALIGN(disk_num_bytes, fs_info->sectorsize);
321323

322324
/*
323325
* We always want to do it this way, every other way is wrong and ends
@@ -329,8 +331,8 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes)
329331
* everything out and try again, which is bad. This way we just
330332
* over-reserve slightly, and clean up the mess when we are done.
331333
*/
332-
calc_inode_reservations(fs_info, num_bytes, &meta_reserve,
333-
&qgroup_reserve);
334+
calc_inode_reservations(fs_info, num_bytes, disk_num_bytes,
335+
&meta_reserve, &qgroup_reserve);
334336
ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserve, true);
335337
if (ret)
336338
return ret;
@@ -349,7 +351,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes)
349351
spin_lock(&inode->lock);
350352
nr_extents = count_max_extents(num_bytes);
351353
btrfs_mod_outstanding_extents(inode, nr_extents);
352-
inode->csum_bytes += num_bytes;
354+
inode->csum_bytes += disk_num_bytes;
353355
btrfs_calculate_inode_block_rsv_size(fs_info, inode);
354356
spin_unlock(&inode->lock);
355357

@@ -454,7 +456,7 @@ int btrfs_delalloc_reserve_space(struct btrfs_inode *inode,
454456
ret = btrfs_check_data_free_space(inode, reserved, start, len);
455457
if (ret < 0)
456458
return ret;
457-
ret = btrfs_delalloc_reserve_metadata(inode, len);
459+
ret = btrfs_delalloc_reserve_metadata(inode, len, len);
458460
if (ret < 0) {
459461
btrfs_free_reserved_data_space(inode, *reserved, start, len);
460462
extent_changeset_free(*reserved);

fs/btrfs/file.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1719,7 +1719,8 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
17191719
fs_info->sectorsize);
17201720
WARN_ON(reserve_bytes == 0);
17211721
ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode),
1722-
reserve_bytes);
1722+
reserve_bytes,
1723+
reserve_bytes);
17231724
if (ret) {
17241725
if (!only_release_metadata)
17251726
btrfs_free_reserved_data_space(BTRFS_I(inode),

fs/btrfs/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4697,7 +4697,7 @@ int btrfs_truncate_block(struct btrfs_inode *inode, loff_t from, loff_t len,
46974697
goto out;
46984698
}
46994699
}
4700-
ret = btrfs_delalloc_reserve_metadata(inode, blocksize);
4700+
ret = btrfs_delalloc_reserve_metadata(inode, blocksize, blocksize);
47014701
if (ret < 0) {
47024702
if (!only_release_metadata)
47034703
btrfs_free_reserved_data_space(inode, data_reserved,
@@ -7467,7 +7467,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
74677467
struct extent_map *em2;
74687468

74697469
/* We can NOCOW, so only need to reserve metadata space. */
7470-
ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len);
7470+
ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode), len, len);
74717471
if (ret < 0) {
74727472
/* Our caller expects us to free the input extent map. */
74737473
free_extent_map(em);

fs/btrfs/relocation.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2997,7 +2997,7 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra,
29972997

29982998
/* Reserve metadata for this range */
29992999
ret = btrfs_delalloc_reserve_metadata(BTRFS_I(inode),
3000-
clamped_len);
3000+
clamped_len, clamped_len);
30013001
if (ret)
30023002
goto release_page;
30033003

0 commit comments

Comments
 (0)