btrfs-progs: mkfs: create root directory with 755 permissions
[btrfs-progs-unstable/devel.git] / qgroup.c
blob4083b57e27760820a18cbb55ea304e9ce9a8f010
1 /*
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.
19 #include "qgroup.h"
20 #include "ctree.h"
22 u64 parse_qgroupid(char *p)
24 char *s = strchr(p, '/');
25 u64 level;
26 u64 id;
28 if (!s)
29 return atoll(p);
30 level = atoll(p);
31 id = atoll(s + 1);
33 return (level << 48) | id;
36 int qgroup_inherit_size(struct btrfs_qgroup_inherit *p)
38 return sizeof(*p) + sizeof(p->qgroups[0]) *
39 (p->num_qgroups + 2 * p->num_ref_copies +
40 2 * p->num_excl_copies);
43 int qgroup_inherit_realloc(struct btrfs_qgroup_inherit **inherit, int n,
44 int pos)
46 struct btrfs_qgroup_inherit *out;
47 int nitems = 0;
49 if (*inherit) {
50 nitems = (*inherit)->num_qgroups +
51 (*inherit)->num_ref_copies +
52 (*inherit)->num_excl_copies;
55 out = calloc(sizeof(*out) + sizeof(out->qgroups[0]) * (nitems + n), 1);
56 if (out == NULL) {
57 fprintf(stderr, "ERROR: Not enough memory\n");
58 return 13;
61 if (*inherit) {
62 struct btrfs_qgroup_inherit *i = *inherit;
63 int s = sizeof(out->qgroups);
65 out->num_qgroups = i->num_qgroups;
66 out->num_ref_copies = i->num_ref_copies;
67 out->num_excl_copies = i->num_excl_copies;
68 memcpy(out->qgroups, i->qgroups, pos * s);
69 memcpy(out->qgroups + pos + n, i->qgroups + pos,
70 (nitems - pos) * s);
72 free(*inherit);
73 *inherit = out;
75 return 0;
78 int qgroup_inherit_add_group(struct btrfs_qgroup_inherit **inherit, char *arg)
80 int ret;
81 u64 qgroupid = parse_qgroupid(arg);
82 int pos = 0;
84 if (qgroupid == 0) {
85 fprintf(stderr, "ERROR: bad qgroup specification\n");
86 return 12;
89 if (*inherit)
90 pos = (*inherit)->num_qgroups;
91 ret = qgroup_inherit_realloc(inherit, 1, pos);
92 if (ret)
93 return ret;
95 (*inherit)->qgroups[(*inherit)->num_qgroups++] = qgroupid;
97 return 0;
100 int qgroup_inherit_add_copy(struct btrfs_qgroup_inherit **inherit, char *arg,
101 int type)
103 int ret;
104 u64 qgroup_src;
105 u64 qgroup_dst;
106 char *p;
107 int pos = 0;
109 p = strchr(arg, ':');
110 if (!p) {
111 bad:
112 fprintf(stderr, "ERROR: bad copy specification\n");
113 return 12;
115 *p = 0;
116 qgroup_src = parse_qgroupid(arg);
117 qgroup_dst = parse_qgroupid(p + 1);
118 *p = ':';
120 if (!qgroup_src || !qgroup_dst)
121 goto bad;
123 if (*inherit)
124 pos = (*inherit)->num_qgroups +
125 (*inherit)->num_ref_copies * 2 * type;
127 ret = qgroup_inherit_realloc(inherit, 2, pos);
128 if (ret)
129 return ret;
131 (*inherit)->qgroups[pos++] = qgroup_src;
132 (*inherit)->qgroups[pos++] = qgroup_dst;
134 if (!type)
135 ++(*inherit)->num_ref_copies;
136 else
137 ++(*inherit)->num_excl_copies;
139 return 0;