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