btrfs: don't reserve space for checksums when writing to nocow files
commit feefe1f49d26bad9d8997096e3a200280fa7b1c5 upstream. 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: stable@vger.kernel.org # 6.1+ Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
dfd1f44e49
commit
4d6b2e17b5
|
@ -243,7 +243,6 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
|
|||
struct btrfs_block_rsv *block_rsv = &inode->block_rsv;
|
||||
u64 reserve_size = 0;
|
||||
u64 qgroup_rsv_size = 0;
|
||||
u64 csum_leaves;
|
||||
unsigned outstanding_extents;
|
||||
|
||||
lockdep_assert_held(&inode->lock);
|
||||
|
@ -258,10 +257,12 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
|
|||
outstanding_extents);
|
||||
reserve_size += btrfs_calc_metadata_size(fs_info, 1);
|
||||
}
|
||||
csum_leaves = btrfs_csum_bytes_to_leaves(fs_info,
|
||||
inode->csum_bytes);
|
||||
reserve_size += btrfs_calc_insert_metadata_size(fs_info,
|
||||
csum_leaves);
|
||||
if (!(inode->flags & BTRFS_INODE_NODATASUM)) {
|
||||
u64 csum_leaves;
|
||||
|
||||
csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, inode->csum_bytes);
|
||||
reserve_size += btrfs_calc_insert_metadata_size(fs_info, csum_leaves);
|
||||
}
|
||||
/*
|
||||
* For qgroup rsv, the calculation is very simple:
|
||||
* account one nodesize for each outstanding extent
|
||||
|
@ -276,14 +277,20 @@ static void btrfs_calculate_inode_block_rsv_size(struct btrfs_fs_info *fs_info,
|
|||
spin_unlock(&block_rsv->lock);
|
||||
}
|
||||
|
||||
static void calc_inode_reservations(struct btrfs_fs_info *fs_info,
|
||||
static void calc_inode_reservations(struct btrfs_inode *inode,
|
||||
u64 num_bytes, u64 disk_num_bytes,
|
||||
u64 *meta_reserve, u64 *qgroup_reserve)
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = inode->root->fs_info;
|
||||
u64 nr_extents = count_max_extents(fs_info, num_bytes);
|
||||
u64 csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes);
|
||||
u64 csum_leaves;
|
||||
u64 inode_update = btrfs_calc_metadata_size(fs_info, 1);
|
||||
|
||||
if (inode->flags & BTRFS_INODE_NODATASUM)
|
||||
csum_leaves = 0;
|
||||
else
|
||||
csum_leaves = btrfs_csum_bytes_to_leaves(fs_info, disk_num_bytes);
|
||||
|
||||
*meta_reserve = btrfs_calc_insert_metadata_size(fs_info,
|
||||
nr_extents + csum_leaves);
|
||||
|
||||
|
@ -335,7 +342,7 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes,
|
|||
* everything out and try again, which is bad. This way we just
|
||||
* over-reserve slightly, and clean up the mess when we are done.
|
||||
*/
|
||||
calc_inode_reservations(fs_info, num_bytes, disk_num_bytes,
|
||||
calc_inode_reservations(inode, num_bytes, disk_num_bytes,
|
||||
&meta_reserve, &qgroup_reserve);
|
||||
ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserve, true,
|
||||
noflush);
|
||||
|
@ -356,7 +363,8 @@ int btrfs_delalloc_reserve_metadata(struct btrfs_inode *inode, u64 num_bytes,
|
|||
spin_lock(&inode->lock);
|
||||
nr_extents = count_max_extents(fs_info, num_bytes);
|
||||
btrfs_mod_outstanding_extents(inode, nr_extents);
|
||||
inode->csum_bytes += disk_num_bytes;
|
||||
if (!(inode->flags & BTRFS_INODE_NODATASUM))
|
||||
inode->csum_bytes += disk_num_bytes;
|
||||
btrfs_calculate_inode_block_rsv_size(fs_info, inode);
|
||||
spin_unlock(&inode->lock);
|
||||
|
||||
|
@ -390,7 +398,8 @@ void btrfs_delalloc_release_metadata(struct btrfs_inode *inode, u64 num_bytes,
|
|||
|
||||
num_bytes = ALIGN(num_bytes, fs_info->sectorsize);
|
||||
spin_lock(&inode->lock);
|
||||
inode->csum_bytes -= num_bytes;
|
||||
if (!(inode->flags & BTRFS_INODE_NODATASUM))
|
||||
inode->csum_bytes -= num_bytes;
|
||||
btrfs_calculate_inode_block_rsv_size(fs_info, inode);
|
||||
spin_unlock(&inode->lock);
|
||||
|
||||
|
|
Loading…
Reference in New Issue