]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/attr.c
Update copyright dates (again)
[thirdparty/xfsprogs-dev.git] / db / attr.c
1 /*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <libxfs.h>
34 #include "bit.h"
35 #include "type.h"
36 #include "faddr.h"
37 #include "fprint.h"
38 #include "field.h"
39 #include "attr.h"
40 #include "io.h"
41 #include "data.h"
42 #include "mount.h"
43
44 static int attr_leaf_entries_count(void *obj, int startoff);
45 static int attr_leaf_hdr_count(void *obj, int startoff);
46 static int attr_leaf_name_local_count(void *obj, int startoff);
47 static int attr_leaf_name_local_name_count(void *obj, int startoff);
48 static int attr_leaf_name_local_value_count(void *obj, int startoff);
49 static int attr_leaf_name_local_value_offset(void *obj, int startoff,
50 int idx);
51 static int attr_leaf_name_remote_count(void *obj, int startoff);
52 static int attr_leaf_name_remote_name_count(void *obj, int startoff);
53 static int attr_leaf_nvlist_count(void *obj, int startoff);
54 static int attr_leaf_nvlist_offset(void *obj, int startoff, int idx);
55 static int attr_node_btree_count(void *obj, int startoff);
56 static int attr_node_hdr_count(void *obj, int startoff);
57
58 const field_t attr_hfld[] = {
59 { "", FLDT_ATTR, OI(0), C1, 0, TYP_NONE },
60 { NULL }
61 };
62
63 #define LOFF(f) bitize(offsetof(xfs_attr_leafblock_t, f))
64 #define NOFF(f) bitize(offsetof(xfs_da_intnode_t, f))
65 const field_t attr_flds[] = {
66 { "hdr", FLDT_ATTR_LEAF_HDR, OI(LOFF(hdr)), attr_leaf_hdr_count,
67 FLD_COUNT, TYP_NONE },
68 { "hdr", FLDT_ATTR_NODE_HDR, OI(NOFF(hdr)), attr_node_hdr_count,
69 FLD_COUNT, TYP_NONE },
70 { "entries", FLDT_ATTR_LEAF_ENTRY, OI(LOFF(entries)),
71 attr_leaf_entries_count, FLD_ARRAY|FLD_COUNT, TYP_NONE },
72 { "btree", FLDT_ATTR_NODE_ENTRY, OI(NOFF(btree)), attr_node_btree_count,
73 FLD_ARRAY|FLD_COUNT, TYP_NONE },
74 { "nvlist", FLDT_ATTR_LEAF_NAME, attr_leaf_nvlist_offset,
75 attr_leaf_nvlist_count, FLD_ARRAY|FLD_OFFSET|FLD_COUNT, TYP_NONE },
76 { NULL }
77 };
78
79 #define BOFF(f) bitize(offsetof(xfs_da_blkinfo_t, f))
80 const field_t attr_blkinfo_flds[] = {
81 { "forw", FLDT_ATTRBLOCK, OI(BOFF(forw)), C1, 0, TYP_ATTR },
82 { "back", FLDT_ATTRBLOCK, OI(BOFF(back)), C1, 0, TYP_ATTR },
83 { "magic", FLDT_UINT16X, OI(BOFF(magic)), C1, 0, TYP_NONE },
84 { "pad", FLDT_UINT16X, OI(BOFF(pad)), C1, FLD_SKIPALL, TYP_NONE },
85 { NULL }
86 };
87
88 #define LEOFF(f) bitize(offsetof(xfs_attr_leaf_entry_t, f))
89 const field_t attr_leaf_entry_flds[] = {
90 { "hashval", FLDT_UINT32X, OI(LEOFF(hashval)), C1, 0, TYP_NONE },
91 { "nameidx", FLDT_UINT16D, OI(LEOFF(nameidx)), C1, 0, TYP_NONE },
92 { "flags", FLDT_UINT8X, OI(LEOFF(flags)), C1, FLD_SKIPALL, TYP_NONE },
93 { "incomplete", FLDT_UINT1,
94 OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_INCOMPLETE_BIT - 1), C1,
95 0, TYP_NONE },
96 { "root", FLDT_UINT1,
97 OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_ROOT_BIT - 1), C1, 0,
98 TYP_NONE },
99 { "local", FLDT_UINT1,
100 OI(LEOFF(flags) + bitsz(__uint8_t) - XFS_ATTR_LOCAL_BIT - 1), C1, 0,
101 TYP_NONE },
102 { "pad2", FLDT_UINT8X, OI(LEOFF(pad2)), C1, FLD_SKIPALL, TYP_NONE },
103 { NULL }
104 };
105
106 #define LHOFF(f) bitize(offsetof(xfs_attr_leaf_hdr_t, f))
107 const field_t attr_leaf_hdr_flds[] = {
108 { "info", FLDT_ATTR_BLKINFO, OI(LHOFF(info)), C1, 0, TYP_NONE },
109 { "count", FLDT_UINT16D, OI(LHOFF(count)), C1, 0, TYP_NONE },
110 { "usedbytes", FLDT_UINT16D, OI(LHOFF(usedbytes)), C1, 0, TYP_NONE },
111 { "firstused", FLDT_UINT16D, OI(LHOFF(firstused)), C1, 0, TYP_NONE },
112 { "holes", FLDT_UINT8D, OI(LHOFF(holes)), C1, 0, TYP_NONE },
113 { "pad1", FLDT_UINT8X, OI(LHOFF(pad1)), C1, FLD_SKIPALL, TYP_NONE },
114 { "freemap", FLDT_ATTR_LEAF_MAP, OI(LHOFF(freemap)),
115 CI(XFS_ATTR_LEAF_MAPSIZE), FLD_ARRAY, TYP_NONE },
116 { NULL }
117 };
118
119 #define LMOFF(f) bitize(offsetof(xfs_attr_leaf_map_t, f))
120 const field_t attr_leaf_map_flds[] = {
121 { "base", FLDT_UINT16D, OI(LMOFF(base)), C1, 0, TYP_NONE },
122 { "size", FLDT_UINT16D, OI(LMOFF(size)), C1, 0, TYP_NONE },
123 { NULL }
124 };
125
126 #define LNOFF(f) bitize(offsetof(xfs_attr_leaf_name_local_t, f))
127 #define LVOFF(f) bitize(offsetof(xfs_attr_leaf_name_remote_t, f))
128 const field_t attr_leaf_name_flds[] = {
129 { "valuelen", FLDT_UINT16D, OI(LNOFF(valuelen)),
130 attr_leaf_name_local_count, FLD_COUNT, TYP_NONE },
131 { "namelen", FLDT_UINT8D, OI(LNOFF(namelen)),
132 attr_leaf_name_local_count, FLD_COUNT, TYP_NONE },
133 { "name", FLDT_CHARNS, OI(LNOFF(nameval)),
134 attr_leaf_name_local_name_count, FLD_COUNT, TYP_NONE },
135 { "value", FLDT_CHARNS, attr_leaf_name_local_value_offset,
136 attr_leaf_name_local_value_count, FLD_COUNT|FLD_OFFSET, TYP_NONE },
137 { "valueblk", FLDT_UINT32X, OI(LVOFF(valueblk)),
138 attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE },
139 { "valuelen", FLDT_UINT32D, OI(LVOFF(valuelen)),
140 attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE },
141 { "namelen", FLDT_UINT8D, OI(LVOFF(namelen)),
142 attr_leaf_name_remote_count, FLD_COUNT, TYP_NONE },
143 { "name", FLDT_CHARNS, OI(LVOFF(name)),
144 attr_leaf_name_remote_name_count, FLD_COUNT, TYP_NONE },
145 { NULL }
146 };
147
148 #define EOFF(f) bitize(offsetof(xfs_da_node_entry_t, f))
149 const field_t attr_node_entry_flds[] = {
150 { "hashval", FLDT_UINT32X, OI(EOFF(hashval)), C1, 0, TYP_NONE },
151 { "before", FLDT_ATTRBLOCK, OI(EOFF(before)), C1, 0, TYP_ATTR },
152 { NULL }
153 };
154
155 #define HOFF(f) bitize(offsetof(xfs_da_node_hdr_t, f))
156 const field_t attr_node_hdr_flds[] = {
157 { "info", FLDT_ATTR_BLKINFO, OI(HOFF(info)), C1, 0, TYP_NONE },
158 { "count", FLDT_UINT16D, OI(HOFF(count)), C1, 0, TYP_NONE },
159 { "level", FLDT_UINT16D, OI(HOFF(level)), C1, 0, TYP_NONE },
160 { NULL }
161 };
162
163 /*ARGSUSED*/
164 static int
165 attr_leaf_entries_count(
166 void *obj,
167 int startoff)
168 {
169 xfs_attr_leafblock_t *block;
170
171 ASSERT(startoff == 0);
172 block = obj;
173 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
174 != XFS_ATTR_LEAF_MAGIC) {
175 return 0;
176 }
177
178 return INT_GET(block->hdr.count, ARCH_CONVERT);
179 }
180
181 /*ARGSUSED*/
182 static int
183 attr_leaf_hdr_count(
184 void *obj,
185 int startoff)
186 {
187 xfs_attr_leafblock_t *block;
188
189 ASSERT(startoff == 0);
190 block = obj;
191 return INT_GET(block->hdr.info.magic, ARCH_CONVERT)
192 == XFS_ATTR_LEAF_MAGIC;
193 }
194
195 static int
196 attr_leaf_name_local_count(
197 void *obj,
198 int startoff)
199 {
200 xfs_attr_leafblock_t *block;
201 xfs_attr_leaf_entry_t *e;
202 int i;
203 int off;
204
205 ASSERT(bitoffs(startoff) == 0);
206 off = byteize(startoff);
207 block = obj;
208 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
209 != XFS_ATTR_LEAF_MAGIC)
210 return 0;
211 for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
212 e = &block->entries[i];
213 if (INT_GET(e->nameidx, ARCH_CONVERT) == off)
214 return (INT_GET(e->flags, ARCH_CONVERT)
215 & XFS_ATTR_LOCAL) != 0;
216 }
217 return 0;
218 }
219
220 static int
221 attr_leaf_name_local_name_count(
222 void *obj,
223 int startoff)
224 {
225 xfs_attr_leafblock_t *block;
226 xfs_attr_leaf_entry_t *e;
227 int i;
228 xfs_attr_leaf_name_local_t *l;
229 int off;
230
231 ASSERT(bitoffs(startoff) == 0);
232 off = byteize(startoff);
233 block = obj;
234 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
235 != XFS_ATTR_LEAF_MAGIC)
236 return 0;
237 for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
238 e = &block->entries[i];
239 if (INT_GET(e->nameidx, ARCH_CONVERT) == off) {
240 if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) {
241 l = XFS_ATTR_LEAF_NAME_LOCAL(block, i);
242 return INT_GET(l->namelen, ARCH_CONVERT);
243 } else
244 return 0;
245 }
246 }
247 return 0;
248 }
249
250 static int
251 attr_leaf_name_local_value_count(
252 void *obj,
253 int startoff)
254 {
255 xfs_attr_leafblock_t *block;
256 xfs_attr_leaf_entry_t *e;
257 int i;
258 xfs_attr_leaf_name_local_t *l;
259 int off;
260
261 ASSERT(bitoffs(startoff) == 0);
262 off = byteize(startoff);
263 block = obj;
264 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
265 != XFS_ATTR_LEAF_MAGIC)
266 return 0;
267 for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
268 e = &block->entries[i];
269 if (INT_GET(e->nameidx, ARCH_CONVERT) == off) {
270 if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) {
271 l = XFS_ATTR_LEAF_NAME_LOCAL(block, i);
272 return INT_GET(l->valuelen, ARCH_CONVERT);
273 } else
274 return 0;
275 }
276 }
277 return 0;
278 }
279
280 /*ARGSUSED*/
281 static int
282 attr_leaf_name_local_value_offset(
283 void *obj,
284 int startoff,
285 int idx)
286 {
287 xfs_attr_leafblock_t *block;
288 xfs_attr_leaf_name_local_t *l;
289 char *vp;
290 int off;
291 xfs_attr_leaf_entry_t *e;
292 int i;
293
294 ASSERT(bitoffs(startoff) == 0);
295 off = byteize(startoff);
296 block = obj;
297 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
298 != XFS_ATTR_LEAF_MAGIC)
299 return 0;
300
301 for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
302 e = &block->entries[i];
303 if (INT_GET(e->nameidx, ARCH_CONVERT) == off)
304 break;
305 }
306 if (i>=INT_GET(block->hdr.count, ARCH_CONVERT)) return 0;
307
308 l = XFS_ATTR_LEAF_NAME_LOCAL(block, i);
309 vp = (char *)&l->nameval[l->namelen];
310 return (int)bitize(vp - (char *)l);
311 }
312
313 static int
314 attr_leaf_name_remote_count(
315 void *obj,
316 int startoff)
317 {
318 xfs_attr_leafblock_t *block;
319 xfs_attr_leaf_entry_t *e;
320 int i;
321 int off;
322
323 ASSERT(bitoffs(startoff) == 0);
324 off = byteize(startoff);
325 block = obj;
326 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
327 != XFS_ATTR_LEAF_MAGIC)
328 return 0;
329 for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
330 e = &block->entries[i];
331 if (INT_GET(e->nameidx, ARCH_CONVERT) == off)
332 return (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) == 0;
333 }
334 return 0;
335 }
336
337 static int
338 attr_leaf_name_remote_name_count(
339 void *obj,
340 int startoff)
341 {
342 xfs_attr_leafblock_t *block;
343 xfs_attr_leaf_entry_t *e;
344 int i;
345 int off;
346 xfs_attr_leaf_name_remote_t *r;
347
348 ASSERT(bitoffs(startoff) == 0);
349 off = byteize(startoff);
350 block = obj;
351 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
352 != XFS_ATTR_LEAF_MAGIC)
353 return 0;
354 for (i = 0; i < INT_GET(block->hdr.count, ARCH_CONVERT); i++) {
355 e = &block->entries[i];
356 if (INT_GET(e->nameidx, ARCH_CONVERT) == off) {
357 if (!(INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL)) {
358 r = XFS_ATTR_LEAF_NAME_REMOTE(block, i);
359 return INT_GET(r->namelen, ARCH_CONVERT);
360 } else
361 return 0;
362 }
363 }
364 return 0;
365 }
366
367 /*ARGSUSED*/
368 int
369 attr_leaf_name_size(
370 void *obj,
371 int startoff,
372 int idx)
373 {
374 xfs_attr_leafblock_t *block;
375 xfs_attr_leaf_entry_t *e;
376 xfs_attr_leaf_name_local_t *l;
377 xfs_attr_leaf_name_remote_t *r;
378
379 ASSERT(startoff == 0);
380 block = obj;
381 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
382 != XFS_ATTR_LEAF_MAGIC)
383 return 0;
384 e = &block->entries[idx];
385 if (INT_GET(e->flags, ARCH_CONVERT) & XFS_ATTR_LOCAL) {
386 l = XFS_ATTR_LEAF_NAME_LOCAL(block, idx);
387 return (int)bitize(XFS_ATTR_LEAF_ENTSIZE_LOCAL(INT_GET(l->namelen, ARCH_CONVERT),
388 INT_GET(l->valuelen, ARCH_CONVERT)));
389 } else {
390 r = XFS_ATTR_LEAF_NAME_REMOTE(block, idx);
391 return (int)bitize(XFS_ATTR_LEAF_ENTSIZE_REMOTE(INT_GET(r->namelen, ARCH_CONVERT)));
392 }
393 }
394
395 /*ARGSUSED*/
396 static int
397 attr_leaf_nvlist_count(
398 void *obj,
399 int startoff)
400 {
401 xfs_attr_leafblock_t *block;
402
403 ASSERT(startoff == 0);
404 block = obj;
405 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
406 != XFS_ATTR_LEAF_MAGIC)
407 return 0;
408 return INT_GET(block->hdr.count, ARCH_CONVERT);
409 }
410
411 /*ARGSUSED*/
412 static int
413 attr_leaf_nvlist_offset(
414 void *obj,
415 int startoff,
416 int idx)
417 {
418 xfs_attr_leafblock_t *block;
419 xfs_attr_leaf_entry_t *e;
420
421 ASSERT(startoff == 0);
422 block = obj;
423 e = &block->entries[idx];
424 return bitize(INT_GET(e->nameidx, ARCH_CONVERT));
425 }
426
427 /*ARGSUSED*/
428 static int
429 attr_node_btree_count(
430 void *obj,
431 int startoff)
432 {
433 xfs_da_intnode_t *block;
434
435 ASSERT(startoff == 0); /* this is a base structure */
436 block = obj;
437 if (INT_GET(block->hdr.info.magic, ARCH_CONVERT)
438 != XFS_DA_NODE_MAGIC)
439 return 0;
440 return INT_GET(block->hdr.count, ARCH_CONVERT);
441 }
442
443 /*ARGSUSED*/
444 static int
445 attr_node_hdr_count(
446 void *obj,
447 int startoff)
448 {
449 xfs_da_intnode_t *block;
450
451 ASSERT(startoff == 0);
452 block = obj;
453 return INT_GET(block->hdr.info.magic, ARCH_CONVERT)
454 == XFS_DA_NODE_MAGIC;
455 }
456
457 /*ARGSUSED*/
458 int
459 attr_size(
460 void *obj,
461 int startoff,
462 int idx)
463 {
464 return bitize(mp->m_sb.sb_blocksize);
465 }