From patchwork Thu Mar 28 10:54:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 2356031 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 C7417DF2A1 for ; Thu, 28 Mar 2013 11:01:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754928Ab3C1LBn (ORCPT ); Thu, 28 Mar 2013 07:01:43 -0400 Received: from mail-pa0-f47.google.com ([209.85.220.47]:42109 "EHLO mail-pa0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751467Ab3C1LBm (ORCPT ); Thu, 28 Mar 2013 07:01:42 -0400 Received: by mail-pa0-f47.google.com with SMTP id bj3so2163555pad.6 for ; Thu, 28 Mar 2013 04:01:42 -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=A6UKSIcSNFcjYbaoq7ltRo/IBliCsgs5AOG5qFeUSk4=; b=ZotGI6lTr9EIXfOtNf8QxrStGPr2X3Fy14myON+UmRJVIvcmKMJACZ4ZWwGNYZnVXS WJEo6ZGnR52ukkJT0/Qtnfn5FsqMs4+ZRbpvTCZplIQpTltTdyylAxl+wS5jPDUsUxHz lSLILvMOejfS35wijYCEro/LV6PsVmHKv5D2eYvHWmZYrz76k8z+ZJLQtTLcpCdwCO1j K70v8Lc1C5z7qU0ONQbe0r0HGP3L9pjPywJlriY9my0BS5MvJeGlsEpCKALIzxPT93aN MqRHuVgyLcvPNJofXKrAw2Ekna2mLLsH2+beMEv2KGoo5xF+aCj9CSpP3CpswM9m2QsM vNvw== X-Received: by 10.68.138.193 with SMTP id qs1mr34880569pbb.9.1364468102240; Thu, 28 Mar 2013 03:55:02 -0700 (PDT) Received: from localhost.localdomain.localdomain ([183.209.136.54]) by mx.google.com with ESMTPS id kb3sm25149525pbc.21.2013.03.28.03.55.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Thu, 28 Mar 2013 03:55:01 -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 6/6] Btrfs: fix missing check before btrfs_qgroup_inherit() Date: Thu, 28 Mar 2013 18:54:47 +0800 Message-Id: <1364468087-1702-5-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 The original code forgot to check 'inherit',we should gurantee that all the qgroups in the struct 'inherit' exist before btrfs_qgroup_inherit(). Signed-off-by: Wang Shilong Reviewed-by: Miao Xie --- fs/btrfs/ctree.h | 2 ++ fs/btrfs/ioctl.c | 6 ++++++ fs/btrfs/qgroup.c | 29 ++++++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 1ca1c63..0e73385 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3855,6 +3855,8 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans, struct btrfs_delayed_extent_op *extent_op); int btrfs_run_qgroups(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); +int btrfs_may_inherit_qgroup(struct btrfs_root *root, + struct btrfs_qgroup_inherit *inherit); int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid, struct btrfs_qgroup_inherit *inherit); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 701d812..96fda7e 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -753,6 +753,11 @@ static noinline int btrfs_mksubvol(struct path *parent, if (btrfs_root_refs(&BTRFS_I(dir)->root->root_item) == 0) goto out_up_read; mutex_lock(&BTRFS_I(dir)->root->fs_info->quota_lock); + + error = btrfs_may_inherit_qgroup(BTRFS_I(dir)->root, inherit); + if (error) + goto out_unlock_mutex; + if (snap_src) { error = create_snapshot(snap_src, dir, dentry, name, namelen, async_transid, readonly, inherit); @@ -762,6 +767,7 @@ static noinline int btrfs_mksubvol(struct path *parent, } if (!error) fsnotify_mkdir(dir, dentry); +out_unlock_mutex: mutex_unlock(&BTRFS_I(dir)->root->fs_info->quota_lock); out_up_read: up_read(&BTRFS_I(dir)->root->fs_info->subvol_sem); diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 0e09ac6..14fca77 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -1359,9 +1359,6 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, if (!fs_info->quota_enabled) return 0; - if (!quota_root) - return -EINVAL; - /* * create a tracking group for the subvol itself */ @@ -1701,3 +1698,29 @@ int btrfs_may_assign_qgroup(struct btrfs_root *root, return 0; return -ENOENT; } + +int btrfs_may_inherit_qgroup(struct btrfs_root *root, + struct btrfs_qgroup_inherit *inherit) +{ + u64 i = 0; + u64 *i_qgroups = NULL; + u64 nums = 0; + struct btrfs_qgroup *qgroup = NULL; + + if (!inherit) + return 0; + if (!root->fs_info->quota_root) + return -EINVAL; + + i_qgroups = (u64 *)(inherit + 1); + nums = inherit->num_qgroups + 2 * inherit->num_ref_copies + + 2 * inherit->num_excl_copies; + for (i = 0; i < nums; ++i) { + qgroup = find_qgroup_rb(root->fs_info, *i_qgroups); + if (!qgroup) + return -EINVAL; + + ++i_qgroups; + } + return 0; +}