Skip to content

Commit feefe1f

Browse files
fdmananakdave
authored andcommitted
btrfs: don't reserve space for checksums when writing to nocow files
Currently when doing a write to a file we always reserve metadata space for inserting data checksums. However we don't need to do it if we have a nodatacow file (-o nodatacow mount option or chattr +C) or if checksums are disabled (-o nodatasum mount option), as in that case we are only adding unnecessary pressure to metadata reservations. For example on x86_64, with the default node size of 16K, a 4K buffered write into a nodatacow file is reserving 655360 bytes of metadata space, as it's accounting for checksums. After this change, which stops reserving space for checksums if we have a nodatacow file or checksums are disabled, we only need to reserve 393216 bytes of metadata. CC: [email protected] # 6.1+ Signed-off-by: Filipe Manana <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 12c5128 commit feefe1f

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

fs/btrfs/delalloc-space.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,6 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
245245
struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
246246
u64 reserve_size = 0;
247247
u64 qgroup_rsv_size = 0;
248-
u64 csum_leaves;
249248
unsigned outstanding_extents;
250249

251250
lockdep_assert_held(&inode->lock);
@@ -260,10 +259,12 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
260259
outstanding_extents);
261260
reserve_size += btrfs_calc_metadata_size(fs_info, 1);
262261
}
263-
csum_leaves = btrfs_csum_bytes_to_leaves(fs_info,
264-
inode->csum_bytes);
265-
reserve_size += btrfs_calc_insert_metadata_size(fs_info,
266-
csum_leaves);
262+
if (!(inode->flags & BTRFS_INODE_NODATASUM)) {
263+
u64 csum_leaves;
264+
265+
csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, inode->csum_bytes);
266+
reserve_size += btrfs_calc_insert_metadata_size(fs_info, csum_leaves);
267+
}
267268
/*
268269
* For qgroup rsv, the calculation is very simple:
269270
* account one nodesize for each outstanding extent
@@ -278,14 +279,20 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
278279
spin_unlock(&block_rsv->lock);
279280
}
280281

281-
static void calc_inode_reservations(struct btrfs_fs_info *fs_info,
282+
static void calc_inode_reservations(struct btrfs_inode *inode,
282283
u64 num_bytes, u64 disk_num_bytes,
283284
u64 *meta_reserve, u64 *qgroup_reserve)
284285
{
286+
struct btrfs_fs_info *fs_info = inode->root->fs_info;
285287
u64 nr_extents = count_max_extents(fs_info, num_bytes);
286-
u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes);
288+
u64 csum_leaves;
287289
u64 inode_update = btrfs_calc_metadata_size(fs_info, 1);
288290

291+
if (inode->flags & BTRFS_INODE_NODATASUM)
292+
csum_leaves = 0;
293+
else
294+
csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes);
295+
289296
*meta_reserve = btrfs_calc_insert_metadata_size(fs_info,
290297
nr_extents + csum_leaves);
291298

@@ -337,7 +344,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes,
337344
* everything out and try again, which is bad. This way we just
338345
* over-reserve slightly, and clean up the mess when we are done.
339346
*/
340-
calc_inode_reservations(fs_info, num_bytes, disk_num_bytes,
347+
calc_inode_reservations(inode, num_bytes, disk_num_bytes,
341348
&meta_reserve, &qgroup_reserve);
342349
ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserve, true,
343350
noflush);
@@ -359,7 +366,8 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes,
359366
nr_extents = count_max_extents(fs_info, num_bytes);
360367
spin_lock(&inode->lock);
361368
btrfs_mod_outstanding_extents(inode, nr_extents);
362-
inode->csum_bytes += disk_num_bytes;
369+
if (!(inode->flags & BTRFS_INODE_NODATASUM))
370+
inode->csum_bytes += disk_num_bytes;
363371
btrfs_calculate_inode_block_rsv_size(fs_info, inode);
364372
spin_unlock(&inode->lock);
365373

@@ -393,7 +401,8 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes,
393401

394402
num_bytes = ALIGN(num_bytes, fs_info->sectorsize);
395403
spin_lock(&inode->lock);
396-
inode->csum_bytes -= num_bytes;
404+
if (!(inode->flags & BTRFS_INODE_NODATASUM))
405+
inode->csum_bytes -= num_bytes;
397406
btrfs_calculate_inode_block_rsv_size(fs_info, inode);
398407
spin_unlock(&inode->lock);
399408

0 commit comments

Comments
 (0)