From patchwork Tue Mar 26 11:55:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wang Shilong X-Patchwork-Id: 2336161 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 9C935DF264 for ; Tue, 26 Mar 2013 11:55:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759398Ab3CZLzs (ORCPT ); Tue, 26 Mar 2013 07:55:48 -0400 Received: from mail-da0-f47.google.com ([209.85.210.47]:56484 "EHLO mail-da0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757614Ab3CZLzp (ORCPT ); Tue, 26 Mar 2013 07:55:45 -0400 Received: by mail-da0-f47.google.com with SMTP id s35so3621413dak.6 for ; Tue, 26 Mar 2013 04:55:44 -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=FVRFA5t+IWcLe+fofXfJ/R/E0Oh8ZwyhHNvH08618sg=; b=vkw3OkiNS8ktFiiN5BmkQCg4dVQcnPp/NT8cuCRNOAie2rFaO695fDztssqHm6jWae 2LcmEyyvu++k6znn7OZ16P+H/Q7KXLBCKo5yuDoJZuYUgkpq4vgkjKNVvQqe4Gp1ZZ3u Lfz/hWF1UJY1K7ZjkdcTARM6wndMrKYPu/jgsQWEcmB6MZtVfQmfevHB2JK+Yd2CuyDe TysU8myqhSwuctvH8KX4hWEiL7QO0v8QsY6N2IEkkJUub9uDfnwXE4xhLcqzXIVURH5j jkYqStuFzxLp/iuuGnT40j7KROOh3e7ciqSIS05v/K6DZWQBmN0ciRn/kQbV7Jl1QB+o SBnw== X-Received: by 10.66.221.66 with SMTP id qc2mr23422587pac.10.1364298944685; Tue, 26 Mar 2013 04:55:44 -0700 (PDT) Received: from localhost.localdomain.localdomain ([223.65.184.172]) by mx.google.com with ESMTPS id fh1sm18974580pac.1.2013.03.26.04.55.42 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 26 Mar 2013 04:55:44 -0700 (PDT) From: Wang Shilong To: linux-btrfs@vger.kernel.org Cc: sensille@gmx.net, miaox@cn.fujitsu.com, wangshilong1991@gmail.com Subject: [PATCH 5/7] Btrfs: fix missing check before btrfs_qgroup_inherit() Date: Tue, 26 Mar 2013 19:55:28 +0800 Message-Id: <1364298930-4507-5-git-send-email-wangshilong1991@gmail.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1364298930-4507-1-git-send-email-wangshilong1991@gmail.com> References: <1364298930-4507-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 dosen't have necessary checks before doing qgroup_inherit. Fix it. Signed-off-by: Wang Shilong Reviewed-by: Miao Xie --- fs/btrfs/ioctl.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 1cd96f6..86e7fb3 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -708,6 +708,49 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child) return inode_permission(dir, MAY_WRITE | MAY_EXEC); } +static int check_qgroup_inherit(struct btrfs_root *root, + struct btrfs_qgroup_inherit *inherit) +{ + int ret = 0; + u64 *i_qgroups; + u64 nums = 0; + u64 i = 0; + struct btrfs_path *path; + struct btrfs_key key; + + if (!inherit) + return 0; + if (!root->fs_info->quota_root) + return -EINVAL; + + path = btrfs_alloc_path(); + if (!path) { + ret = -ENOMEM; + return ret; + } + + i_qgroups = (u64 *)(inherit + 1); + nums = inherit->num_qgroups + inherit->num_ref_copies + + inherit->num_excl_copies; + for (i = 0; i < nums; ++i) { + btrfs_release_path(path); + key.objectid = 0; + key.type = BTRFS_QGROUP_INFO_KEY; + key.offset = *i_qgroups; + + ret = btrfs_search_slot(NULL, root->fs_info->quota_root, + &key, path, 0, 0); + if (ret > 0) + ret = -EINVAL; + if (ret) + goto out; + ++i_qgroups; + } +out: + btrfs_free_path(path); + return ret; +} + /* * Create a new subvolume below @parent. This is largely modeled after * sys_mkdirat and vfs_mkdir, but we only do a single component lookup @@ -753,6 +796,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 = check_qgroup_inherit(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 +810,8 @@ 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); out_dput: