2 * Copyright (c) 2000-2001,2004-2005 Silicon Graphics, Inc.
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.
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.
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
30 static int attr_leaf_entries_count(void *obj
, int startoff
);
31 static int attr_leaf_hdr_count(void *obj
, int startoff
);
32 static int attr_leaf_name_local_count(void *obj
, int startoff
);
33 static int attr_leaf_name_local_name_count(void *obj
, int startoff
);
34 static int attr_leaf_name_local_value_count(void *obj
, int startoff
);
35 static int attr_leaf_name_local_value_offset(void *obj
, int startoff
,
37 static int attr_leaf_name_remote_count(void *obj
, int startoff
);
38 static int attr_leaf_name_remote_name_count(void *obj
, int startoff
);
39 static int attr_leaf_nvlist_count(void *obj
, int startoff
);
40 static int attr_leaf_nvlist_offset(void *obj
, int startoff
, int idx
);
41 static int attr_node_btree_count(void *obj
, int startoff
);
42 static int attr_node_hdr_count(void *obj
, int startoff
);
44 const field_t attr_hfld
[] = {
45 { "", FLDT_ATTR
, OI(0), C1
, 0, TYP_NONE
},
49 #define LOFF(f) bitize(offsetof(xfs_attr_leafblock_t, f))
50 #define NOFF(f) bitize(offsetof(xfs_da_intnode_t, f))
51 const field_t attr_flds
[] = {
52 { "hdr", FLDT_ATTR_LEAF_HDR
, OI(LOFF(hdr
)), attr_leaf_hdr_count
,
53 FLD_COUNT
, TYP_NONE
},
54 { "hdr", FLDT_ATTR_NODE_HDR
, OI(NOFF(hdr
)), attr_node_hdr_count
,
55 FLD_COUNT
, TYP_NONE
},
56 { "entries", FLDT_ATTR_LEAF_ENTRY
, OI(LOFF(entries
)),
57 attr_leaf_entries_count
, FLD_ARRAY
|FLD_COUNT
, TYP_NONE
},
58 { "btree", FLDT_ATTR_NODE_ENTRY
, OI(NOFF(__btree
)), attr_node_btree_count
,
59 FLD_ARRAY
|FLD_COUNT
, TYP_NONE
},
60 { "nvlist", FLDT_ATTR_LEAF_NAME
, attr_leaf_nvlist_offset
,
61 attr_leaf_nvlist_count
, FLD_ARRAY
|FLD_OFFSET
|FLD_COUNT
, TYP_NONE
},
65 #define BOFF(f) bitize(offsetof(xfs_da_blkinfo_t, f))
66 const field_t attr_blkinfo_flds
[] = {
67 { "forw", FLDT_ATTRBLOCK
, OI(BOFF(forw
)), C1
, 0, TYP_ATTR
},
68 { "back", FLDT_ATTRBLOCK
, OI(BOFF(back
)), C1
, 0, TYP_ATTR
},
69 { "magic", FLDT_UINT16X
, OI(BOFF(magic
)), C1
, 0, TYP_NONE
},
70 { "pad", FLDT_UINT16X
, OI(BOFF(pad
)), C1
, FLD_SKIPALL
, TYP_NONE
},
74 #define LEOFF(f) bitize(offsetof(xfs_attr_leaf_entry_t, f))
75 const field_t attr_leaf_entry_flds
[] = {
76 { "hashval", FLDT_UINT32X
, OI(LEOFF(hashval
)), C1
, 0, TYP_NONE
},
77 { "nameidx", FLDT_UINT16D
, OI(LEOFF(nameidx
)), C1
, 0, TYP_NONE
},
78 { "flags", FLDT_UINT8X
, OI(LEOFF(flags
)), C1
, FLD_SKIPALL
, TYP_NONE
},
79 { "incomplete", FLDT_UINT1
,
80 OI(LEOFF(flags
) + bitsz(__uint8_t
) - XFS_ATTR_INCOMPLETE_BIT
- 1), C1
,
83 OI(LEOFF(flags
) + bitsz(__uint8_t
) - XFS_ATTR_ROOT_BIT
- 1), C1
, 0,
85 { "secure", FLDT_UINT1
,
86 OI(LEOFF(flags
) + bitsz(__uint8_t
) - XFS_ATTR_SECURE_BIT
- 1), C1
, 0,
88 { "local", FLDT_UINT1
,
89 OI(LEOFF(flags
) + bitsz(__uint8_t
) - XFS_ATTR_LOCAL_BIT
- 1), C1
, 0,
91 { "pad2", FLDT_UINT8X
, OI(LEOFF(pad2
)), C1
, FLD_SKIPALL
, TYP_NONE
},
95 #define LHOFF(f) bitize(offsetof(xfs_attr_leaf_hdr_t, f))
96 const field_t attr_leaf_hdr_flds
[] = {
97 { "info", FLDT_ATTR_BLKINFO
, OI(LHOFF(info
)), C1
, 0, TYP_NONE
},
98 { "count", FLDT_UINT16D
, OI(LHOFF(count
)), C1
, 0, TYP_NONE
},
99 { "usedbytes", FLDT_UINT16D
, OI(LHOFF(usedbytes
)), C1
, 0, TYP_NONE
},
100 { "firstused", FLDT_UINT16D
, OI(LHOFF(firstused
)), C1
, 0, TYP_NONE
},
101 { "holes", FLDT_UINT8D
, OI(LHOFF(holes
)), C1
, 0, TYP_NONE
},
102 { "pad1", FLDT_UINT8X
, OI(LHOFF(pad1
)), C1
, FLD_SKIPALL
, TYP_NONE
},
103 { "freemap", FLDT_ATTR_LEAF_MAP
, OI(LHOFF(freemap
)),
104 CI(XFS_ATTR_LEAF_MAPSIZE
), FLD_ARRAY
, TYP_NONE
},
108 #define LMOFF(f) bitize(offsetof(xfs_attr_leaf_map_t, f))
109 const field_t attr_leaf_map_flds
[] = {
110 { "base", FLDT_UINT16D
, OI(LMOFF(base
)), C1
, 0, TYP_NONE
},
111 { "size", FLDT_UINT16D
, OI(LMOFF(size
)), C1
, 0, TYP_NONE
},
115 #define LNOFF(f) bitize(offsetof(xfs_attr_leaf_name_local_t, f))
116 #define LVOFF(f) bitize(offsetof(xfs_attr_leaf_name_remote_t, f))
117 const field_t attr_leaf_name_flds
[] = {
118 { "valuelen", FLDT_UINT16D
, OI(LNOFF(valuelen
)),
119 attr_leaf_name_local_count
, FLD_COUNT
, TYP_NONE
},
120 { "namelen", FLDT_UINT8D
, OI(LNOFF(namelen
)),
121 attr_leaf_name_local_count
, FLD_COUNT
, TYP_NONE
},
122 { "name", FLDT_CHARNS
, OI(LNOFF(nameval
)),
123 attr_leaf_name_local_name_count
, FLD_COUNT
, TYP_NONE
},
124 { "value", FLDT_CHARNS
, attr_leaf_name_local_value_offset
,
125 attr_leaf_name_local_value_count
, FLD_COUNT
|FLD_OFFSET
, TYP_NONE
},
126 { "valueblk", FLDT_UINT32X
, OI(LVOFF(valueblk
)),
127 attr_leaf_name_remote_count
, FLD_COUNT
, TYP_NONE
},
128 { "valuelen", FLDT_UINT32D
, OI(LVOFF(valuelen
)),
129 attr_leaf_name_remote_count
, FLD_COUNT
, TYP_NONE
},
130 { "namelen", FLDT_UINT8D
, OI(LVOFF(namelen
)),
131 attr_leaf_name_remote_count
, FLD_COUNT
, TYP_NONE
},
132 { "name", FLDT_CHARNS
, OI(LVOFF(name
)),
133 attr_leaf_name_remote_name_count
, FLD_COUNT
, TYP_NONE
},
137 #define EOFF(f) bitize(offsetof(xfs_da_node_entry_t, f))
138 const field_t attr_node_entry_flds
[] = {
139 { "hashval", FLDT_UINT32X
, OI(EOFF(hashval
)), C1
, 0, TYP_NONE
},
140 { "before", FLDT_ATTRBLOCK
, OI(EOFF(before
)), C1
, 0, TYP_ATTR
},
144 #define HOFF(f) bitize(offsetof(xfs_da_node_hdr_t, f))
145 const field_t attr_node_hdr_flds
[] = {
146 { "info", FLDT_ATTR_BLKINFO
, OI(HOFF(info
)), C1
, 0, TYP_NONE
},
147 { "count", FLDT_UINT16D
, OI(HOFF(__count
)), C1
, 0, TYP_NONE
},
148 { "level", FLDT_UINT16D
, OI(HOFF(__level
)), C1
, 0, TYP_NONE
},
153 attr_leaf_entries_count(
157 struct xfs_attr_leafblock
*leaf
= obj
;
159 ASSERT(startoff
== 0);
160 if (be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_ATTR_LEAF_MAGIC
)
162 return be16_to_cpu(leaf
->hdr
.count
);
166 attr3_leaf_entries_count(
170 struct xfs_attr3_leafblock
*leaf
= obj
;
172 ASSERT(startoff
== 0);
173 if (be16_to_cpu(leaf
->hdr
.info
.hdr
.magic
) != XFS_ATTR3_LEAF_MAGIC
)
175 return be16_to_cpu(leaf
->hdr
.count
);
183 struct xfs_attr_leafblock
*leaf
= obj
;
185 ASSERT(startoff
== 0);
186 return be16_to_cpu(leaf
->hdr
.info
.magic
) == XFS_ATTR_LEAF_MAGIC
;
190 attr3_leaf_hdr_count(
194 struct xfs_attr3_leafblock
*leaf
= obj
;
196 ASSERT(startoff
== 0);
197 return be16_to_cpu(leaf
->hdr
.info
.hdr
.magic
) == XFS_ATTR3_LEAF_MAGIC
;
200 typedef int (*attr_leaf_entry_walk_f
)(struct xfs_attr_leafblock
*,
201 struct xfs_attr_leaf_entry
*, int);
203 attr_leaf_entry_walk(
206 attr_leaf_entry_walk_f func
)
208 struct xfs_attr_leafblock
*leaf
= obj
;
209 struct xfs_attr3_icleaf_hdr leafhdr
;
210 struct xfs_attr_leaf_entry
*entries
;
211 struct xfs_attr_leaf_entry
*e
;
215 ASSERT(bitoffs(startoff
) == 0);
216 if (be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_ATTR_LEAF_MAGIC
&&
217 be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_ATTR3_LEAF_MAGIC
)
220 off
= byteize(startoff
);
221 xfs_attr3_leaf_hdr_from_disk(mp
->m_attr_geo
, &leafhdr
, leaf
);
222 entries
= xfs_attr3_leaf_entryp(leaf
);
224 for (i
= 0; i
< leafhdr
.count
; i
++) {
226 if (be16_to_cpu(e
->nameidx
) == off
)
227 return func(leaf
, e
, i
);
233 __attr_leaf_name_local_count(
234 struct xfs_attr_leafblock
*leaf
,
235 struct xfs_attr_leaf_entry
*e
,
238 return (e
->flags
& XFS_ATTR_LOCAL
) != 0;
242 attr_leaf_name_local_count(
246 return attr_leaf_entry_walk(obj
, startoff
,
247 __attr_leaf_name_local_count
);
251 __attr_leaf_name_local_name_count(
252 struct xfs_attr_leafblock
*leaf
,
253 struct xfs_attr_leaf_entry
*e
,
256 struct xfs_attr_leaf_name_local
*l
;
258 if (!(e
->flags
& XFS_ATTR_LOCAL
))
261 l
= xfs_attr3_leaf_name_local(leaf
, i
);
266 attr_leaf_name_local_name_count(
270 return attr_leaf_entry_walk(obj
, startoff
,
271 __attr_leaf_name_local_name_count
);
275 __attr_leaf_name_local_value_count(
276 struct xfs_attr_leafblock
*leaf
,
277 struct xfs_attr_leaf_entry
*e
,
280 struct xfs_attr_leaf_name_local
*l
;
282 if (!(e
->flags
& XFS_ATTR_LOCAL
))
285 l
= xfs_attr3_leaf_name_local(leaf
, i
);
286 return be16_to_cpu(l
->valuelen
);
290 attr_leaf_name_local_value_count(
294 return attr_leaf_entry_walk(obj
, startoff
,
295 __attr_leaf_name_local_value_count
);
299 __attr_leaf_name_local_value_offset(
300 struct xfs_attr_leafblock
*leaf
,
301 struct xfs_attr_leaf_entry
*e
,
304 struct xfs_attr_leaf_name_local
*l
;
307 l
= xfs_attr3_leaf_name_local(leaf
, i
);
308 vp
= (char *)&l
->nameval
[l
->namelen
];
310 return (int)bitize(vp
- (char *)l
);
314 attr_leaf_name_local_value_offset(
319 return attr_leaf_entry_walk(obj
, startoff
,
320 __attr_leaf_name_local_value_offset
);
324 __attr_leaf_name_remote_count(
325 struct xfs_attr_leafblock
*leaf
,
326 struct xfs_attr_leaf_entry
*e
,
329 return (e
->flags
& XFS_ATTR_LOCAL
) == 0;
333 attr_leaf_name_remote_count(
337 return attr_leaf_entry_walk(obj
, startoff
,
338 __attr_leaf_name_remote_count
);
342 __attr_leaf_name_remote_name_count(
343 struct xfs_attr_leafblock
*leaf
,
344 struct xfs_attr_leaf_entry
*e
,
347 struct xfs_attr_leaf_name_remote
*r
;
349 if (e
->flags
& XFS_ATTR_LOCAL
)
352 r
= xfs_attr3_leaf_name_remote(leaf
, i
);
357 attr_leaf_name_remote_name_count(
361 return attr_leaf_entry_walk(obj
, startoff
,
362 __attr_leaf_name_remote_name_count
);
371 struct xfs_attr_leafblock
*leaf
= obj
;
372 struct xfs_attr_leaf_entry
*e
;
373 struct xfs_attr_leaf_name_local
*l
;
374 struct xfs_attr_leaf_name_remote
*r
;
376 ASSERT(startoff
== 0);
377 if (be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_ATTR_LEAF_MAGIC
&&
378 be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_ATTR3_LEAF_MAGIC
)
380 e
= &xfs_attr3_leaf_entryp(leaf
)[idx
];
381 if (e
->flags
& XFS_ATTR_LOCAL
) {
382 l
= xfs_attr3_leaf_name_local(leaf
, idx
);
383 return (int)bitize(xfs_attr_leaf_entsize_local(l
->namelen
,
384 be16_to_cpu(l
->valuelen
)));
386 r
= xfs_attr3_leaf_name_remote(leaf
, idx
);
387 return (int)bitize(xfs_attr_leaf_entsize_remote(r
->namelen
));
392 attr_leaf_nvlist_count(
396 struct xfs_attr_leafblock
*leaf
= obj
;
398 ASSERT(startoff
== 0);
399 if (be16_to_cpu(leaf
->hdr
.info
.magic
) != XFS_ATTR_LEAF_MAGIC
)
401 return be16_to_cpu(leaf
->hdr
.count
);
405 attr3_leaf_nvlist_count(
409 struct xfs_attr3_leafblock
*leaf
= obj
;
411 ASSERT(startoff
== 0);
412 if (be16_to_cpu(leaf
->hdr
.info
.hdr
.magic
) != XFS_ATTR3_LEAF_MAGIC
)
414 return be16_to_cpu(leaf
->hdr
.count
);
418 attr_leaf_nvlist_offset(
423 struct xfs_attr_leafblock
*leaf
= obj
;
424 struct xfs_attr_leaf_entry
*e
;
426 ASSERT(startoff
== 0);
427 e
= &xfs_attr3_leaf_entryp(leaf
)[idx
];
428 return bitize(be16_to_cpu(e
->nameidx
));
432 attr_node_btree_count(
436 struct xfs_da_intnode
*node
= obj
;
438 ASSERT(startoff
== 0); /* this is a base structure */
439 if (be16_to_cpu(node
->hdr
.info
.magic
) != XFS_DA_NODE_MAGIC
)
441 return be16_to_cpu(node
->hdr
.__count
);
445 attr3_node_btree_count(
449 struct xfs_da3_intnode
*node
= obj
;
451 ASSERT(startoff
== 0);
452 if (be16_to_cpu(node
->hdr
.info
.hdr
.magic
) != XFS_DA3_NODE_MAGIC
)
454 return be16_to_cpu(node
->hdr
.__count
);
463 struct xfs_da_intnode
*node
= obj
;
465 ASSERT(startoff
== 0);
466 return be16_to_cpu(node
->hdr
.info
.magic
) == XFS_DA_NODE_MAGIC
;
470 attr3_node_hdr_count(
474 struct xfs_da3_intnode
*node
= obj
;
476 ASSERT(startoff
== 0);
477 return be16_to_cpu(node
->hdr
.info
.hdr
.magic
) == XFS_DA3_NODE_MAGIC
;
486 return bitize(mp
->m_sb
.sb_blocksize
);
490 * CRC enabled attribute block field definitions
492 const field_t attr3_hfld
[] = {
493 { "", FLDT_ATTR3
, OI(0), C1
, 0, TYP_NONE
},
497 #define L3OFF(f) bitize(offsetof(struct xfs_attr3_leafblock, f))
498 #define N3OFF(f) bitize(offsetof(struct xfs_da3_intnode, f))
499 const field_t attr3_flds
[] = {
500 { "hdr", FLDT_ATTR3_LEAF_HDR
, OI(L3OFF(hdr
)), attr3_leaf_hdr_count
,
501 FLD_COUNT
, TYP_NONE
},
502 { "hdr", FLDT_DA3_NODE_HDR
, OI(N3OFF(hdr
)), attr3_node_hdr_count
,
503 FLD_COUNT
, TYP_NONE
},
504 { "entries", FLDT_ATTR_LEAF_ENTRY
, OI(L3OFF(entries
)),
505 attr3_leaf_entries_count
, FLD_ARRAY
|FLD_COUNT
, TYP_NONE
},
506 { "btree", FLDT_ATTR_NODE_ENTRY
, OI(N3OFF(__btree
)),
507 attr3_node_btree_count
, FLD_ARRAY
|FLD_COUNT
, TYP_NONE
},
508 { "nvlist", FLDT_ATTR_LEAF_NAME
, attr_leaf_nvlist_offset
,
509 attr3_leaf_nvlist_count
, FLD_ARRAY
|FLD_OFFSET
|FLD_COUNT
, TYP_NONE
},
513 #define LH3OFF(f) bitize(offsetof(struct xfs_attr3_leaf_hdr, f))
514 const field_t attr3_leaf_hdr_flds
[] = {
515 { "info", FLDT_DA3_BLKINFO
, OI(LH3OFF(info
)), C1
, 0, TYP_NONE
},
516 { "count", FLDT_UINT16D
, OI(LH3OFF(count
)), C1
, 0, TYP_NONE
},
517 { "usedbytes", FLDT_UINT16D
, OI(LH3OFF(usedbytes
)), C1
, 0, TYP_NONE
},
518 { "firstused", FLDT_UINT16D
, OI(LH3OFF(firstused
)), C1
, 0, TYP_NONE
},
519 { "holes", FLDT_UINT8D
, OI(LH3OFF(holes
)), C1
, 0, TYP_NONE
},
520 { "pad1", FLDT_UINT8X
, OI(LH3OFF(pad1
)), C1
, FLD_SKIPALL
, TYP_NONE
},
521 { "freemap", FLDT_ATTR_LEAF_MAP
, OI(LH3OFF(freemap
)),
522 CI(XFS_ATTR_LEAF_MAPSIZE
), FLD_ARRAY
, TYP_NONE
},
527 * Special read verifier for attribute buffers. Detect the magic number
528 * appropriately and set the correct verifier and call it.
531 xfs_attr3_db_read_verify(
537 magic32
= *(__be32
*)bp
->b_addr
;
538 magic16
= ((struct xfs_da_blkinfo
*)bp
->b_addr
)->magic
;
541 case cpu_to_be16(XFS_ATTR3_LEAF_MAGIC
):
542 bp
->b_ops
= &xfs_attr3_leaf_buf_ops
;
544 case cpu_to_be16(XFS_DA3_NODE_MAGIC
):
545 bp
->b_ops
= &xfs_da3_node_buf_ops
;
552 case cpu_to_be32(XFS_ATTR3_RMT_MAGIC
):
553 bp
->b_ops
= &xfs_attr3_rmt_buf_ops
;
556 dbprintf(_("Unknown attribute buffer type!\n"));
557 xfs_buf_ioerror(bp
, -EFSCORRUPTED
);
561 bp
->b_ops
->verify_read(bp
);
565 xfs_attr3_db_write_verify(
568 dbprintf(_("Writing unknown attribute buffer type!\n"));
569 xfs_buf_ioerror(bp
, -EFSCORRUPTED
);
572 const struct xfs_buf_ops xfs_attr3_db_buf_ops
= {
573 .verify_read
= xfs_attr3_db_read_verify
,
574 .verify_write
= xfs_attr3_db_write_verify
,