]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/attr.c
Update copyright dates
[thirdparty/xfsprogs-dev.git] / db / attr.c
CommitLineData
2bd0ea18 1/*
cc08d43e 2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
2bd0ea18
NS
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
44static int attr_leaf_entries_count(void *obj, int startoff);
45static int attr_leaf_hdr_count(void *obj, int startoff);
46static int attr_leaf_name_local_count(void *obj, int startoff);
47static int attr_leaf_name_local_name_count(void *obj, int startoff);
48static int attr_leaf_name_local_value_count(void *obj, int startoff);
49static int attr_leaf_name_local_value_offset(void *obj, int startoff,
50 int idx);
51static int attr_leaf_name_remote_count(void *obj, int startoff);
52static int attr_leaf_name_remote_name_count(void *obj, int startoff);
53static int attr_leaf_nvlist_count(void *obj, int startoff);
54static int attr_leaf_nvlist_offset(void *obj, int startoff, int idx);
55static int attr_node_btree_count(void *obj, int startoff);
56static int attr_node_hdr_count(void *obj, int startoff);
57
58const 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))
65const 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))
80const 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))
89const 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))
107const 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))
120const 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))
128const 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))
149const 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))
156const 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*/
164static int
165attr_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*/
182static int
183attr_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
195static int
196attr_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
220static int
221attr_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
250static int
251attr_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*/
281static int
282attr_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
313static int
314attr_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
337static int
338attr_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*/
368int
369attr_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*/
396static int
397attr_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*/
412static int
413attr_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*/
428static int
429attr_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*/
444static int
445attr_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*/
458int
459attr_size(
460 void *obj,
461 int startoff,
462 int idx)
463{
464 return bitize(mp->m_sb.sb_blocksize);
465}