* [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup.
@ 2015-02-10 10:24 Dongsheng Yang
2015-02-10 10:24 ` [PATCH 1/4] btrfs-progs: Add type to qgroup Dongsheng Yang
` (12 more replies)
0 siblings, 13 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
Hi all,
This patchset is based on [Btrfs: qgroup: part-3: bug fixes.]
I am introducing a type to qgroup, then we can get the numbers what we
only care about.
Easy way to get the code for testing:
btrfs: https://yangdongsheng@github.com/yangdongsheng/linux.git qgroup_type
btrfs-progs: https://yangdongsheng@github.com/yangdongsheng/btrfs-progs.git qgroup_type
with the patches applied in this series, both in btrfs and btrfs-progs:
[root@atest-guest linux_btrfs]# mkfs.btrfs -O qgroup-type /dev/sdc -f
Btrfs v3.18-76-ga900a61
See http://btrfs.wiki.kernel.org for more information.
Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
Turning ON incompat feature 'skinny-metadata': reduced-size metadata extent refs
Turning ON incompat feature 'qgroup-type': create qgroup in different type
fs created label (null) on /dev/sdc
nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
[root@atest-guest linux_btrfs]# mount /dev/sdc /mnt/
[root@atest-guest linux_btrfs]# btrfs quota enable /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child type
-------- ---- ---- -------- -------- ------ ----- ----
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child type
-------- ---- ---- -------- -------- ------ ----- ----
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data <--- default type is mixed.
[root@atest-guest linux_btrfs]# btrfs sub create --qgroup-type data /mnt/sub1
Create subvolume '/mnt/sub1'
Set qgroup arguments:
qgroup type: data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child type
-------- ---- ---- -------- -------- ------ ----- ----
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
0/258 0.00B 0.00B 0.00B 0.00B --- --- data <--- create a data qgroup
[root@atest-guest linux_btrfs]# btrfs qgroup limit -e 5M 0/258 /mnt
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
qgroupid rfer excl max_rfer max_excl parent child type
-------- ---- ---- -------- -------- ------ ----- ----
0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
0/258 0.00B 0.00B 0.00B 5.00MiB --- --- data
[root@atest-guest linux_btrfs]# dd if=/dev/zero of=/mnt/sub1/data bs=1024
dd: error writing \u2018/mnt/sub1/data\u2019: Disk quota exceeded
5121+0 records in
5120+0 records out
5242880 bytes (5.2 MB) copied, 0.0218646 s, 240 MB/s
[root@atest-guest linux_btrfs]# sync
[root@atest-guest linux_btrfs]# ll /mnt/sub1/data
-rw-r--r--. 1 root root 5242880 Feb 10 16:17 /mnt/sub1/data
[root@atest-guest linux_btrfs]# btrfs qgroup show -prce --raw /mnt
qgroupid rfer excl max_rfer max_excl parent child type
-------- ---- ---- -------- -------- ------ ----- ----
0/5 16384 16384 0 0 --- --- metadata,data
0/257 16384 16384 0 0 --- --- metadata,data
0/258 5242880 5242880 0 5242880 --- --- data <--- excl == max_excl == data_size == 5M == 5242880
Dongsheng Yang (7):
Btrfs: qgroup: Add type to btrfs_qgroup.
btrfs: qgroup: apply type to the recording and accounting.
btrfs: qgroup: Apply type to btrfs_qgroup_inherit().
btrfs: qgroup: Apply qgroup type to qgroup creating.
btrfs: qgroup: Apply qgroup type to subvol creating.
btrfs: qgroup: apply type to quota rescan.
btrfs: qgroup: fix a bug when type of parent is different with
child's.
fs/btrfs/ctree.h | 10 ++-
fs/btrfs/extent-tree.c | 48 ++++++-----
fs/btrfs/ioctl.c | 49 ++++++++---
fs/btrfs/qgroup.c | 186 ++++++++++++++++++++++++++++--------------
fs/btrfs/qgroup.h | 29 ++++++-
fs/btrfs/tests/qgroup-tests.c | 19 +++--
fs/btrfs/transaction.c | 13 +--
include/uapi/linux/btrfs.h | 1 +
8 files changed, 246 insertions(+), 109 deletions(-)
--
1.8.4.2
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/4] btrfs-progs: Add type to qgroup.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 1/7] Btrfs: qgroup: Add type to btrfs_qgroup Dongsheng Yang
` (11 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
ctree.h | 12 +++++++++++-
ioctl.h | 1 +
mkfs.c | 2 ++
print-tree.c | 9 +++++++++
qgroup.c | 25 +++++++++++++++++++------
qgroup.h | 16 ++++++++++++++++
6 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/ctree.h b/ctree.h
index c069a95..6b8e144 100644
--- a/ctree.h
+++ b/ctree.h
@@ -474,6 +474,10 @@ struct btrfs_super_block {
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
#define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
+/*
+ * * Add a type in btrfs_qgroup_info_item;
+ * */
+#define BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE (1ULL << 10)
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL
@@ -486,7 +490,8 @@ struct btrfs_super_block {
BTRFS_FEATURE_INCOMPAT_RAID56 | \
BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \
BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA | \
- BTRFS_FEATURE_INCOMPAT_NO_HOLES)
+ BTRFS_FEATURE_INCOMPAT_NO_HOLES | \
+ BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE)
/*
* A leaf is full of items. offset and size tell us where to find
@@ -892,6 +897,7 @@ struct btrfs_qgroup_info_item {
__le64 referenced_compressed;
__le64 exclusive;
__le64 exclusive_compressed;
+ __u8 type;
} __attribute__ ((__packed__));
/* flags definition for qgroup limits */
@@ -2059,6 +2065,8 @@ BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item,
/* btrfs_qgroup_info_item */
BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item,
generation, 64);
+BTRFS_SETGET_FUNCS(qgroup_info_type, struct btrfs_qgroup_info_item,
+ type, 8);
BTRFS_SETGET_FUNCS(qgroup_info_referenced, struct btrfs_qgroup_info_item,
referenced, 64);
BTRFS_SETGET_FUNCS(qgroup_info_referenced_compressed,
@@ -2070,6 +2078,8 @@ BTRFS_SETGET_FUNCS(qgroup_info_exclusive_compressed,
BTRFS_SETGET_STACK_FUNCS(stack_qgroup_info_generation,
struct btrfs_qgroup_info_item, generation, 64);
+BTRFS_SETGET_STACK_FUNCS(stack_qgroup_info_type,
+ struct btrfs_qgroup_info_item, type, 8);
BTRFS_SETGET_STACK_FUNCS(stack_qgroup_info_referenced,
struct btrfs_qgroup_info_item, referenced, 64);
BTRFS_SETGET_STACK_FUNCS(stack_qgroup_info_referenced_compressed,
diff --git a/ioctl.h b/ioctl.h
index a47eab8..892f8de 100644
--- a/ioctl.h
+++ b/ioctl.h
@@ -77,6 +77,7 @@ struct btrfs_ioctl_vol_args_v2 {
struct {
__u64 size;
struct btrfs_qgroup_inherit *qgroup_inherit;
+ __u8 qgroup_type;
};
__u64 unused[4];
};
diff --git a/mkfs.c b/mkfs.c
index 18c4cb0..379068d 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1144,6 +1144,8 @@ static const struct btrfs_fs_feature {
"reduced-size metadata extent refs" },
{ "no-holes", BTRFS_FEATURE_INCOMPAT_NO_HOLES,
"no explicit hole extents for files" },
+ { "qgroup-type", BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE,
+ "create qgroup in different type" },
/* Keep this one last */
{ "list-all", BTRFS_FEATURE_LIST_ALL, NULL }
};
diff --git a/print-tree.c b/print-tree.c
index 70a7acc..6bfcc32 100644
--- a/print-tree.c
+++ b/print-tree.c
@@ -25,6 +25,7 @@
#include "disk-io.h"
#include "print-tree.h"
#include "utils.h"
+#include "qgroup.h"
static void print_dir_item_type(struct extent_buffer *eb,
@@ -797,6 +798,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
u32 nr = btrfs_header_nritems(l);
u64 objectid;
u32 type;
+ u8 qgroup_type = BTRFS_QGROUP_TYPE_DEFAULT;
char bg_flags_str[32];
printf("leaf %llu items %d free space %d generation %llu owner %llu\n",
@@ -980,6 +982,13 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
(unsigned long long)
btrfs_qgroup_info_exclusive_compressed(l,
qg_info));
+
+ if (btrfs_fs_incompat(root->fs_info,
+ BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE))
+ qgroup_type = btrfs_qgroup_info_type(l, qg_info);
+
+ printf("\t\tqgroup type %u\n",
+ (unsigned int)qgroup_type);
break;
case BTRFS_QGROUP_LIMIT_KEY:
qg_limit = btrfs_item_ptr(l, i,
diff --git a/qgroup.c b/qgroup.c
index 620ec7e..8a7c20f 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -48,6 +48,7 @@ struct btrfs_qgroup {
u64 rfer_cmpr; /*referenced compressed*/
u64 excl; /*exclusive*/
u64 excl_cmpr; /*exclusive compressed*/
+ u8 type;
/*
*limit_item
@@ -572,7 +573,7 @@ static struct btrfs_qgroup *qgroup_tree_search(struct qgroup_lookup *root_tree,
static int update_qgroup(struct qgroup_lookup *qgroup_lookup, u64 qgroupid,
u64 generation, u64 rfer, u64 rfer_cmpr, u64 excl,
- u64 excl_cmpr, u64 flags, u64 max_rfer, u64 max_excl,
+ u64 excl_cmpr, u8 type, u64 flags, u64 max_rfer, u64 max_excl,
u64 rsv_rfer, u64 rsv_excl, struct btrfs_qgroup *pa,
struct btrfs_qgroup *child)
{
@@ -593,6 +594,8 @@ static int update_qgroup(struct qgroup_lookup *qgroup_lookup, u64 qgroupid,
bq->excl = excl;
if (excl_cmpr)
bq->excl_cmpr = excl_cmpr;
+ if (type)
+ bq->type = type;
if (flags)
bq->flags = flags;
if (max_rfer)
@@ -617,7 +620,7 @@ static int update_qgroup(struct qgroup_lookup *qgroup_lookup, u64 qgroupid,
static int add_qgroup(struct qgroup_lookup *qgroup_lookup, u64 qgroupid,
u64 generation, u64 rfer, u64 rfer_cmpr, u64 excl,
- u64 excl_cmpr, u64 flags, u64 max_rfer, u64 max_excl,
+ u64 excl_cmpr, u8 type, u64 flags, u64 max_rfer, u64 max_excl,
u64 rsv_rfer, u64 rsv_excl, struct btrfs_qgroup *parent,
struct btrfs_qgroup *child)
{
@@ -626,7 +629,7 @@ static int add_qgroup(struct qgroup_lookup *qgroup_lookup, u64 qgroupid,
int ret;
ret = update_qgroup(qgroup_lookup, qgroupid, generation, rfer,
- rfer_cmpr, excl, excl_cmpr, flags, max_rfer,
+ rfer_cmpr, excl, excl_cmpr, type, flags, max_rfer,
max_excl, rsv_rfer, rsv_excl, parent, child);
if (!ret)
return 0;
@@ -652,6 +655,8 @@ static int add_qgroup(struct qgroup_lookup *qgroup_lookup, u64 qgroupid,
bq->excl = excl;
if (excl_cmpr)
bq->excl_cmpr = excl_cmpr;
+ if (type)
+ bq->type = type;
if (flags)
bq->flags = flags;
if (max_rfer)
@@ -1031,6 +1036,7 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
u64 a3;
u64 a4;
u64 a5;
+ u8 type;
memset(&args, 0, sizeof(args));
@@ -1044,6 +1050,8 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
qgroup_lookup_init(qgroup_lookup);
+ type = BTRFS_QGROUP_TYPE_DEFAULT;
+
while (1) {
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args);
e = errno;
@@ -1079,8 +1087,13 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
a5 =
btrfs_stack_qgroup_info_exclusive_compressed
(info);
+ /*
+ * Check incompatability of qgroup->type.
+ */
+ if (sh->len == sizeof(*info))
+ type = btrfs_stack_qgroup_info_type(info);
add_qgroup(qgroup_lookup, sh->offset, a1, a2,
- a3, a4, a5, 0, 0, 0, 0, 0, 0, 0);
+ a3, a4, a5, type, 0, 0, 0, 0, 0, 0, 0);
} else if (sh->type == BTRFS_QGROUP_LIMIT_KEY) {
limit = (struct btrfs_qgroup_limit_item *)
(args.buf + off);
@@ -1095,7 +1108,7 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
a5 = btrfs_stack_qgroup_limit_rsv_exclusive
(limit);
add_qgroup(qgroup_lookup, sh->offset, 0, 0,
- 0, 0, 0, a1, a2, a3, a4, a5, 0, 0);
+ 0, 0, 0, 0, a1, a2, a3, a4, a5, 0, 0);
} else if (sh->type == BTRFS_QGROUP_RELATION_KEY) {
if (sh->offset < sh->objectid)
goto skip;
@@ -1108,7 +1121,7 @@ static int __qgroups_search(int fd, struct qgroup_lookup *qgroup_lookup)
if (!bq1)
goto skip;
add_qgroup(qgroup_lookup, sh->offset, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, bq, bq1);
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, bq, bq1);
} else
goto done;
skip:
diff --git a/qgroup.h b/qgroup.h
index e5d03ca..421eb42 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -22,6 +22,22 @@
#include "ioctl.h"
#include "kerncompat.h"
+/*
+ * * Type for qgroup.
+ * */
+#define BTRFS_QGROUP_TYPE_DATA (1 << 0)
+#define BTRFS_QGROUP_TYPE_METADATA (1 << 1)
+#define BTRFS_QGROUP_TYPE_MIXED (BTRFS_QGROUP_TYPE_DATA | \
+ BTRFS_QGROUP_TYPE_METADATA)
+
+#define BTRFS_QGROUP_TYPE_DEFAULT BTRFS_QGROUP_TYPE_MIXED
+
+/*
+ * * We are using the first byte in ->create of btrfs_ioctl_qgroup_create_args
+ * * to specify the type of the qgroup to be created.
+ * */
+#define BTRFS_QGROUP_TYPE_SHIFT 56
+
struct btrfs_qgroup;
typedef int (*btrfs_qgroup_filter_func)(struct btrfs_qgroup *, u64);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 1/7] Btrfs: qgroup: Add type to btrfs_qgroup.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
2015-02-10 10:24 ` [PATCH 1/4] btrfs-progs: Add type to qgroup Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 2/4] btrfs-progs: specify qgroup type when creating subvolume Dongsheng Yang
` (10 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
This patch is introducing a *type* to btrfs_qgroup.
Type could be data, metadata or both. data means this
qgroup only care about the data size, metadata means
this qgroup only care about the metadata size and both
means this qgroup will care about data and metadata like
what it was doing before this patch.
This idea comes from some complain of user that
"Why I can not write one byte in the subvolume when
the qgroup does not reach the limit?". That is caused
by the qgroup was accounting the metadata also, but it
is not confusing to a user.
So this patch here allow user to only limit the data size
in a qgroup.
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
fs/btrfs/ctree.h | 10 ++++++++-
fs/btrfs/ioctl.c | 3 ++-
fs/btrfs/qgroup.c | 47 +++++++++++++++++++++++++++++++------------
fs/btrfs/qgroup.h | 12 ++++++++++-
fs/btrfs/tests/qgroup-tests.c | 4 ++--
5 files changed, 58 insertions(+), 18 deletions(-)
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 1d17e7a..24b0d42 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -521,6 +521,11 @@ struct btrfs_super_block {
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
#define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
+/*
+ * Add a type in btrfs_qgroup_info_item;
+ */
+#define BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE (1ULL << 10)
+
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
#define BTRFS_FEATURE_COMPAT_SAFE_SET 0ULL
#define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL
@@ -537,7 +542,8 @@ struct btrfs_super_block {
BTRFS_FEATURE_INCOMPAT_RAID56 | \
BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \
BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA | \
- BTRFS_FEATURE_INCOMPAT_NO_HOLES)
+ BTRFS_FEATURE_INCOMPAT_NO_HOLES | \
+ BTRFS_FEATURE_INCOMPAT_QGROUP_TYPE)
#define BTRFS_FEATURE_INCOMPAT_SAFE_SET \
(BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
@@ -1101,6 +1107,7 @@ struct btrfs_qgroup_info_item {
__le64 rfer_cmpr;
__le64 excl;
__le64 excl_cmpr;
+ __u8 type;
} __attribute__ ((__packed__));
/* flags definition for qgroup limits */
@@ -3214,6 +3221,7 @@ BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item,
/* btrfs_qgroup_info_item */
BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item,
generation, 64);
+BTRFS_SETGET_FUNCS(qgroup_info_type, struct btrfs_qgroup_info_item, type, 8);
BTRFS_SETGET_FUNCS(qgroup_info_rfer, struct btrfs_qgroup_info_item, rfer, 64);
BTRFS_SETGET_FUNCS(qgroup_info_rfer_cmpr, struct btrfs_qgroup_info_item,
rfer_cmpr, 64);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f6e730b..a50f295 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4675,7 +4675,8 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
/* FIXME: check if the IDs really exist */
if (sa->create) {
- ret = btrfs_create_qgroup(trans, root->fs_info, sa->qgroupid);
+ ret = btrfs_create_qgroup(trans, root->fs_info, sa->qgroupid,
+ BTRFS_QGROUP_TYPE_DEFAULT);
} else {
ret = btrfs_remove_qgroup(trans, root->fs_info, sa->qgroupid);
}
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 28b0aa5..8ac785a 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -51,6 +51,7 @@
*/
struct btrfs_qgroup {
u64 qgroupid;
+ u8 type;
/*
* state
@@ -128,7 +129,7 @@ static struct btrfs_qgroup *find_qgroup_rb(struct btrfs_fs_info *fs_info,
/* must be called with qgroup_lock held */
static struct btrfs_qgroup *add_qgroup_rb(struct btrfs_fs_info *fs_info,
- u64 qgroupid)
+ u64 qgroupid, u8 type)
{
struct rb_node **p = &fs_info->qgroup_tree.rb_node;
struct rb_node *parent = NULL;
@@ -151,6 +152,7 @@ static struct btrfs_qgroup *add_qgroup_rb(struct btrfs_fs_info *fs_info,
return ERR_PTR(-ENOMEM);
qgroup->qgroupid = qgroupid;
+ qgroup->type = type;
INIT_LIST_HEAD(&qgroup->groups);
INIT_LIST_HEAD(&qgroup->members);
INIT_LIST_HEAD(&qgroup->dirty);
@@ -348,7 +350,8 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
}
if (!qgroup) {
- qgroup = add_qgroup_rb(fs_info, found_key.offset);
+ qgroup = add_qgroup_rb(fs_info, found_key.offset,
+ BTRFS_QGROUP_TYPE_DEFAULT);
if (IS_ERR(qgroup)) {
ret = PTR_ERR(qgroup);
goto out;
@@ -360,6 +363,8 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
ptr = btrfs_item_ptr(l, slot,
struct btrfs_qgroup_info_item);
+ if (btrfs_fs_incompat(fs_info, QGROUP_TYPE))
+ qgroup->type = btrfs_qgroup_info_type(l, ptr);
qgroup->rfer = btrfs_qgroup_info_rfer(l, ptr);
qgroup->rfer_cmpr = btrfs_qgroup_info_rfer_cmpr(l, ptr);
qgroup->excl = btrfs_qgroup_info_excl(l, ptr);
@@ -530,7 +535,8 @@ out:
}
static int add_qgroup_item(struct btrfs_trans_handle *trans,
- struct btrfs_root *quota_root, u64 qgroupid)
+ struct btrfs_root *quota_root, u64 qgroupid,
+ u8 type)
{
int ret;
struct btrfs_path *path;
@@ -538,6 +544,7 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans,
struct btrfs_qgroup_limit_item *qgroup_limit;
struct extent_buffer *leaf;
struct btrfs_key key;
+ unsigned long size_of_info = 0;
if (btrfs_test_is_dummy_root(quota_root))
return 0;
@@ -556,8 +563,12 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans,
* on disk.
*/
+ size_of_info = sizeof(*qgroup_info);
+ if (!btrfs_fs_incompat(quota_root->fs_info, QGROUP_TYPE))
+ size_of_info = size_of_info - sizeof(u8);
+
ret = btrfs_insert_empty_item(trans, quota_root, path, &key,
- sizeof(*qgroup_info));
+ size_of_info);
if (ret && ret != -EEXIST)
goto out;
@@ -565,6 +576,8 @@ static int add_qgroup_item(struct btrfs_trans_handle *trans,
qgroup_info = btrfs_item_ptr(leaf, path->slots[0],
struct btrfs_qgroup_info_item);
btrfs_set_qgroup_info_generation(leaf, qgroup_info, trans->transid);
+ if (btrfs_fs_incompat(quota_root->fs_info, QGROUP_TYPE))
+ btrfs_set_qgroup_info_type(leaf, qgroup_info, type);
btrfs_set_qgroup_info_rfer(leaf, qgroup_info, 0);
btrfs_set_qgroup_info_rfer_cmpr(leaf, qgroup_info, 0);
btrfs_set_qgroup_info_excl(leaf, qgroup_info, 0);
@@ -722,6 +735,8 @@ static int update_qgroup_info_item(struct btrfs_trans_handle *trans,
btrfs_set_qgroup_info_rfer_cmpr(l, qgroup_info, qgroup->rfer_cmpr);
btrfs_set_qgroup_info_excl(l, qgroup_info, qgroup->excl);
btrfs_set_qgroup_info_excl_cmpr(l, qgroup_info, qgroup->excl_cmpr);
+ if (btrfs_fs_incompat(root->fs_info, QGROUP_TYPE))
+ btrfs_set_qgroup_info_type(l, qgroup_info, qgroup->type);
btrfs_mark_buffer_dirty(l);
@@ -902,11 +917,13 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
if (found_key.type == BTRFS_ROOT_REF_KEY) {
ret = add_qgroup_item(trans, quota_root,
- found_key.offset);
+ found_key.offset,
+ BTRFS_QGROUP_TYPE_DEFAULT);
if (ret)
goto out_free_path;
- qgroup = add_qgroup_rb(fs_info, found_key.offset);
+ qgroup = add_qgroup_rb(fs_info, found_key.offset,
+ BTRFS_QGROUP_TYPE_DEFAULT);
if (IS_ERR(qgroup)) {
ret = PTR_ERR(qgroup);
goto out_free_path;
@@ -921,11 +938,13 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans,
out_add_root:
btrfs_release_path(path);
- ret = add_qgroup_item(trans, quota_root, BTRFS_FS_TREE_OBJECTID);
+ ret = add_qgroup_item(trans, quota_root, BTRFS_FS_TREE_OBJECTID,
+ BTRFS_QGROUP_TYPE_DEFAULT);
if (ret)
goto out_free_path;
- qgroup = add_qgroup_rb(fs_info, BTRFS_FS_TREE_OBJECTID);
+ qgroup = add_qgroup_rb(fs_info, BTRFS_FS_TREE_OBJECTID,
+ BTRFS_QGROUP_TYPE_DEFAULT);
if (IS_ERR(qgroup)) {
ret = PTR_ERR(qgroup);
goto out_free_path;
@@ -1118,7 +1137,8 @@ int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
}
int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
- struct btrfs_fs_info *fs_info, u64 qgroupid)
+ struct btrfs_fs_info *fs_info, u64 qgroupid,
+ u8 type)
{
struct btrfs_root *quota_root;
struct btrfs_qgroup *qgroup;
@@ -1136,12 +1156,12 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
goto out;
}
- ret = add_qgroup_item(trans, quota_root, qgroupid);
+ ret = add_qgroup_item(trans, quota_root, qgroupid, type);
if (ret)
goto out;
spin_lock(&fs_info->qgroup_lock);
- qgroup = add_qgroup_rb(fs_info, qgroupid);
+ qgroup = add_qgroup_rb(fs_info, qgroupid, type);
spin_unlock(&fs_info->qgroup_lock);
if (IS_ERR(qgroup))
@@ -2276,7 +2296,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
/*
* create a tracking group for the subvol itself
*/
- ret = add_qgroup_item(trans, quota_root, objectid);
+ ret = add_qgroup_item(trans, quota_root, objectid, BTRFS_QGROUP_TYPE_DEFAULT);
if (ret)
goto out;
@@ -2319,7 +2339,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
spin_lock(&fs_info->qgroup_lock);
- dstgroup = add_qgroup_rb(fs_info, objectid);
+ dstgroup = add_qgroup_rb(fs_info, objectid, BTRFS_QGROUP_TYPE_DEFAULT);
if (IS_ERR(dstgroup)) {
ret = PTR_ERR(dstgroup);
goto unlock;
@@ -2351,6 +2371,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
* our counts don't go crazy, so at this point the only
* difference between the two roots should be the root node.
*/
+ dstgroup->type = srcgroup->type;
dstgroup->rfer = srcgroup->rfer;
dstgroup->rfer_cmpr = srcgroup->rfer_cmpr;
dstgroup->excl = level_size;
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 52d8b19..7bd3a90 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -20,6 +20,16 @@
#define __BTRFS_QGROUP__
/*
+ * Type for qgroup.
+ */
+#define BTRFS_QGROUP_TYPE_DATA (1 << 0)
+#define BTRFS_QGROUP_TYPE_METADATA (1 << 1)
+#define BTRFS_QGROUP_TYPE_MIXED (BTRFS_QGROUP_TYPE_DATA | \
+ BTRFS_QGROUP_TYPE_METADATA)
+
+#define BTRFS_QGROUP_TYPE_DEFAULT BTRFS_QGROUP_TYPE_MIXED
+
+/*
* A description of the operations, all of these operations only happen when we
* are adding the 1st reference for that subvolume in the case of adding space
* or on the last reference delete in the case of subtraction. The only
@@ -73,7 +83,7 @@ int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans,
int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 src, u64 dst);
int btrfs_create_qgroup(struct btrfs_trans_handle *trans,
- struct btrfs_fs_info *fs_info, u64 qgroupid);
+ struct btrfs_fs_info *fs_info, u64 qgroupid, u8 type);
int btrfs_remove_qgroup(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 qgroupid);
int btrfs_limit_qgroup(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
index bcc1c7a..4ae3b5d 100644
--- a/fs/btrfs/tests/qgroup-tests.c
+++ b/fs/btrfs/tests/qgroup-tests.c
@@ -232,7 +232,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root)
init_dummy_trans(&trans);
test_msg("Qgroup basic add\n");
- ret = btrfs_create_qgroup(NULL, fs_info, 5);
+ ret = btrfs_create_qgroup(NULL, fs_info, 5, BTRFS_QGROUP_TYPE_DEFAULT);
if (ret) {
test_msg("Couldn't create a qgroup %d\n", ret);
return ret;
@@ -301,7 +301,7 @@ static int test_multiple_refs(struct btrfs_root *root)
test_msg("Qgroup multiple refs test\n");
/* We have 5 created already from the previous test */
- ret = btrfs_create_qgroup(NULL, fs_info, 256);
+ ret = btrfs_create_qgroup(NULL, fs_info, 256, BTRFS_QGROUP_TYPE_DEFAULT);
if (ret) {
test_msg("Couldn't create a qgroup %d\n", ret);
return ret;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/4] btrfs-progs: specify qgroup type when creating subvolume
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
2015-02-10 10:24 ` [PATCH 1/4] btrfs-progs: Add type to qgroup Dongsheng Yang
2015-02-10 10:24 ` [PATCH 1/7] Btrfs: qgroup: Add type to btrfs_qgroup Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 2/7] btrfs: qgroup: apply type to the recording and accounting Dongsheng Yang
` (9 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Fan Chengniang, Dongsheng Yang
From: Fan Chengniang <fancn.fnst@cn.fujitsu.com>
add --qgroup-type option to specify qgroup type. Type
can be metadata, data or all.
Signed-off-by: Fan Chengniang <fancn.fnst@cn.fujitsu.com>
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
Documentation/btrfs-subvolume.txt | 4 ++++
cmds-subvolume.c | 50 +++++++++++++++++++++++++++++++++------
qgroup.c | 15 ++++++++++++
qgroup.h | 1 +
4 files changed, 63 insertions(+), 7 deletions(-)
diff --git a/Documentation/btrfs-subvolume.txt b/Documentation/btrfs-subvolume.txt
index fe13943..4ac8cf5 100644
--- a/Documentation/btrfs-subvolume.txt
+++ b/Documentation/btrfs-subvolume.txt
@@ -60,6 +60,10 @@ set the newly created subvolume's max reference size
+
-e <max_excl>::::
set the newly created subvolume's max exclusive size
+--qgroup-type=<type>::::
+specify the <type> of qgroup to set qgroup limit.
++
+<attr> can be one of metadata, data, mixed.
*delete* [options] <subvolume> [<subvolume>...]::
Delete the subvolume(s) from the filesystem.
diff --git a/cmds-subvolume.c b/cmds-subvolume.c
index f0e22ac..871f749 100644
--- a/cmds-subvolume.c
+++ b/cmds-subvolume.c
@@ -51,6 +51,8 @@ static const char * const cmd_subvol_create_usage[] = {
" option can be given multiple times.",
"-r <max_rfer> set the newly created subvolume's max reference size",
"-e <max_excl> set the newly created subvolume's max exclusive size",
+ "--qgroup-type=metadata,data,mixed",
+ " specify which qgroup type to set qgroup limit",
NULL
};
@@ -65,10 +67,19 @@ static int cmd_subvol_create(int argc, char **argv)
char *dst;
struct btrfs_qgroup_inherit *inherit = NULL;
DIR *dirstream = NULL;
+ __u8 qgroup_type = 0;
+ int set_qgroup_type = 0;
optind = 1;
while (1) {
- int c = getopt(argc, argv, "c:i:r:e:v");
+ int c;
+ static const struct option long_options[] = {
+ {"qgroup-type", required_argument, NULL, 'q'},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long(argc, argv, "c:i:r:e:v",
+ long_options, NULL);
if (c < 0)
break;
@@ -101,6 +112,14 @@ static int cmd_subvol_create(int argc, char **argv)
goto out;
}
break;
+ case 'q':
+ set_qgroup_type = 1;
+ res = btrfs_qgroup_set_qgroup_type(&qgroup_type, optarg);
+ if (res) {
+ retval = res;
+ goto out;
+ }
+ break;
default:
usage(cmd_subvol_create_usage);
}
@@ -143,11 +162,21 @@ static int cmd_subvol_create(int argc, char **argv)
}
printf("Create subvolume '%s/%s'\n", dstdir, newname);
- if (inherit) {
- struct btrfs_ioctl_vol_args_v2 args;
- struct btrfs_ioctl_quota_ctl_args sa;
+ if (set_qgroup_type || inherit)
printf("Set qgroup arguments:\n");
+
+ if (set_qgroup_type) {
+ if (qgroup_type != 0) {
+ printf("\tqgroup type: ");
+ if (qgroup_type & BTRFS_QGROUP_TYPE_METADATA)
+ printf("metadata ");
+ if (qgroup_type & BTRFS_QGROUP_TYPE_DATA)
+ printf("data");
+ printf("\n");
+ }
+ }
+ if (inherit) {
if (inherit->num_qgroups > 0) {
__u64 index;
__u64 qgroupid;
@@ -168,7 +197,11 @@ static int cmd_subvol_create(int argc, char **argv)
printf("\tmax exclusive: %llu\n",
inherit->lim.max_exclusive);
}
+ }
+ if (inherit || set_qgroup_type) {
+ struct btrfs_ioctl_vol_args_v2 args;
+ struct btrfs_ioctl_quota_ctl_args sa;
sa.cmd = BTRFS_QUOTA_CTL_STATUS;
res = ioctl(fddst, BTRFS_IOC_QUOTA_CTL, &sa);
if (res < 0) {
@@ -185,9 +218,12 @@ static int cmd_subvol_create(int argc, char **argv)
memset(&args, 0, sizeof(args));
strncpy_null(args.name, newname);
- args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
- args.size = qgroup_inherit_size(inherit);
- args.qgroup_inherit = inherit;
+ if (inherit != NULL) {
+ args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
+ args.size = qgroup_inherit_size(inherit);
+ args.qgroup_inherit = inherit;
+ }
+ args.qgroup_type = qgroup_type;
res = ioctl(fddst, BTRFS_IOC_SUBVOL_CREATE_V2, &args);
} else {
diff --git a/qgroup.c b/qgroup.c
index 8a7c20f..a647925 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -1483,3 +1483,18 @@ int qgroup_inherit_set_maxexcl(struct btrfs_qgroup_inherit **inherit, char *arg)
(*inherit)->lim.max_exclusive = size;
return 0;
}
+
+int btrfs_qgroup_set_qgroup_type(__u8 *qgroup_type, char *arg)
+{
+ if (strcmp(arg, "metadata") == 0)
+ *qgroup_type = BTRFS_QGROUP_TYPE_METADATA;
+ else if (strcmp(arg, "data") == 0)
+ *qgroup_type = BTRFS_QGROUP_TYPE_DATA;
+ else if (strcmp(arg, "mixed") == 0) {
+ *qgroup_type = BTRFS_QGROUP_TYPE_MIXED;
+ } else {
+ fprintf(stderr, "ERROR: Invalid qgroup type arguments given\n");
+ return -EINVAL;
+ }
+ return 0;
+}
diff --git a/qgroup.h b/qgroup.h
index 421eb42..8423fdf 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -109,6 +109,7 @@ void btrfs_qgroup_free_comparer_set(struct btrfs_qgroup_comparer_set *comp_set);
int btrfs_qgroup_setup_comparer(struct btrfs_qgroup_comparer_set **comp_set,
enum btrfs_qgroup_comp_enum comparer,
int is_descending);
+int btrfs_qgroup_set_qgroup_type(__u8 *qgroup_type, char *arg);
u64 parse_qgroupid(char *p);
int parse_limit(const char *p, unsigned long long *s);
int qgroup_inherit_size(struct btrfs_qgroup_inherit *p);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/7] btrfs: qgroup: apply type to the recording and accounting.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (2 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 2/4] btrfs-progs: specify qgroup type when creating subvolume Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 3/4] btrfs-progs:specify qgroup type when creating qgroup Dongsheng Yang
` (8 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
So far, we have a type in each qgroup and we can create
a qgroup in different type. But there is no actual differenc
in accounting action in different qgroups.
This patch makes the qgroup ignore the qgroup recording
for other type. It means qgroup in DATA type only care
about the data size in this qgroup and ignore the metadata
size accounting.
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
fs/btrfs/extent-tree.c | 48 ++++++++++++++++++++++++++-----------------
fs/btrfs/qgroup.c | 19 ++++++++++++++---
fs/btrfs/qgroup.h | 9 ++++++--
fs/btrfs/tests/qgroup-tests.c | 15 +++++++++-----
fs/btrfs/transaction.c | 11 +++++-----
5 files changed, 68 insertions(+), 34 deletions(-)
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index f59809c..2f8506e 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -82,7 +82,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
u64 root_objectid, u64 owner_objectid,
u64 owner_offset, int refs_to_drop,
struct btrfs_delayed_extent_op *extra_op,
- int no_quota);
+ int no_quota, unsigned int quota_type);
static void __run_delayed_extent_op(struct btrfs_delayed_extent_op *extent_op,
struct extent_buffer *leaf,
struct btrfs_extent_item *ei);
@@ -1970,7 +1970,8 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
u64 parent, u64 root_objectid,
u64 owner, u64 offset, int refs_to_add,
int no_quota,
- struct btrfs_delayed_extent_op *extent_op)
+ struct btrfs_delayed_extent_op *extent_op,
+ unsigned int quota_type)
{
struct btrfs_fs_info *fs_info = root->fs_info;
struct btrfs_path *path;
@@ -2012,7 +2013,8 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
btrfs_release_path(path);
ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid,
- bytenr, num_bytes, type, 0);
+ bytenr, num_bytes, type,
+ quota_type, 0);
goto out;
}
@@ -2036,7 +2038,8 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
if (!no_quota) {
ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid,
- bytenr, num_bytes, type, 0);
+ bytenr, num_bytes, type,
+ quota_type, 0);
if (ret)
goto out;
}
@@ -2090,13 +2093,15 @@ static int run_delayed_data_ref(struct btrfs_trans_handle *trans,
node->num_bytes, parent,
ref_root, ref->objectid,
ref->offset, node->ref_mod,
- node->no_quota, extent_op);
+ node->no_quota, extent_op,
+ BTRFS_QGROUP_TYPE_DATA);
} else if (node->action == BTRFS_DROP_DELAYED_REF) {
ret = __btrfs_free_extent(trans, root, node->bytenr,
node->num_bytes, parent,
ref_root, ref->objectid,
ref->offset, node->ref_mod,
- extent_op, node->no_quota);
+ extent_op, node->no_quota,
+ BTRFS_QGROUP_TYPE_DATA);
} else {
BUG();
}
@@ -2257,12 +2262,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
ret = __btrfs_inc_extent_ref(trans, root, node->bytenr,
node->num_bytes, parent, ref_root,
ref->level, 0, 1, node->no_quota,
- extent_op);
+ extent_op, BTRFS_QGROUP_TYPE_METADATA);
} else if (node->action == BTRFS_DROP_DELAYED_REF) {
ret = __btrfs_free_extent(trans, root, node->bytenr,
node->num_bytes, parent, ref_root,
ref->level, 0, 1, extent_op,
- node->no_quota);
+ node->no_quota, BTRFS_QGROUP_TYPE_METADATA);
} else {
BUG();
}
@@ -3778,7 +3783,7 @@ commit_trans:
data_sinfo->flags, bytes, 1);
return -ENOSPC;
}
- ret = btrfs_qgroup_reserve(root, write_bytes);
+ ret = btrfs_qgroup_reserve(root, write_bytes, BTRFS_QGROUP_TYPE_DATA);
if (ret)
goto out;
data_sinfo->bytes_may_use += bytes;
@@ -5013,7 +5018,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
if (root->fs_info->quota_enabled) {
/* One for parent inode, two for dir entries */
num_bytes = 3 * root->nodesize;
- ret = btrfs_qgroup_reserve(root, num_bytes);
+ ret = btrfs_qgroup_reserve(root, num_bytes, BTRFS_QGROUP_TYPE_METADATA);
if (ret)
return ret;
} else {
@@ -5033,7 +5038,7 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root,
if (ret) {
if (*qgroup_reserved)
- btrfs_qgroup_free(root, *qgroup_reserved);
+ btrfs_qgroup_free(root, *qgroup_reserved, BTRFS_QGROUP_TYPE_METADATA);
}
return ret;
@@ -5197,7 +5202,8 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
spin_unlock(&BTRFS_I(inode)->lock);
if (root->fs_info->quota_enabled) {
- ret = btrfs_qgroup_reserve(root, nr_extents * root->nodesize);
+ ret = btrfs_qgroup_reserve(root, nr_extents * root->nodesize,
+ BTRFS_QGROUP_TYPE_METADATA);
if (ret)
goto out_fail;
}
@@ -5205,7 +5211,8 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
ret = reserve_metadata_bytes(root, block_rsv, to_reserve, flush);
if (unlikely(ret)) {
if (root->fs_info->quota_enabled)
- btrfs_qgroup_free(root, nr_extents * root->nodesize);
+ btrfs_qgroup_free(root, nr_extents * root->nodesize,
+ BTRFS_QGROUP_TYPE_METADATA);
goto out_fail;
}
@@ -5851,7 +5858,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
u64 root_objectid, u64 owner_objectid,
u64 owner_offset, int refs_to_drop,
struct btrfs_delayed_extent_op *extent_op,
- int no_quota)
+ int no_quota, unsigned int quota_type)
{
struct btrfs_key key;
struct btrfs_path *path;
@@ -6121,7 +6128,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
ret = btrfs_qgroup_record_ref(trans, info, root_objectid,
bytenr, num_bytes, type,
- mod_seq);
+ quota_type, mod_seq);
}
out:
btrfs_free_path(path);
@@ -7060,7 +7067,8 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
/* Always set parent to 0 here since its exclusive anyway. */
ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid,
ins->objectid, ins->offset,
- BTRFS_QGROUP_OPER_ADD_EXCL, 0);
+ BTRFS_QGROUP_OPER_ADD_EXCL,
+ BTRFS_QGROUP_TYPE_DATA, 0);
if (ret)
return ret;
@@ -7148,7 +7156,8 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
if (!no_quota) {
ret = btrfs_qgroup_record_ref(trans, fs_info, root_objectid,
ins->objectid, num_bytes,
- BTRFS_QGROUP_OPER_ADD_EXCL, 0);
+ BTRFS_QGROUP_OPER_ADD_EXCL,
+ BTRFS_QGROUP_TYPE_METADATA, 0);
if (ret)
return ret;
}
@@ -7526,7 +7535,8 @@ static int account_leaf_items(struct btrfs_trans_handle *trans,
ret = btrfs_qgroup_record_ref(trans, root->fs_info,
root->objectid,
bytenr, num_bytes,
- BTRFS_QGROUP_OPER_SUB_SUBTREE, 0);
+ BTRFS_QGROUP_OPER_SUB_SUBTREE,
+ BTRFS_QGROUP_TYPE_METADATA, 0);
if (ret)
return ret;
}
@@ -7676,7 +7686,7 @@ walk_down:
child_bytenr,
root->nodesize,
BTRFS_QGROUP_OPER_SUB_SUBTREE,
- 0);
+ BTRFS_QGROUP_TYPE_METADATA, 0);
if (ret)
goto out;
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 8ac785a..2fa8497 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1376,7 +1376,8 @@ static int insert_qgroup_oper(struct btrfs_fs_info *fs_info,
int btrfs_qgroup_record_ref(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 ref_root,
u64 bytenr, u64 num_bytes,
- enum btrfs_qgroup_operation_type type, int mod_seq)
+ enum btrfs_qgroup_operation_type type,
+ unsigned int quota_type, int mod_seq)
{
struct btrfs_qgroup_operation *oper;
int ret;
@@ -1392,6 +1393,7 @@ int btrfs_qgroup_record_ref(struct btrfs_trans_handle *trans,
oper->bytenr = bytenr;
oper->num_bytes = num_bytes;
oper->type = type;
+ oper->quota_type = quota_type;
oper->seq = atomic_inc_return(&fs_info->qgroup_op_seq);
INIT_LIST_HEAD(&oper->elem.list);
oper->elem.seq = 0;
@@ -1455,6 +1457,8 @@ static int qgroup_excl_accounting(struct btrfs_fs_info *fs_info,
qgroup = find_qgroup_rb(fs_info, oper->ref_root);
if (!qgroup)
goto out;
+ if (!(qgroup->type & oper->quota_type))
+ goto out;
switch (oper->type) {
case BTRFS_QGROUP_OPER_ADD_EXCL:
sign = 1;
@@ -1943,6 +1947,8 @@ static int qgroup_shared_accounting(struct btrfs_trans_handle *trans,
qgroup = find_qgroup_rb(fs_info, oper->ref_root);
if (!qgroup)
goto out;
+ if (!(qgroup->type & oper->quota_type))
+ goto out;
seq = fs_info->qgroup_seq;
/*
@@ -2069,6 +2075,8 @@ static int qgroup_subtree_accounting(struct btrfs_trans_handle *trans,
qg = find_qgroup_rb(fs_info, root_obj);
if (!qg)
goto out_unlock;
+ if (!(qg->type & oper->quota_type))
+ goto out_unlock;
qg->excl += oper->num_bytes;
qg->excl_cmpr += oper->num_bytes;
@@ -2442,7 +2450,7 @@ out:
return ret;
}
-int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
+int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes, u8 type)
{
struct btrfs_root *quota_root;
struct btrfs_qgroup *qgroup;
@@ -2467,6 +2475,8 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
if (!qgroup)
goto out;
+ if (!(qgroup->type & type))
+ goto out;
/*
* in a first step, we check all affected qgroups if any limits would
* be exceeded
@@ -2523,7 +2533,7 @@ out:
return ret;
}
-void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)
+void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes, u8 type)
{
struct btrfs_root *quota_root;
struct btrfs_qgroup *qgroup;
@@ -2549,6 +2559,9 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)
if (!qgroup)
goto out;
+ if (!(qgroup->type & type))
+ goto out;
+
ulist_reinit(fs_info->qgroup_ulist);
ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
(uintptr_t)qgroup, GFP_ATOMIC);
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 7bd3a90..75d0bb6 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -63,6 +63,10 @@ struct btrfs_qgroup_operation {
u64 num_bytes;
u64 seq;
enum btrfs_qgroup_operation_type type;
+ /*
+ * DATA or METADATA;
+ **/
+ unsigned int quota_type;
struct seq_list elem;
struct rb_node n;
struct list_head list;
@@ -96,6 +100,7 @@ int btrfs_qgroup_record_ref(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 ref_root,
u64 bytenr, u64 num_bytes,
enum btrfs_qgroup_operation_type type,
+ unsigned int quota_type,
int mod_seq);
int btrfs_delayed_qgroup_accounting(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info);
@@ -107,8 +112,8 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans,
int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid,
struct btrfs_qgroup_inherit *inherit);
-int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes);
-void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes);
+int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes, u8 type);
+void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes, u8 type);
void assert_qgroups_uptodate(struct btrfs_trans_handle *trans);
diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c
index 4ae3b5d..9c2f884 100644
--- a/fs/btrfs/tests/qgroup-tests.c
+++ b/fs/btrfs/tests/qgroup-tests.c
@@ -239,7 +239,8 @@ static int test_no_shared_qgroup(struct btrfs_root *root)
}
ret = btrfs_qgroup_record_ref(&trans, fs_info, 5, 4096, 4096,
- BTRFS_QGROUP_OPER_ADD_EXCL, 0);
+ BTRFS_QGROUP_OPER_ADD_EXCL,
+ BTRFS_QGROUP_TYPE_DEFAULT, 0);
if (ret) {
test_msg("Couldn't add space to a qgroup %d\n", ret);
return ret;
@@ -265,7 +266,8 @@ static int test_no_shared_qgroup(struct btrfs_root *root)
return -EINVAL;
ret = btrfs_qgroup_record_ref(&trans, fs_info, 5, 4096, 4096,
- BTRFS_QGROUP_OPER_SUB_EXCL, 0);
+ BTRFS_QGROUP_OPER_SUB_EXCL,
+ BTRFS_QGROUP_TYPE_DEFAULT, 0);
if (ret) {
test_msg("Couldn't remove space from the qgroup %d\n", ret);
return -EINVAL;
@@ -312,7 +314,8 @@ static int test_multiple_refs(struct btrfs_root *root)
return ret;
ret = btrfs_qgroup_record_ref(&trans, fs_info, 5, 4096, 4096,
- BTRFS_QGROUP_OPER_ADD_EXCL, 0);
+ BTRFS_QGROUP_OPER_ADD_EXCL,
+ BTRFS_QGROUP_TYPE_DEFAULT, 0);
if (ret) {
test_msg("Couldn't add space to a qgroup %d\n", ret);
return ret;
@@ -334,7 +337,8 @@ static int test_multiple_refs(struct btrfs_root *root)
return ret;
ret = btrfs_qgroup_record_ref(&trans, fs_info, 256, 4096, 4096,
- BTRFS_QGROUP_OPER_ADD_SHARED, 0);
+ BTRFS_QGROUP_OPER_ADD_SHARED,
+ BTRFS_QGROUP_TYPE_DEFAULT, 0);
if (ret) {
test_msg("Qgroup record ref failed %d\n", ret);
return ret;
@@ -361,7 +365,8 @@ static int test_multiple_refs(struct btrfs_root *root)
return ret;
ret = btrfs_qgroup_record_ref(&trans, fs_info, 256, 4096, 4096,
- BTRFS_QGROUP_OPER_SUB_SHARED, 0);
+ BTRFS_QGROUP_OPER_SUB_SHARED,
+ BTRFS_QGROUP_TYPE_DEFAULT, 0);
if (ret) {
test_msg("Qgroup record ref failed %d\n", ret);
return ret;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index a605d4e..358f3ab 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -437,7 +437,8 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type,
if (root->fs_info->quota_enabled &&
is_fstree(root->root_key.objectid)) {
qgroup_reserved = num_items * root->nodesize;
- ret = btrfs_qgroup_reserve(root, qgroup_reserved);
+ ret = btrfs_qgroup_reserve(root, qgroup_reserved,
+ BTRFS_QGROUP_TYPE_METADATA);
if (ret)
return ERR_PTR(ret);
}
@@ -552,7 +553,7 @@ alloc_fail:
num_bytes);
reserve_fail:
if (qgroup_reserved)
- btrfs_qgroup_free(root, qgroup_reserved);
+ btrfs_qgroup_free(root, qgroup_reserved, BTRFS_QGROUP_TYPE_METADATA);
return ERR_PTR(ret);
}
@@ -774,7 +775,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
* the same root has to be passed here between start_transaction
* and end_transaction. Subvolume quota depends on this.
*/
- btrfs_qgroup_free(trans->root, trans->qgroup_reserved);
+ btrfs_qgroup_free(trans->root, trans->qgroup_reserved, BTRFS_QGROUP_TYPE_METADATA);
trans->qgroup_reserved = 0;
}
@@ -1772,7 +1773,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
btrfs_trans_release_metadata(trans, root);
trans->block_rsv = NULL;
if (trans->qgroup_reserved) {
- btrfs_qgroup_free(root, trans->qgroup_reserved);
+ btrfs_qgroup_free(root, trans->qgroup_reserved, BTRFS_QGROUP_TYPE_METADATA);
trans->qgroup_reserved = 0;
}
@@ -2064,7 +2065,7 @@ cleanup_transaction:
btrfs_trans_release_metadata(trans, root);
trans->block_rsv = NULL;
if (trans->qgroup_reserved) {
- btrfs_qgroup_free(root, trans->qgroup_reserved);
+ btrfs_qgroup_free(root, trans->qgroup_reserved, BTRFS_QGROUP_TYPE_METADATA);
trans->qgroup_reserved = 0;
}
btrfs_warn(root->fs_info, "Skipping commit of aborted transaction.");
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/4] btrfs-progs:specify qgroup type when creating qgroup
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (3 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 2/7] btrfs: qgroup: apply type to the recording and accounting Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 3/7] btrfs: qgroup: Apply type to btrfs_qgroup_inherit() Dongsheng Yang
` (7 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Fan Chengniang, Dongsheng Yang
From: Fan Chengniang <fancn.fnst@cn.fujitsu.com>
add --qgroup-type option to specify qgroup type. Type
can be metadata, data or mixed.
Signed-off-by: Fan Chengniang <fancn.fnst@cn.fujitsu.com>
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
Documentation/btrfs-qgroup.txt | 5 +++++
cmds-qgroup.c | 37 ++++++++++++++++++++++++++++++++++---
2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/Documentation/btrfs-qgroup.txt b/Documentation/btrfs-qgroup.txt
index eadfe1c..7b07e97 100644
--- a/Documentation/btrfs-qgroup.txt
+++ b/Documentation/btrfs-qgroup.txt
@@ -45,6 +45,11 @@ Create a subvolume quota group.
+
For the '0/<subvolume id>' qgroup, a qgroup can be created even before the
subvolume created.
++
+--qgroup-type=<type>::::
+specify the <type> of qgroup to set qgroup limit.
++
+<attr> can be one of metadata, data, mixed.
*destroy* <qgroupid> <path>::
Destroy a qgroup.
diff --git a/cmds-qgroup.c b/cmds-qgroup.c
index 30f0851..23accdf 100644
--- a/cmds-qgroup.c
+++ b/cmds-qgroup.c
@@ -78,16 +78,45 @@ static int qgroup_create(int create, int argc, char **argv)
int ret = 0;
int fd;
int e;
- char *path = argv[2];
+ char *path = argv[argc - 1];
struct btrfs_ioctl_qgroup_create_args args;
DIR *dirstream = NULL;
+ __u8 qgroup_type = 0;
+ __u64 create_type;
- if (check_argc_exact(argc, 3))
+ optind = 1;
+ while (1) {
+ int c;
+ static const struct option long_options[] = {
+ {"qgroup-type", required_argument, NULL, 'q'},
+ {NULL, 0, NULL, 0}
+ };
+
+ c = getopt_long(argc, argv, "", long_options, NULL);
+ if (c < 0)
+ break;
+
+ switch (c) {
+ case 'q':
+ ret = btrfs_qgroup_set_qgroup_type(&qgroup_type, optarg);
+ if (ret)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ }
+
+ if (check_argc_exact(argc - optind, 2))
return -1;
memset(&args, 0, sizeof(args));
args.create = create;
- args.qgroupid = parse_qgroupid(argv[1]);
+ if (create && qgroup_type) {
+ create_type = qgroup_type;
+ args.create |= (create_type << BTRFS_QGROUP_TYPE_SHIFT);
+ }
+ args.qgroupid = parse_qgroupid(argv[argc - 2]);
fd = open_file_or_dir(path, &dirstream);
if (fd < 0) {
@@ -137,6 +166,8 @@ static int cmd_qgroup_remove(int argc, char **argv)
static const char * const cmd_qgroup_create_usage[] = {
"btrfs qgroup create <qgroupid> <path>",
"Create a subvolume quota group.",
+ "--qgroup-type=metadata,data,mixed",
+ " specify which qgroup type to set qgroup limit",
NULL
};
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/7] btrfs: qgroup: Apply type to btrfs_qgroup_inherit().
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (4 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 3/4] btrfs-progs:specify qgroup type when creating qgroup Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 4/4] btrfs-progs:show qgroup type Dongsheng Yang
` (6 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
Now, we have a type in each qgroup, then when we do a inherit(),
we need to consider the type of qgroup to decide account metadata
or not.
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
fs/btrfs/qgroup.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 2fa8497..0129dae 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2382,10 +2382,20 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
dstgroup->type = srcgroup->type;
dstgroup->rfer = srcgroup->rfer;
dstgroup->rfer_cmpr = srcgroup->rfer_cmpr;
- dstgroup->excl = level_size;
- dstgroup->excl_cmpr = level_size;
- srcgroup->excl = level_size;
- srcgroup->excl_cmpr = level_size;
+ if (dstgroup->type & BTRFS_QGROUP_TYPE_METADATA) {
+ dstgroup->excl = level_size;
+ dstgroup->excl_cmpr = level_size;
+ } else {
+ dstgroup->excl = 0;
+ dstgroup->excl_cmpr = 0;
+ }
+ if (srcgroup->type & BTRFS_QGROUP_TYPE_METADATA) {
+ srcgroup->excl = level_size;
+ srcgroup->excl_cmpr = level_size;
+ } else {
+ srcgroup->excl = 0;
+ srcgroup->excl_cmpr = 0;
+ }
/* inherit the limit info */
dstgroup->lim_flags = srcgroup->lim_flags;
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/4] btrfs-progs:show qgroup type
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (5 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 3/7] btrfs: qgroup: Apply type to btrfs_qgroup_inherit() Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 4/7] btrfs: qgroup: Apply qgroup type to qgroup creating Dongsheng Yang
` (5 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Fan Chengniang
From: Fan Chengniang <fancn.fnst@cn.fujitsu.com>
make 'btrfs qgroup show' command show qgroup type.
Signed-off-by: Fan Chengniang <fancn.fnst@cn.fujitsu.com>
---
qgroup.c | 42 +++++++++++++++++++++++++++++++++++++++---
qgroup.h | 1 +
2 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/qgroup.c b/qgroup.c
index a647925..d359659 100644
--- a/qgroup.c
+++ b/qgroup.c
@@ -135,6 +135,13 @@ static struct {
.max_len = 5,
},
{
+ .name = "type",
+ .column_name = "Type",
+ .need_print = 1,
+ .unit_mode = 0,
+ .max_len = 8,
+ },
+ {
.name = NULL,
.column_name = NULL,
.need_print = 0,
@@ -201,6 +208,20 @@ static int print_child_column(struct btrfs_qgroup *qgroup)
return len;
}
+static int print_type_column(struct btrfs_qgroup *qgroup)
+{
+ __u8 type = qgroup->type;
+ int len = 0;
+
+ if (type == BTRFS_QGROUP_TYPE_DATA)
+ len = printf("data");
+ if (type == BTRFS_QGROUP_TYPE_METADATA)
+ len = printf("metadata");
+ if (type == BTRFS_QGROUP_TYPE_MIXED)
+ len = printf("metadata,data");
+ return len;
+}
+
static void print_qgroup_column_add_blank(enum btrfs_qgroup_column_enum column,
int len)
{
@@ -244,6 +265,10 @@ static void print_qgroup_column(struct btrfs_qgroup *qgroup,
len = print_child_column(qgroup);
print_qgroup_column_add_blank(BTRFS_QGROUP_CHILD, len);
break;
+ case BTRFS_QGROUP_TYPE:
+ len = print_type_column(qgroup);
+ print_qgroup_column_add_blank(BTRFS_QGROUP_TYPE, len);
+ break;
default:
break;
}
@@ -258,7 +283,7 @@ static void print_single_qgroup_table(struct btrfs_qgroup *qgroup)
continue;
print_qgroup_column(qgroup, i);
- if (i != BTRFS_QGROUP_CHILD)
+ if (i != BTRFS_QGROUP_ALL - 1)
printf(" ");
}
printf("\n");
@@ -275,7 +300,7 @@ static void print_table_head()
if (!btrfs_qgroup_columns[i].need_print)
continue;
if ((i == BTRFS_QGROUP_QGROUPID) | (i == BTRFS_QGROUP_PARENT) |
- (i == BTRFS_QGROUP_CHILD))
+ (i == BTRFS_QGROUP_CHILD) | (i == BTRFS_QGROUP_TYPE))
printf("%-*s", max_len, btrfs_qgroup_columns[i].name);
else
printf("%*s", max_len, btrfs_qgroup_columns[i].name);
@@ -287,7 +312,7 @@ static void print_table_head()
if (!btrfs_qgroup_columns[i].need_print)
continue;
if ((i == BTRFS_QGROUP_QGROUPID) | (i == BTRFS_QGROUP_PARENT) |
- (i == BTRFS_QGROUP_CHILD)) {
+ (i == BTRFS_QGROUP_CHILD) | (i == BTRFS_QGROUP_TYPE)) {
len = strlen(btrfs_qgroup_columns[i].name);
while (len--)
printf("-");
@@ -976,6 +1001,17 @@ static void __update_columns_max_len(struct btrfs_qgroup *bq,
if (btrfs_qgroup_columns[column].max_len < len)
btrfs_qgroup_columns[column].max_len = len;
break;
+ case BTRFS_QGROUP_TYPE:
+ len = 0;
+ if (bq->type == BTRFS_QGROUP_TYPE_DATA)
+ len = strlen("data");
+ if (bq->type == BTRFS_QGROUP_TYPE_METADATA)
+ len = strlen("metadata");
+ if (bq->type == BTRFS_QGROUP_TYPE_MIXED)
+ len = strlen("metadata,data");
+ if (btrfs_qgroup_columns[column].max_len < len)
+ btrfs_qgroup_columns[column].max_len = len;
+ break;
default:
break;
}
diff --git a/qgroup.h b/qgroup.h
index 8423fdf..cc61477 100644
--- a/qgroup.h
+++ b/qgroup.h
@@ -75,6 +75,7 @@ enum btrfs_qgroup_column_enum {
BTRFS_QGROUP_MAX_EXCL,
BTRFS_QGROUP_PARENT,
BTRFS_QGROUP_CHILD,
+ BTRFS_QGROUP_TYPE,
BTRFS_QGROUP_ALL,
};
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/7] btrfs: qgroup: Apply qgroup type to qgroup creating.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (6 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 4/4] btrfs-progs:show qgroup type Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 5/7] btrfs: qgroup: Apply qgroup type to subvol creating Dongsheng Yang
` (4 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
This patch provide a method to user to create a qgroup
in a specified type.
It use a byte of the ->create in btrfs_ioctl_qgroup_create_args
to pass the type of qgroup to kernel. Then there is a macro
named as BTRFS_QGROUP_TYPE_SHIFT to help kernel get the type
of qgroup user want to creat.
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
fs/btrfs/ioctl.c | 12 ++++++++++--
fs/btrfs/qgroup.h | 6 ++++++
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index a50f295..b1f46e8 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4675,8 +4675,16 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
/* FIXME: check if the IDs really exist */
if (sa->create) {
- ret = btrfs_create_qgroup(trans, root->fs_info, sa->qgroupid,
- BTRFS_QGROUP_TYPE_DEFAULT);
+ u8 type = (sa->create >> BTRFS_QGROUP_TYPE_SHIFT);
+ if (type) {
+ if (!btrfs_fs_incompat(root->fs_info, QGROUP_TYPE)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ } else {
+ type = BTRFS_QGROUP_TYPE_DEFAULT;
+ }
+ ret = btrfs_create_qgroup(trans, root->fs_info, sa->qgroupid, type);
} else {
ret = btrfs_remove_qgroup(trans, root->fs_info, sa->qgroupid);
}
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 75d0bb6..0be0548 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -30,6 +30,12 @@
#define BTRFS_QGROUP_TYPE_DEFAULT BTRFS_QGROUP_TYPE_MIXED
/*
+ * We are using the first byte in ->create of btrfs_ioctl_qgroup_create_args
+ * to specify the type of the qgroup to be created.
+ */
+#define BTRFS_QGROUP_TYPE_SHIFT 56
+
+/*
* A description of the operations, all of these operations only happen when we
* are adding the 1st reference for that subvolume in the case of adding space
* or on the last reference delete in the case of subtraction. The only
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 5/7] btrfs: qgroup: Apply qgroup type to subvol creating.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (7 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 4/7] btrfs: qgroup: Apply qgroup type to qgroup creating Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 6/7] btrfs: qgroup: apply type to quota rescan Dongsheng Yang
` (3 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
Although we have a type in each qgroup, the all qgroups
are created in a default mode. This patch provide a
method to user to specify the type of qgroup for a sub volume.
It uses an unused byte in btrfs_ioctl_vol_args_v2 to pass
a qgroup type from userspace to kernel. Then kernel can
create a qgroup with requested type to the subvolume.
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
fs/btrfs/ioctl.c | 38 ++++++++++++++++++++++++++++----------
fs/btrfs/qgroup.c | 9 ++++++---
fs/btrfs/qgroup.h | 2 +-
fs/btrfs/transaction.c | 2 +-
include/uapi/linux/btrfs.h | 1 +
5 files changed, 37 insertions(+), 15 deletions(-)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index b1f46e8..a6d83c4 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -432,7 +432,8 @@ static noinline int create_subvol(struct inode *dir,
struct dentry *dentry,
char *name, int namelen,
u64 *async_transid,
- struct btrfs_qgroup_inherit *inherit)
+ struct btrfs_qgroup_inherit *inherit,
+ u8 qgroup_type)
{
struct btrfs_trans_handle *trans;
struct btrfs_key key;
@@ -476,7 +477,7 @@ static noinline int create_subvol(struct inode *dir,
trans->block_rsv = &block_rsv;
trans->bytes_reserved = block_rsv.size;
- ret = btrfs_qgroup_inherit(trans, root->fs_info, 0, objectid, inherit);
+ ret = btrfs_qgroup_inherit(trans, root->fs_info, 0, objectid, inherit, qgroup_type);
if (ret)
goto fail;
@@ -808,7 +809,8 @@ static noinline int btrfs_mksubvol(struct path *parent,
char *name, int namelen,
struct btrfs_root *snap_src,
u64 *async_transid, bool readonly,
- struct btrfs_qgroup_inherit *inherit)
+ struct btrfs_qgroup_inherit *inherit,
+ u8 qgroup_type)
{
struct inode *dir = parent->dentry->d_inode;
struct dentry *dentry;
@@ -851,7 +853,7 @@ static noinline int btrfs_mksubvol(struct path *parent,
async_transid, readonly, inherit);
} else {
error = create_subvol(dir, dentry, name, namelen,
- async_transid, inherit);
+ async_transid, inherit, qgroup_type);
}
if (!error)
fsnotify_mkdir(dir, dentry);
@@ -1594,7 +1596,8 @@ out:
static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
char *name, unsigned long fd, int subvol,
u64 *transid, bool readonly,
- struct btrfs_qgroup_inherit *inherit)
+ struct btrfs_qgroup_inherit *inherit,
+ u8 qgroup_type)
{
int namelen;
int ret = 0;
@@ -1617,7 +1620,8 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
if (subvol) {
ret = btrfs_mksubvol(&file->f_path, name, namelen,
- NULL, transid, readonly, inherit);
+ NULL, transid, readonly, inherit,
+ qgroup_type);
} else {
struct fd src = fdget(fd);
struct inode *src_inode;
@@ -1640,7 +1644,8 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
} else {
ret = btrfs_mksubvol(&file->f_path, name, namelen,
BTRFS_I(src_inode)->root,
- transid, readonly, inherit);
+ transid, readonly, inherit,
+ qgroup_type);
}
fdput(src);
}
@@ -1663,7 +1668,8 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
ret = btrfs_ioctl_snap_create_transid(file, vol_args->name,
vol_args->fd, subvol,
- NULL, false, NULL);
+ NULL, false, NULL,
+ BTRFS_QGROUP_TYPE_DEFAULT);
kfree(vol_args);
return ret;
@@ -1673,11 +1679,13 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
void __user *arg, int subvol)
{
struct btrfs_ioctl_vol_args_v2 *vol_args;
+ struct btrfs_root *root = BTRFS_I(file_inode(file))->root;
int ret;
u64 transid = 0;
u64 *ptr = NULL;
bool readonly = false;
struct btrfs_qgroup_inherit *inherit = NULL;
+ u8 qgroup_type = 0;
vol_args = memdup_user(arg, sizeof(*vol_args));
if (IS_ERR(vol_args))
@@ -1707,9 +1715,19 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
}
}
+ qgroup_type = vol_args->qgroup_type;
+ if (qgroup_type) {
+ if (!btrfs_fs_incompat(root->fs_info, QGROUP_TYPE)) {
+ ret = -EINVAL;
+ goto free_args;
+ }
+ } else {
+ qgroup_type = BTRFS_QGROUP_TYPE_DEFAULT;
+ }
+
ret = btrfs_ioctl_snap_create_transid(file, vol_args->name,
vol_args->fd, subvol, ptr,
- readonly, inherit);
+ readonly, inherit, qgroup_type);
if (ret)
goto free_inherit;
@@ -4674,7 +4692,7 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
}
/* FIXME: check if the IDs really exist */
- if (sa->create) {
+ if (sa->create & 0x1) {
u8 type = (sa->create >> BTRFS_QGROUP_TYPE_SHIFT);
if (type) {
if (!btrfs_fs_incompat(root->fs_info, QGROUP_TYPE)) {
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 0129dae..ba1997f 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -2262,7 +2262,7 @@ out:
*/
int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid,
- struct btrfs_qgroup_inherit *inherit)
+ struct btrfs_qgroup_inherit *inherit, u8 type)
{
int ret = 0;
int i;
@@ -2273,6 +2273,9 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
u32 level_size = 0;
u64 nums;
+ if (!type)
+ type = BTRFS_QGROUP_TYPE_DEFAULT;
+
mutex_lock(&fs_info->qgroup_ioctl_lock);
if (!fs_info->quota_enabled)
goto out;
@@ -2304,7 +2307,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
/*
* create a tracking group for the subvol itself
*/
- ret = add_qgroup_item(trans, quota_root, objectid, BTRFS_QGROUP_TYPE_DEFAULT);
+ ret = add_qgroup_item(trans, quota_root, objectid, type);
if (ret)
goto out;
@@ -2347,7 +2350,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
spin_lock(&fs_info->qgroup_lock);
- dstgroup = add_qgroup_rb(fs_info, objectid, BTRFS_QGROUP_TYPE_DEFAULT);
+ dstgroup = add_qgroup_rb(fs_info, objectid, type);
if (IS_ERR(dstgroup)) {
ret = PTR_ERR(dstgroup);
goto unlock;
diff --git a/fs/btrfs/qgroup.h b/fs/btrfs/qgroup.h
index 0be0548..52cfdc2 100644
--- a/fs/btrfs/qgroup.h
+++ b/fs/btrfs/qgroup.h
@@ -117,7 +117,7 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info);
int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info, u64 srcid, u64 objectid,
- struct btrfs_qgroup_inherit *inherit);
+ struct btrfs_qgroup_inherit *inherit, u8 type);
int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes, u8 type);
void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes, u8 type);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 358f3ab..dfe2201 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1388,7 +1388,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
ret = btrfs_qgroup_inherit(trans, fs_info,
root->root_key.objectid,
- objectid, pending->inherit);
+ objectid, pending->inherit, 0);
if (ret) {
btrfs_abort_transaction(trans, root, ret);
goto fail;
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index d4014e6..cb7a882 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -73,6 +73,7 @@ struct btrfs_ioctl_vol_args_v2 {
struct {
__u64 size;
struct btrfs_qgroup_inherit __user *qgroup_inherit;
+ __u8 qgroup_type;
};
__u64 unused[4];
};
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 6/7] btrfs: qgroup: apply type to quota rescan.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (8 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 5/7] btrfs: qgroup: Apply qgroup type to subvol creating Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-02-10 10:24 ` [PATCH 7/7] btrfs: qgroup: fix a bug when type of parent is different with child's Dongsheng Yang
` (2 subsequent siblings)
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
Although we have different type for each qgroup now,
but the rescan is also working as before which is considering
data and metadata both.
This patch fix this problem.
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
fs/btrfs/qgroup.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index ba1997f..d4ad565 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1759,7 +1759,8 @@ static int qgroup_calc_new_refcnt(struct btrfs_fs_info *fs_info,
static int qgroup_adjust_counters(struct btrfs_fs_info *fs_info,
u64 root_to_skip, u64 num_bytes,
struct ulist *qgroups, u64 seq,
- int old_roots, int new_roots, int rescan)
+ int old_roots, int new_roots, int rescan,
+ u8 qgroup_type)
{
struct ulist_node *unode;
struct ulist_iterator uiter;
@@ -1771,6 +1772,9 @@ static int qgroup_adjust_counters(struct btrfs_fs_info *fs_info,
bool dirty = false;
qg = u64_to_ptr(unode->aux);
+
+ if (!(qg->type & qgroup_type))
+ continue;
/*
* Wasn't referenced before but is now, add to the reference
* counters.
@@ -2007,7 +2011,7 @@ static int qgroup_shared_accounting(struct btrfs_trans_handle *trans,
* solution for this.
*/
qgroup_adjust_counters(fs_info, oper->ref_root, oper->num_bytes,
- qgroups, seq, old_roots, new_roots, 0);
+ qgroups, seq, old_roots, new_roots, 0, oper->quota_type);
out:
spin_unlock(&fs_info->qgroup_lock);
ulist_free(qgroups);
@@ -2670,14 +2674,19 @@ qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
mutex_unlock(&fs_info->qgroup_rescan_lock);
for (; slot < btrfs_header_nritems(scratch_leaf); ++slot) {
+ u8 type;
+
btrfs_item_key_to_cpu(scratch_leaf, &found, slot);
if (found.type != BTRFS_EXTENT_ITEM_KEY &&
found.type != BTRFS_METADATA_ITEM_KEY)
continue;
- if (found.type == BTRFS_METADATA_ITEM_KEY)
+ if (found.type == BTRFS_METADATA_ITEM_KEY) {
num_bytes = fs_info->extent_root->nodesize;
- else
+ type = BTRFS_QGROUP_TYPE_METADATA;
+ } else {
num_bytes = found.offset;
+ type = BTRFS_QGROUP_TYPE_DATA;
+ }
ulist_reinit(qgroups);
ret = btrfs_find_all_roots(NULL, fs_info, found.objectid, 0,
@@ -2698,7 +2707,7 @@ qgroup_rescan_leaf(struct btrfs_fs_info *fs_info, struct btrfs_path *path,
}
ret = qgroup_adjust_counters(fs_info, 0, num_bytes, qgroups,
- seq, 0, new_roots, 1);
+ seq, 0, new_roots, 1, type);
if (ret < 0) {
spin_unlock(&fs_info->qgroup_lock);
ulist_free(roots);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 7/7] btrfs: qgroup: fix a bug when type of parent is different with child's.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (9 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 6/7] btrfs: qgroup: apply type to quota rescan Dongsheng Yang
@ 2015-02-10 10:24 ` Dongsheng Yang
2015-03-04 1:49 ` [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
2015-03-17 10:08 ` Dongsheng Yang
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-02-10 10:24 UTC (permalink / raw)
To: linux-btrfs; +Cc: Dongsheng Yang
When the type of a record is not considered, we currently ignore it at all.
But this operation may be considered by his parent.
This patch fix this problem, it record the operation and only accounting it
when current type cover the operation type in iteration.
Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
fs/btrfs/qgroup.c | 100 +++++++++++++++++++++++++++++-------------------------
1 file changed, 54 insertions(+), 46 deletions(-)
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index d4ad565..103a908 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1457,8 +1457,6 @@ static int qgroup_excl_accounting(struct btrfs_fs_info *fs_info,
qgroup = find_qgroup_rb(fs_info, oper->ref_root);
if (!qgroup)
goto out;
- if (!(qgroup->type & oper->quota_type))
- goto out;
switch (oper->type) {
case BTRFS_QGROUP_OPER_ADD_EXCL:
sign = 1;
@@ -1469,16 +1467,19 @@ static int qgroup_excl_accounting(struct btrfs_fs_info *fs_info,
default:
ASSERT(0);
}
- qgroup->rfer += sign * oper->num_bytes;
- qgroup->rfer_cmpr += sign * oper->num_bytes;
- WARN_ON(sign < 0 && qgroup->excl < oper->num_bytes);
- qgroup->excl += sign * oper->num_bytes;
- qgroup->excl_cmpr += sign * oper->num_bytes;
- if (sign > 0)
- qgroup->reserved -= oper->num_bytes;
+ if ((qgroup->type & oper->quota_type)) {
+ qgroup->rfer += sign * oper->num_bytes;
+ qgroup->rfer_cmpr += sign * oper->num_bytes;
+
+ WARN_ON(sign < 0 && qgroup->excl < oper->num_bytes);
+ qgroup->excl += sign * oper->num_bytes;
+ qgroup->excl_cmpr += sign * oper->num_bytes;
+ if (sign > 0)
+ qgroup->reserved -= oper->num_bytes;
- qgroup_dirty(fs_info, qgroup);
+ qgroup_dirty(fs_info, qgroup);
+ }
/* Get all of the parent groups that contain this qgroup */
list_for_each_entry(glist, &qgroup->groups, next_group) {
@@ -1492,14 +1493,18 @@ static int qgroup_excl_accounting(struct btrfs_fs_info *fs_info,
ULIST_ITER_INIT(&uiter);
while ((unode = ulist_next(tmp, &uiter))) {
qgroup = u64_to_ptr(unode->aux);
- qgroup->rfer += sign * oper->num_bytes;
- qgroup->rfer_cmpr += sign * oper->num_bytes;
- WARN_ON(sign < 0 && qgroup->excl < oper->num_bytes);
- qgroup->excl += sign * oper->num_bytes;
- if (sign > 0)
- qgroup->reserved -= oper->num_bytes;
- qgroup->excl_cmpr += sign * oper->num_bytes;
- qgroup_dirty(fs_info, qgroup);
+
+ if ((qgroup->type & oper->quota_type)) {
+ qgroup->rfer += sign * oper->num_bytes;
+ qgroup->rfer_cmpr += sign * oper->num_bytes;
+ WARN_ON(sign < 0 && qgroup->excl < oper->num_bytes);
+ qgroup->excl += sign * oper->num_bytes;
+ if (sign > 0)
+ qgroup->reserved -= oper->num_bytes;
+ qgroup->excl_cmpr += sign * oper->num_bytes;
+ qgroup_dirty(fs_info, qgroup);
+
+ }
/* Add any parents of the parents */
list_for_each_entry(glist, &qgroup->groups, next_group) {
@@ -1951,8 +1956,7 @@ static int qgroup_shared_accounting(struct btrfs_trans_handle *trans,
qgroup = find_qgroup_rb(fs_info, oper->ref_root);
if (!qgroup)
goto out;
- if (!(qgroup->type & oper->quota_type))
- goto out;
+
seq = fs_info->qgroup_seq;
/*
@@ -2079,12 +2083,12 @@ static int qgroup_subtree_accounting(struct btrfs_trans_handle *trans,
qg = find_qgroup_rb(fs_info, root_obj);
if (!qg)
goto out_unlock;
- if (!(qg->type & oper->quota_type))
- goto out_unlock;
- qg->excl += oper->num_bytes;
- qg->excl_cmpr += oper->num_bytes;
- qgroup_dirty(fs_info, qg);
+ if ((qg->type & oper->quota_type)) {
+ qg->excl += oper->num_bytes;
+ qg->excl_cmpr += oper->num_bytes;
+ qgroup_dirty(fs_info, qg);
+ }
/*
* Adjust counts for parent groups. First we find all
@@ -2103,9 +2107,12 @@ static int qgroup_subtree_accounting(struct btrfs_trans_handle *trans,
ULIST_ITER_INIT(&uiter);
while ((unode = ulist_next(parents, &uiter))) {
qg = u64_to_ptr(unode->aux);
- qg->excl += oper->num_bytes;
- qg->excl_cmpr += oper->num_bytes;
- qgroup_dirty(fs_info, qg);
+
+ if ((qg->type & oper->quota_type)) {
+ qg->excl += oper->num_bytes;
+ qg->excl_cmpr += oper->num_bytes;
+ qgroup_dirty(fs_info, qg);
+ }
/* Add any parents of the parents */
list_for_each_entry(glist, &qg->groups, next_group) {
@@ -2492,8 +2499,6 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes, u8 type)
if (!qgroup)
goto out;
- if (!(qgroup->type & type))
- goto out;
/*
* in a first step, we check all affected qgroups if any limits would
* be exceeded
@@ -2510,18 +2515,20 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes, u8 type)
qg = u64_to_ptr(unode->aux);
- if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
- qg->reserved + (s64)qg->rfer + num_bytes >
- qg->max_rfer) {
- ret = -EDQUOT;
- goto out;
- }
+ if (qg->type & type) {
+ if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_RFER) &&
+ qg->reserved + (s64)qg->rfer + num_bytes >
+ qg->max_rfer) {
+ ret = -EDQUOT;
+ goto out;
+ }
- if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
- qg->reserved + (s64)qg->excl + num_bytes >
- qg->max_excl) {
- ret = -EDQUOT;
- goto out;
+ if ((qg->lim_flags & BTRFS_QGROUP_LIMIT_MAX_EXCL) &&
+ qg->reserved + (s64)qg->excl + num_bytes >
+ qg->max_excl) {
+ ret = -EDQUOT;
+ goto out;
+ }
}
list_for_each_entry(glist, &qg->groups, next_group) {
@@ -2542,7 +2549,9 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes, u8 type)
qg = u64_to_ptr(unode->aux);
- qg->reserved += num_bytes;
+ if (qg->type & type) {
+ qg->reserved += num_bytes;
+ }
}
out:
@@ -2576,9 +2585,6 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes, u8 type)
if (!qgroup)
goto out;
- if (!(qgroup->type & type))
- goto out;
-
ulist_reinit(fs_info->qgroup_ulist);
ret = ulist_add(fs_info->qgroup_ulist, qgroup->qgroupid,
(uintptr_t)qgroup, GFP_ATOMIC);
@@ -2591,7 +2597,9 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes, u8 type)
qg = u64_to_ptr(unode->aux);
- qg->reserved -= num_bytes;
+ if (qg->type & type) {
+ qg->reserved -= num_bytes;
+ }
list_for_each_entry(glist, &qg->groups, next_group) {
ret = ulist_add(fs_info->qgroup_ulist,
--
1.8.4.2
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (10 preceding siblings ...)
2015-02-10 10:24 ` [PATCH 7/7] btrfs: qgroup: fix a bug when type of parent is different with child's Dongsheng Yang
@ 2015-03-04 1:49 ` Dongsheng Yang
2015-03-17 10:08 ` Dongsheng Yang
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-03-04 1:49 UTC (permalink / raw)
To: Josef Bacik; +Cc: linux-btrfs
On 02/10/2015 06:24 PM, Dongsheng Yang wrote:
> Hi all,
> This patchset is based on [Btrfs: qgroup: part-3: bug fixes.]
>
> I am introducing a type to qgroup, then we can get the numbers what we
> only care about.
>
> Easy way to get the code for testing:
> btrfs: https://yangdongsheng@github.com/yangdongsheng/linux.git qgroup_type
> btrfs-progs: https://yangdongsheng@github.com/yangdongsheng/btrfs-progs.git qgroup_type
> with the patches applied in this series, both in btrfs and btrfs-progs:
Any comment on this patchset?
I think it's a good enhancement for qgroup.
Thanx
>
> [root@atest-guest linux_btrfs]# mkfs.btrfs -O qgroup-type /dev/sdc -f
> Btrfs v3.18-76-ga900a61
> See http://btrfs.wiki.kernel.org for more information.
>
> Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
> Turning ON incompat feature 'skinny-metadata': reduced-size metadata extent refs
> Turning ON incompat feature 'qgroup-type': create qgroup in different type
> fs created label (null) on /dev/sdc
> nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
> [root@atest-guest linux_btrfs]# mount /dev/sdc /mnt/
> [root@atest-guest linux_btrfs]# btrfs quota enable /mnt
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data <--- default type is mixed.
> [root@atest-guest linux_btrfs]# btrfs sub create --qgroup-type data /mnt/sub1
> Create subvolume '/mnt/sub1'
> Set qgroup arguments:
> qgroup type: data
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/258 0.00B 0.00B 0.00B 0.00B --- --- data <--- create a data qgroup
> [root@atest-guest linux_btrfs]# btrfs qgroup limit -e 5M 0/258 /mnt
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/258 0.00B 0.00B 0.00B 5.00MiB --- --- data
> [root@atest-guest linux_btrfs]# dd if=/dev/zero of=/mnt/sub1/data bs=1024
> dd: error writing \u2018/mnt/sub1/data\u2019: Disk quota exceeded
> 5121+0 records in
> 5120+0 records out
> 5242880 bytes (5.2 MB) copied, 0.0218646 s, 240 MB/s
> [root@atest-guest linux_btrfs]# sync
> [root@atest-guest linux_btrfs]# ll /mnt/sub1/data
> -rw-r--r--. 1 root root 5242880 Feb 10 16:17 /mnt/sub1/data
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce --raw /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16384 16384 0 0 --- --- metadata,data
> 0/257 16384 16384 0 0 --- --- metadata,data
> 0/258 5242880 5242880 0 5242880 --- --- data <--- excl == max_excl == data_size == 5M == 5242880
>
> Dongsheng Yang (7):
> Btrfs: qgroup: Add type to btrfs_qgroup.
> btrfs: qgroup: apply type to the recording and accounting.
> btrfs: qgroup: Apply type to btrfs_qgroup_inherit().
> btrfs: qgroup: Apply qgroup type to qgroup creating.
> btrfs: qgroup: Apply qgroup type to subvol creating.
> btrfs: qgroup: apply type to quota rescan.
> btrfs: qgroup: fix a bug when type of parent is different with
> child's.
>
> fs/btrfs/ctree.h | 10 ++-
> fs/btrfs/extent-tree.c | 48 ++++++-----
> fs/btrfs/ioctl.c | 49 ++++++++---
> fs/btrfs/qgroup.c | 186 ++++++++++++++++++++++++++++--------------
> fs/btrfs/qgroup.h | 29 ++++++-
> fs/btrfs/tests/qgroup-tests.c | 19 +++--
> fs/btrfs/transaction.c | 13 +--
> include/uapi/linux/btrfs.h | 1 +
> 8 files changed, 246 insertions(+), 109 deletions(-)
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup.
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
` (11 preceding siblings ...)
2015-03-04 1:49 ` [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
@ 2015-03-17 10:08 ` Dongsheng Yang
12 siblings, 0 replies; 14+ messages in thread
From: Dongsheng Yang @ 2015-03-17 10:08 UTC (permalink / raw)
To: linux-btrfs
Hi all,
I am cooking a V2 for this patchset, it will make user to limit
data, metadata or mixed of a qgroup.
Even, you can limit all of the three quota number at one time. I believe
it's much better.
Thanx.
On 02/10/2015 06:24 PM, Dongsheng Yang wrote:
> Hi all,
> This patchset is based on [Btrfs: qgroup: part-3: bug fixes.]
>
> I am introducing a type to qgroup, then we can get the numbers what we
> only care about.
>
> Easy way to get the code for testing:
> btrfs: https://yangdongsheng@github.com/yangdongsheng/linux.git qgroup_type
> btrfs-progs: https://yangdongsheng@github.com/yangdongsheng/btrfs-progs.git qgroup_type
> with the patches applied in this series, both in btrfs and btrfs-progs:
>
> [root@atest-guest linux_btrfs]# mkfs.btrfs -O qgroup-type /dev/sdc -f
> Btrfs v3.18-76-ga900a61
> See http://btrfs.wiki.kernel.org for more information.
>
> Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
> Turning ON incompat feature 'skinny-metadata': reduced-size metadata extent refs
> Turning ON incompat feature 'qgroup-type': create qgroup in different type
> fs created label (null) on /dev/sdc
> nodesize 16384 leafsize 16384 sectorsize 4096 size 10.00GiB
> [root@atest-guest linux_btrfs]# mount /dev/sdc /mnt/
> [root@atest-guest linux_btrfs]# btrfs quota enable /mnt
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data <--- default type is mixed.
> [root@atest-guest linux_btrfs]# btrfs sub create --qgroup-type data /mnt/sub1
> Create subvolume '/mnt/sub1'
> Set qgroup arguments:
> qgroup type: data
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/258 0.00B 0.00B 0.00B 0.00B --- --- data <--- create a data qgroup
> [root@atest-guest linux_btrfs]# btrfs qgroup limit -e 5M 0/258 /mnt
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/257 16.00KiB 16.00KiB 0.00B 0.00B --- --- metadata,data
> 0/258 0.00B 0.00B 0.00B 5.00MiB --- --- data
> [root@atest-guest linux_btrfs]# dd if=/dev/zero of=/mnt/sub1/data bs=1024
> dd: error writing \u2018/mnt/sub1/data\u2019: Disk quota exceeded
> 5121+0 records in
> 5120+0 records out
> 5242880 bytes (5.2 MB) copied, 0.0218646 s, 240 MB/s
> [root@atest-guest linux_btrfs]# sync
> [root@atest-guest linux_btrfs]# ll /mnt/sub1/data
> -rw-r--r--. 1 root root 5242880 Feb 10 16:17 /mnt/sub1/data
> [root@atest-guest linux_btrfs]# btrfs qgroup show -prce --raw /mnt
> qgroupid rfer excl max_rfer max_excl parent child type
> -------- ---- ---- -------- -------- ------ ----- ----
> 0/5 16384 16384 0 0 --- --- metadata,data
> 0/257 16384 16384 0 0 --- --- metadata,data
> 0/258 5242880 5242880 0 5242880 --- --- data <--- excl == max_excl == data_size == 5M == 5242880
>
> Dongsheng Yang (7):
> Btrfs: qgroup: Add type to btrfs_qgroup.
> btrfs: qgroup: apply type to the recording and accounting.
> btrfs: qgroup: Apply type to btrfs_qgroup_inherit().
> btrfs: qgroup: Apply qgroup type to qgroup creating.
> btrfs: qgroup: Apply qgroup type to subvol creating.
> btrfs: qgroup: apply type to quota rescan.
> btrfs: qgroup: fix a bug when type of parent is different with
> child's.
>
> fs/btrfs/ctree.h | 10 ++-
> fs/btrfs/extent-tree.c | 48 ++++++-----
> fs/btrfs/ioctl.c | 49 ++++++++---
> fs/btrfs/qgroup.c | 186 ++++++++++++++++++++++++++++--------------
> fs/btrfs/qgroup.h | 29 ++++++-
> fs/btrfs/tests/qgroup-tests.c | 19 +++--
> fs/btrfs/transaction.c | 13 +--
> include/uapi/linux/btrfs.h | 1 +
> 8 files changed, 246 insertions(+), 109 deletions(-)
>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2015-03-17 10:12 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-10 10:24 [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
2015-02-10 10:24 ` [PATCH 1/4] btrfs-progs: Add type to qgroup Dongsheng Yang
2015-02-10 10:24 ` [PATCH 1/7] Btrfs: qgroup: Add type to btrfs_qgroup Dongsheng Yang
2015-02-10 10:24 ` [PATCH 2/4] btrfs-progs: specify qgroup type when creating subvolume Dongsheng Yang
2015-02-10 10:24 ` [PATCH 2/7] btrfs: qgroup: apply type to the recording and accounting Dongsheng Yang
2015-02-10 10:24 ` [PATCH 3/4] btrfs-progs:specify qgroup type when creating qgroup Dongsheng Yang
2015-02-10 10:24 ` [PATCH 3/7] btrfs: qgroup: Apply type to btrfs_qgroup_inherit() Dongsheng Yang
2015-02-10 10:24 ` [PATCH 4/4] btrfs-progs:show qgroup type Dongsheng Yang
2015-02-10 10:24 ` [PATCH 4/7] btrfs: qgroup: Apply qgroup type to qgroup creating Dongsheng Yang
2015-02-10 10:24 ` [PATCH 5/7] btrfs: qgroup: Apply qgroup type to subvol creating Dongsheng Yang
2015-02-10 10:24 ` [PATCH 6/7] btrfs: qgroup: apply type to quota rescan Dongsheng Yang
2015-02-10 10:24 ` [PATCH 7/7] btrfs: qgroup: fix a bug when type of parent is different with child's Dongsheng Yang
2015-03-04 1:49 ` [RFC PATCH 0/7] Btrfs: qgroup: part-4: Add type to btrfs qgroup Dongsheng Yang
2015-03-17 10:08 ` Dongsheng Yang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).