diff options
author | Qu Wenruo <quwenruo@cn.fujitsu.com> | 2015-02-27 03:24:22 -0500 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-04-13 10:52:53 -0400 |
commit | 8465ecec9611d60cbbc8e374ecf68453e0dd5b50 (patch) | |
tree | eae55fdac84734729dfbfa6488ec76b6d322199c | |
parent | f5a6b1c53bdd44f79e3904c0f5e59f956b49b2c8 (diff) |
btrfs: Check qgroup level in kernel qgroup assign.
Although we have qgroup level check in btrfs-progs, it's not enough
since other programe may still call ioctl directly not using
btrfs-progs. For example, systemd.
But it's btrfs-progs to be blame since we don't provide a
full-function(like subvolume create things) btrfs library with enough
check, and only rely on kernel ioctl.
So Add level checks in kernel too.
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Reviewed-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
-rw-r--r-- | fs/btrfs/qgroup.c | 4 |
2 files changed, 10 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 851f2355f3c8..8b851ac7c3fa 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1061,6 +1061,12 @@ struct btrfs_block_group_item { | |||
1061 | __le64 flags; | 1061 | __le64 flags; |
1062 | } __attribute__ ((__packed__)); | 1062 | } __attribute__ ((__packed__)); |
1063 | 1063 | ||
1064 | #define BTRFS_QGROUP_LEVEL_SHIFT 48 | ||
1065 | static inline u64 btrfs_qgroup_level(u64 qgroupid) | ||
1066 | { | ||
1067 | return qgroupid >> BTRFS_QGROUP_LEVEL_SHIFT; | ||
1068 | } | ||
1069 | |||
1064 | /* | 1070 | /* |
1065 | * is subvolume quota turned on? | 1071 | * is subvolume quota turned on? |
1066 | */ | 1072 | */ |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 464d1e237512..4fb9610beec7 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -1009,6 +1009,10 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, | |||
1009 | struct btrfs_qgroup_list *list; | 1009 | struct btrfs_qgroup_list *list; |
1010 | int ret = 0; | 1010 | int ret = 0; |
1011 | 1011 | ||
1012 | /* Check the level of src and dst first */ | ||
1013 | if (btrfs_qgroup_level(src) >= btrfs_qgroup_level(dst)) | ||
1014 | return -EINVAL; | ||
1015 | |||
1012 | mutex_lock(&fs_info->qgroup_ioctl_lock); | 1016 | mutex_lock(&fs_info->qgroup_ioctl_lock); |
1013 | quota_root = fs_info->quota_root; | 1017 | quota_root = fs_info->quota_root; |
1014 | if (!quota_root) { | 1018 | if (!quota_root) { |