mirror of https://gitee.com/openkylin/linux.git
Btrfs: fix missing qgroup reservation before fallocating
Steps to reproduce: mkfs.btrfs <disk> mount <disk> <mnt> btrfs quota enable <mnt> btrfs sub create <mnt>/subv btrfs qgroup limit 10M <mnt>/subv fallocate --length 20M <mnt>/subv/data For the above example, fallocating will return successfully which is not expected, we try to fix it by doing qgroup reservation before fallocating. Signed-off-by: Wang Shilong <wangsl-fnst@cn.fujitsu.com> Reviewed-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
This commit is contained in:
parent
835d974fab
commit
6113077cd3
|
@ -2142,6 +2142,7 @@ static long btrfs_fallocate(struct file *file, int mode,
|
|||
{
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
struct extent_state *cached_state = NULL;
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
u64 cur_offset;
|
||||
u64 last_byte;
|
||||
u64 alloc_start;
|
||||
|
@ -2169,6 +2170,11 @@ static long btrfs_fallocate(struct file *file, int mode,
|
|||
ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (root->fs_info->quota_enabled) {
|
||||
ret = btrfs_qgroup_reserve(root, alloc_end - alloc_start);
|
||||
if (ret)
|
||||
goto out_reserve_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* wait for ordered IO before we have any locks. We'll loop again
|
||||
|
@ -2272,6 +2278,9 @@ static long btrfs_fallocate(struct file *file, int mode,
|
|||
&cached_state, GFP_NOFS);
|
||||
out:
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
if (root->fs_info->quota_enabled)
|
||||
btrfs_qgroup_free(root, alloc_end - alloc_start);
|
||||
out_reserve_fail:
|
||||
/* Let go of our reservation. */
|
||||
btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue