From: Wang Shilong <[email protected]> We should check whether a qgroup exists before updating qgroup limit, if the relative qgroup dosen't exsit, return -EEXIST and do not join a transaction, fix it.
Signed-off-by: Wang Shilong <[email protected]> Reviewed-by: Miao Xie <[email protected]> --- fs/btrfs/ctree.h | 1 + fs/btrfs/ioctl.c | 18 ++++++++++-------- fs/btrfs/qgroup.c | 15 ++++++++++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index a11a8ed..3fc393d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3094,6 +3094,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytes_used, u64 type, u64 chunk_objectid, u64 chunk_offset, u64 size); +int btrfs_may_limit_qgroup(struct btrfs_root *root, u64 qgroupid); int btrfs_remove_block_group(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 group_start); void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index e2950f1..7c72b12 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3859,20 +3859,22 @@ static long btrfs_ioctl_qgroup_limit(struct file *file, void __user *arg) ret = PTR_ERR(sa); goto drop_write; } - mutex_lock(&root->fs_info->quota_lock); - trans = btrfs_join_transaction(root); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - goto out; - } - qgroupid = sa->qgroupid; if (!qgroupid) { /* take the current subvol as qgroup */ qgroupid = root->root_key.objectid; } - /* FIXME: check if the IDs really exist */ + mutex_lock(&root->fs_info->quota_lock); + ret = btrfs_may_limit_qgroup(root, qgroupid); + if (ret) + goto out; + + trans = btrfs_join_transaction(root); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out; + } ret = btrfs_limit_qgroup(trans, root->fs_info, qgroupid, &sa->lim); err = btrfs_end_transaction(trans, root); diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 7df372a..bed0e22 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1059,9 +1059,6 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, struct btrfs_qgroup *qgroup; int ret = 0; - if (!quota_root) - return -EINVAL; - ret = update_qgroup_limit_item(trans, quota_root, qgroupid, limit->flags, limit->max_rfer, limit->max_excl, limit->rsv_rfer, @@ -1665,3 +1662,15 @@ void assert_qgroups_uptodate(struct btrfs_trans_handle *trans) trans->delayed_ref_elem.seq); BUG(); } + +int btrfs_may_limit_qgroup(struct btrfs_root *root, u64 qgroupid) +{ + struct btrfs_qgroup *qgroup = NULL; + + if (!root->fs_info->quota_root) + return -EINVAL; + qgroup = find_qgroup_rb(root->fs_info, qgroupid); + if (!qgroup) + return -ENOENT; + return 0; +} -- 1.7.7.6 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
