2 * Copyright (C) 2012 STRATO. All rights reserved.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this program; if not, write to the
15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16 * Boston, MA 021110-1307, USA.
22 u64 parse_qgroupid(char *p)
24 char *s = strchr(p, '/');
25 char *ptr_src_end = p + strlen(p);
26 char *ptr_parse_end = NULL;
31 id = strtoull(p, &ptr_parse_end, 10);
32 if (ptr_parse_end != ptr_src_end)
36 level = strtoull(p, &ptr_parse_end, 10);
37 if (ptr_parse_end != s)
40 id = strtoull(s+1, &ptr_parse_end, 10);
41 if (ptr_parse_end != ptr_src_end)
44 return (level << 48) | id;
46 fprintf(stderr, "ERROR:invalid qgroupid\n");
50 int qgroup_inherit_size(struct btrfs_qgroup_inherit *p)
52 return sizeof(*p) + sizeof(p->qgroups[0]) *
53 (p->num_qgroups + 2 * p->num_ref_copies +
54 2 * p->num_excl_copies);
57 int qgroup_inherit_realloc(struct btrfs_qgroup_inherit **inherit, int n,
60 struct btrfs_qgroup_inherit *out;
64 nitems = (*inherit)->num_qgroups +
65 (*inherit)->num_ref_copies +
66 (*inherit)->num_excl_copies;
69 out = calloc(sizeof(*out) + sizeof(out->qgroups[0]) * (nitems + n), 1);
71 fprintf(stderr, "ERROR: Not enough memory\n");
76 struct btrfs_qgroup_inherit *i = *inherit;
77 int s = sizeof(out->qgroups);
79 out->num_qgroups = i->num_qgroups;
80 out->num_ref_copies = i->num_ref_copies;
81 out->num_excl_copies = i->num_excl_copies;
82 memcpy(out->qgroups, i->qgroups, pos * s);
83 memcpy(out->qgroups + pos + n, i->qgroups + pos,
92 int qgroup_inherit_add_group(struct btrfs_qgroup_inherit **inherit, char *arg)
95 u64 qgroupid = parse_qgroupid(arg);
99 fprintf(stderr, "ERROR: bad qgroup specification\n");
104 pos = (*inherit)->num_qgroups;
105 ret = qgroup_inherit_realloc(inherit, 1, pos);
109 (*inherit)->qgroups[(*inherit)->num_qgroups++] = qgroupid;
114 int qgroup_inherit_add_copy(struct btrfs_qgroup_inherit **inherit, char *arg,
123 p = strchr(arg, ':');
126 fprintf(stderr, "ERROR: bad copy specification\n");
130 qgroup_src = parse_qgroupid(arg);
131 qgroup_dst = parse_qgroupid(p + 1);
134 if (!qgroup_src || !qgroup_dst)
138 pos = (*inherit)->num_qgroups +
139 (*inherit)->num_ref_copies * 2 * type;
141 ret = qgroup_inherit_realloc(inherit, 2, pos);
145 (*inherit)->qgroups[pos++] = qgroup_src;
146 (*inherit)->qgroups[pos++] = qgroup_dst;
149 ++(*inherit)->num_ref_copies;
151 ++(*inherit)->num_excl_copies;