mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 06:10:53 +07:00
Btrfs: don't use global block reservation for inode cache truncation
It is very likely that there are lots of subvolumes/snapshots in the filesystem, so if we use global block reservation to do inode cache truncation, we may hog all the free space that is reserved in global rsv. So it is better that we do the free space reservation for inode cache truncation by ourselves. Cc: Tsutomu Itoh <t-itoh@jp.fujitsu.com> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
This commit is contained in:
parent
7cfa9e51d2
commit
7b61cd9224
@ -3106,6 +3106,11 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group,
|
|||||||
WARN_ON(ret);
|
WARN_ON(ret);
|
||||||
|
|
||||||
if (i_size_read(inode) > 0) {
|
if (i_size_read(inode) > 0) {
|
||||||
|
ret = btrfs_check_trunc_cache_free_space(root,
|
||||||
|
&root->fs_info->global_block_rsv);
|
||||||
|
if (ret)
|
||||||
|
goto out_put;
|
||||||
|
|
||||||
ret = btrfs_truncate_free_space_cache(root, trans, path,
|
ret = btrfs_truncate_free_space_cache(root, trans, path,
|
||||||
inode);
|
inode);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -197,30 +197,32 @@ int create_free_space_inode(struct btrfs_root *root,
|
|||||||
block_group->key.objectid);
|
block_group->key.objectid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
int btrfs_check_trunc_cache_free_space(struct btrfs_root *root,
|
||||||
struct btrfs_trans_handle *trans,
|
struct btrfs_block_rsv *rsv)
|
||||||
struct btrfs_path *path,
|
|
||||||
struct inode *inode)
|
|
||||||
{
|
{
|
||||||
struct btrfs_block_rsv *rsv;
|
|
||||||
u64 needed_bytes;
|
u64 needed_bytes;
|
||||||
loff_t oldsize;
|
int ret;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
rsv = trans->block_rsv;
|
|
||||||
trans->block_rsv = &root->fs_info->global_block_rsv;
|
|
||||||
|
|
||||||
/* 1 for slack space, 1 for updating the inode */
|
/* 1 for slack space, 1 for updating the inode */
|
||||||
needed_bytes = btrfs_calc_trunc_metadata_size(root, 1) +
|
needed_bytes = btrfs_calc_trunc_metadata_size(root, 1) +
|
||||||
btrfs_calc_trans_metadata_size(root, 1);
|
btrfs_calc_trans_metadata_size(root, 1);
|
||||||
|
|
||||||
spin_lock(&trans->block_rsv->lock);
|
spin_lock(&rsv->lock);
|
||||||
if (trans->block_rsv->reserved < needed_bytes) {
|
if (rsv->reserved < needed_bytes)
|
||||||
spin_unlock(&trans->block_rsv->lock);
|
ret = -ENOSPC;
|
||||||
trans->block_rsv = rsv;
|
else
|
||||||
return -ENOSPC;
|
ret = 0;
|
||||||
}
|
spin_unlock(&rsv->lock);
|
||||||
spin_unlock(&trans->block_rsv->lock);
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
||||||
|
struct btrfs_trans_handle *trans,
|
||||||
|
struct btrfs_path *path,
|
||||||
|
struct inode *inode)
|
||||||
|
{
|
||||||
|
loff_t oldsize;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
oldsize = i_size_read(inode);
|
oldsize = i_size_read(inode);
|
||||||
btrfs_i_size_write(inode, 0);
|
btrfs_i_size_write(inode, 0);
|
||||||
@ -232,9 +234,7 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
|||||||
*/
|
*/
|
||||||
ret = btrfs_truncate_inode_items(trans, root, inode,
|
ret = btrfs_truncate_inode_items(trans, root, inode,
|
||||||
0, BTRFS_EXTENT_DATA_KEY);
|
0, BTRFS_EXTENT_DATA_KEY);
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
trans->block_rsv = rsv;
|
|
||||||
btrfs_abort_transaction(trans, root, ret);
|
btrfs_abort_transaction(trans, root, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -242,7 +242,6 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
|||||||
ret = btrfs_update_inode(trans, root, inode);
|
ret = btrfs_update_inode(trans, root, inode);
|
||||||
if (ret)
|
if (ret)
|
||||||
btrfs_abort_transaction(trans, root, ret);
|
btrfs_abort_transaction(trans, root, ret);
|
||||||
trans->block_rsv = rsv;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,8 @@ int create_free_space_inode(struct btrfs_root *root,
|
|||||||
struct btrfs_block_group_cache *block_group,
|
struct btrfs_block_group_cache *block_group,
|
||||||
struct btrfs_path *path);
|
struct btrfs_path *path);
|
||||||
|
|
||||||
|
int btrfs_check_trunc_cache_free_space(struct btrfs_root *root,
|
||||||
|
struct btrfs_block_rsv *rsv);
|
||||||
int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
int btrfs_truncate_free_space_cache(struct btrfs_root *root,
|
||||||
struct btrfs_trans_handle *trans,
|
struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_path *path,
|
struct btrfs_path *path,
|
||||||
|
@ -429,11 +429,12 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
|
|||||||
num_bytes = trans->bytes_reserved;
|
num_bytes = trans->bytes_reserved;
|
||||||
/*
|
/*
|
||||||
* 1 item for inode item insertion if need
|
* 1 item for inode item insertion if need
|
||||||
* 3 items for inode item update (in the worst case)
|
* 4 items for inode item update (in the worst case)
|
||||||
|
* 1 items for slack space if we need do truncation
|
||||||
* 1 item for free space object
|
* 1 item for free space object
|
||||||
* 3 items for pre-allocation
|
* 3 items for pre-allocation
|
||||||
*/
|
*/
|
||||||
trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 8);
|
trans->bytes_reserved = btrfs_calc_trans_metadata_size(root, 10);
|
||||||
ret = btrfs_block_rsv_add(root, trans->block_rsv,
|
ret = btrfs_block_rsv_add(root, trans->block_rsv,
|
||||||
trans->bytes_reserved,
|
trans->bytes_reserved,
|
||||||
BTRFS_RESERVE_NO_FLUSH);
|
BTRFS_RESERVE_NO_FLUSH);
|
||||||
|
@ -3350,6 +3350,11 @@ static int delete_block_group_cache(struct btrfs_fs_info *fs_info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
truncate:
|
truncate:
|
||||||
|
ret = btrfs_check_trunc_cache_free_space(root,
|
||||||
|
&fs_info->global_block_rsv);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
path = btrfs_alloc_path();
|
path = btrfs_alloc_path();
|
||||||
if (!path) {
|
if (!path) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
Loading…
Reference in New Issue
Block a user