From patchwork Thu Mar 28 10:54:44 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 2355991 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 3EC03DF2A1 for ; Thu, 28 Mar 2013 10:55:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755368Ab3C1Ky4 (ORCPT ); Thu, 28 Mar 2013 06:54:56 -0400 Received: from mail-pd0-f179.google.com ([209.85.192.179]:53513 "EHLO mail-pd0-f179.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755320Ab3C1Kyz (ORCPT ); Thu, 28 Mar 2013 06:54:55 -0400 Received: by mail-pd0-f179.google.com with SMTP id x11so1121560pdj.10 for ; Thu, 28 Mar 2013 03:54:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=1mjhuBYt+hiKGHyqS0DqpdwkMaltoW2zGkGYSVzZVA4=; b=XCPfB1YJoI2AGYuA8GNGiT2zyGXrkpoeEBHnuGJ8nTmPVhHNw6fIXwv/yu0QkeYHFF 1v6WEL3TNiUxkj9RY+ZakJnDt8C/l6jMjdY4CnoNs2vmQUh/FMRpYLHjjdUYcv0YvBBL xx7GrZARvvYI9TR/eeXXF7Cfc7EmYYvEtOovSxm3b6FlDslH3oTabKLEZYhbzTpblidk 6ghzKcVXHfgjCS9g69ftlmoXXCp5PjZsp4H7fguVNac+bPcofJ0pd3sWEFbSHDDI5wPJ H/wT8xJw4nOvYjK3Bv0SA4xrGFP0F7JPtVEQCqXm3M3T7YU2zl97qjc204BtY1k1ywWG kcOA== X-Received: by 10.66.159.163 with SMTP id xd3mr35169586pab.47.1364468095153; Thu, 28 Mar 2013 03:54:55 -0700 (PDT) Received: from localhost.localdomain.localdomain ([183.209.136.54]) by mx.google.com with ESMTPS id kb3sm25149525pbc.21.2013.03.28.03.54.52 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 28 Mar 2013 03:54:54 -0700 (PDT) From: Wang Shilong To: linux-btrfs@vger.kernel.org Cc: sensille@gmx.net, miaox@cn.fujitsu.com, wangsl-fnst@cn.fujitsu.com Subject: [PATCH V2 3/6] Btrfs: fix missing check before updating qgroup limit Date: Thu, 28 Mar 2013 18:54:44 +0800 Message-Id: <1364468087-1702-2-git-send-email-wangshilong1991@gmail.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1364468087-1702-1-git-send-email-wangshilong1991@gmail.com> References: <1364468087-1702-1-git-send-email-wangshilong1991@gmail.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org From: Wang Shilong 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 Reviewed-by: Miao Xie --- 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; +}