]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/attrset.c
metadump: bounds check btree block regions being zeroed
[thirdparty/xfsprogs-dev.git] / db / attrset.c
1 /*
2 * Copyright (c) 2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "libxfs.h"
20 #include "command.h"
21 #include "attrset.h"
22 #include "io.h"
23 #include "output.h"
24 #include "type.h"
25 #include "init.h"
26 #include "fprint.h"
27 #include "faddr.h"
28 #include "field.h"
29 #include "inode.h"
30 #include "malloc.h"
31
32 static int attr_set_f(int argc, char **argv);
33 static int attr_remove_f(int argc, char **argv);
34 static void attrset_help(void);
35
36 static const cmdinfo_t attr_set_cmd =
37 { "attr_set", "aset", attr_set_f, 1, -1, 0,
38 N_("[-r|-s|-p|-u] [-n] [-R|-C] [-v n] name"),
39 N_("set the named attribute on the current inode"), attrset_help };
40 static const cmdinfo_t attr_remove_cmd =
41 { "attr_remove", "aremove", attr_remove_f, 1, -1, 0,
42 N_("[-r|-s|-p|-u] [-n] name"),
43 N_("remove the named attribute from the current inode"), attrset_help };
44
45 static void
46 attrset_help(void)
47 {
48 dbprintf(_(
49 "\n"
50 " The 'attr_set' and 'attr_remove' commands provide interfaces for debugging\n"
51 " the extended attribute allocation and removal code.\n"
52 " Both commands require an attribute name to be specified, and the attr_set\n"
53 " command allows an optional value length (-v) to be provided as well.\n"
54 " There are 4 namespace flags:\n"
55 " -r -- 'root'\n"
56 " -u -- 'user' (default)\n"
57 " -s -- 'secure'\n"
58 "\n"
59 " For attr_set, these options further define the type of set operation:\n"
60 " -C -- 'create' - create attribute, fail if it already exists\n"
61 " -R -- 'replace' - replace attribute, fail if it does not exist\n"
62 " The backward compatibility mode 'noattr2' can be emulated (-n) also.\n"
63 "\n"));
64 }
65
66 void
67 attrset_init(void)
68 {
69 if (!expert_mode)
70 return;
71
72 add_command(&attr_set_cmd);
73 add_command(&attr_remove_cmd);
74 }
75
76 static int
77 attr_set_f(
78 int argc,
79 char **argv)
80 {
81 xfs_inode_t *ip = NULL;
82 char *name, *value, *sp;
83 int c, valuelen = 0, flags = 0;
84
85 if (cur_typ == NULL) {
86 dbprintf(_("no current type\n"));
87 return 0;
88 }
89 if (cur_typ->typnm != TYP_INODE) {
90 dbprintf(_("current type is not inode\n"));
91 return 0;
92 }
93
94 while ((c = getopt(argc, argv, "rusCRnv:")) != EOF) {
95 switch (c) {
96 /* namespaces */
97 case 'r':
98 flags |= LIBXFS_ATTR_ROOT;
99 flags &= ~LIBXFS_ATTR_SECURE;
100 break;
101 case 'u':
102 flags &= ~(LIBXFS_ATTR_ROOT | LIBXFS_ATTR_SECURE);
103 break;
104 case 's':
105 flags |= LIBXFS_ATTR_SECURE;
106 flags &= ~LIBXFS_ATTR_ROOT;
107 break;
108
109 /* modifiers */
110 case 'C':
111 flags |= LIBXFS_ATTR_CREATE;
112 break;
113 case 'R':
114 flags |= LIBXFS_ATTR_REPLACE;
115 break;
116
117 case 'n':
118 mp->m_flags |= LIBXFS_MOUNT_COMPAT_ATTR;
119 break;
120
121 /* value length */
122 case 'v':
123 valuelen = (int)strtol(optarg, &sp, 0);
124 if (*sp != '\0' || valuelen < 0 || valuelen > 64*1024) {
125 dbprintf(_("bad attr_set valuelen %s\n"), optarg);
126 return 0;
127 }
128 break;
129
130 default:
131 dbprintf(_("bad option for attr_set command\n"));
132 return 0;
133 }
134 }
135
136 if (optind != argc - 1) {
137 dbprintf(_("too few options for attr_set (no name given)\n"));
138 return 0;
139 }
140
141 name = argv[optind];
142
143 if (valuelen) {
144 value = (char *)memalign(getpagesize(), valuelen);
145 if (!value) {
146 dbprintf(_("cannot allocate buffer (%d)\n"), valuelen);
147 goto out;
148 }
149 memset(value, 'v', valuelen);
150 } else {
151 value = NULL;
152 }
153
154 if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip, 0)) {
155 dbprintf(_("failed to iget inode %llu\n"),
156 (unsigned long long)iocur_top->ino);
157 goto out;
158 }
159
160 if (libxfs_attr_set(ip, (unsigned char *)name,
161 (unsigned char *)value, valuelen, flags)) {
162 dbprintf(_("failed to set attr %s on inode %llu\n"),
163 name, (unsigned long long)iocur_top->ino);
164 goto out;
165 }
166
167 /* refresh with updated inode contents */
168 set_cur_inode(iocur_top->ino);
169
170 out:
171 mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR;
172 if (ip)
173 IRELE(ip);
174 if (value)
175 free(value);
176 return 0;
177 }
178
179 static int
180 attr_remove_f(
181 int argc,
182 char **argv)
183 {
184 xfs_inode_t *ip = NULL;
185 char *name;
186 int c, flags = 0;
187
188 if (cur_typ == NULL) {
189 dbprintf(_("no current type\n"));
190 return 0;
191 }
192 if (cur_typ->typnm != TYP_INODE) {
193 dbprintf(_("current type is not inode\n"));
194 return 0;
195 }
196
197 while ((c = getopt(argc, argv, "rusn")) != EOF) {
198 switch (c) {
199 /* namespaces */
200 case 'r':
201 flags |= LIBXFS_ATTR_ROOT;
202 flags &= ~LIBXFS_ATTR_SECURE;
203 break;
204 case 'u':
205 flags &= ~(LIBXFS_ATTR_ROOT | LIBXFS_ATTR_SECURE);
206 break;
207 case 's':
208 flags |= LIBXFS_ATTR_SECURE;
209 flags &= ~LIBXFS_ATTR_ROOT;
210 break;
211
212 case 'n':
213 mp->m_flags |= LIBXFS_MOUNT_COMPAT_ATTR;
214 break;
215
216 default:
217 dbprintf(_("bad option for attr_remove command\n"));
218 return 0;
219 }
220 }
221
222 if (optind != argc - 1) {
223 dbprintf(_("too few options for attr_remove (no name given)\n"));
224 return 0;
225 }
226
227 name = argv[optind];
228
229 if (libxfs_iget(mp, NULL, iocur_top->ino, 0, &ip, 0)) {
230 dbprintf(_("failed to iget inode %llu\n"),
231 (unsigned long long)iocur_top->ino);
232 goto out;
233 }
234
235 if (libxfs_attr_remove(ip, (unsigned char *)name, flags)) {
236 dbprintf(_("failed to remove attr %s from inode %llu\n"),
237 name, (unsigned long long)iocur_top->ino);
238 goto out;
239 }
240
241 /* refresh with updated inode contents */
242 set_cur_inode(iocur_top->ino);
243
244 out:
245 mp->m_flags &= ~LIBXFS_MOUNT_COMPAT_ATTR;
246 if (ip)
247 IRELE(ip);
248 return 0;
249 }