xfs: Use dprintf() for debug messages in xfs_debug()
[syslinux.git] / core / fs / xfs / xfs.h
bloba7330c27f7f99f8519415283f527e466cb2691ba
1 /*
2 * Copyright (c) 2012 Paulo Alcantara <pcacjr@zytor.com>
4 * Some parts borrowed from Linux kernel tree (linux/fs/xfs):
6 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
7 * All Rights Reserved.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it would be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #ifndef XFS_H_
24 #define XFS_H_
26 #include <disk.h>
27 #include <fs.h>
28 #include <dprintf.h>
30 #include "xfs_types.h"
31 #include "xfs_ag.h"
33 #define xfs_error(fmt, args...) \
34 printf("xfs: " fmt "\n", ## args);
36 #define xfs_debug(fmt, args...) \
37 dprintf("%s: " fmt "\n", __func__, ## args);
39 struct xfs_fs_info;
41 #define XFS_INFO(fs) ((struct xfs_fs_info *)((fs)->fs_info))
42 #define XFS_PVT(ino) ((struct xfs_inode *)((ino)->pvt))
44 #define XFS_INO_MASK(k) (uint32_t)((1ULL << (k)) - 1)
45 #define XFS_INO_OFFSET_BITS(fs) (fs)->inopb_shift
46 #define XFS_INO_AGINO_BITS(fs) \
47 (XFS_INFO((fs))->inopb_shift + XFS_INFO((fs))->agblk_shift)
49 #define XFS_INO_TO_AGINO(fs, i) \
50 ((xfs_agino_t)(i) & XFS_INO_MASK(XFS_INO_AGINO_BITS(fs)))
52 #define XFS_INO_TO_AGNO(fs, ino) \
53 ((xfs_agnumber_t)((ino) >> (XFS_INFO((fs))->inopb_shift + \
54 XFS_INFO((fs))->agblk_shift)))
56 #define XFS_INO_TO_OFFSET(fs, i) \
57 ((int)(i) & XFS_INO_MASK(XFS_INO_OFFSET_BITS(fs)))
59 #define XFS_AGNO_TO_FSB(fs, agno) \
60 ((block_t)((agno) << XFS_INFO((fs))->agblocks_shift))
62 #define XFS_AGI_OFFS(fs, mp) \
63 ((xfs_agi_t *)((uint8_t *)(mp) + 2 * SECTOR_SIZE((fs))))
65 #define XFS_GET_DIR_INO4(di) \
66 (((uint32_t)(di).i[0] << 24) | ((di).i[1] << 16) | ((di).i[2] << 8) | \
67 ((di).i[3]))
69 #define XFS_DI_HI(di) \
70 (((uint32_t)(di).i[1] << 16) | ((di).i[2] << 8) | ((di).i[3]))
72 #define XFS_DI_LO(di) \
73 (((uint32_t)(di).i[4] << 24) | ((di).i[5] << 16) | ((di).i[6] << 8) | \
74 ((di).i[7]))
76 #define XFS_GET_DIR_INO8(di) \
77 (((xfs_ino_t)XFS_DI_LO(di) & 0xffffffffULL) | \
78 ((xfs_ino_t)XFS_DI_HI(di) << 32))
80 #define XFS_FSB_TO_AGNO(fs, fsbno) \
81 ((xfs_agnumber_t)((fsbno) >> XFS_INFO((fs))->agblk_shift))
82 #define XFS_FSB_TO_AGBNO(fs, fsbno) \
83 ((xfs_agblock_t)((fsbno) & (uint32_t)((1ULL << \
84 XFS_INFO((fs))->agblk_shift) - 1)))
86 #define agblock_to_bytes(fs, x) \
87 ((uint64_t)(x) << BLOCK_SHIFT((fs)))
88 #define agino_to_bytes(fs, x) \
89 ((uint64_t)(x) << XFS_INFO((fs))->inode_shift)
90 #define agnumber_to_bytes(fs, x) \
91 agblock_to_bytes(fs, (uint64_t)(x) * XFS_INFO((fs))->agblocks)
92 #define fsblock_to_bytes(fs,x) \
93 (agnumber_to_bytes(fs, XFS_FSB_TO_AGNO(fs, (x))) + \
94 agblock_to_bytes(fs, XFS_FSB_TO_AGBNO(fs, (x))))
95 #define ino_to_bytes(fs, x) \
96 (agnumber_to_bytes(fs, XFS_INO_TO_AGNO(fs, (x))) + \
97 agino_to_bytes(fs, XFS_INO_TO_AGINO(fs, (x))))
99 /* Superblock's LBA */
100 #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */
102 /* Magic numbers */
103 #define XFS_AGI_MAGIC "XAGI"
104 #define XFS_IBT_MAGIC "IABT"
105 #define XFS_DINODE_MAGIC "IN"
107 #define XFS_DIR2_BLOCK_MAGIC 0x58443242U /* XD2B: single block dirs */
108 #define XFS_DIR2_DATA_MAGIC 0x58443244U /* XD2D: multiblock dirs */
109 #define XFS_DIR2_FREE_MAGIC 0x58443246U /* XD2F: free index blocks */
111 #define XFS_DIR2_NULL_DATAPTR ((uint32_t)0)
113 /* File types and modes */
114 #define S_IFMT 00170000
115 #define S_IFSOCK 0140000
116 #define S_IFLNK 0120000
117 #define S_IFREG 0100000
118 #define S_IFBLK 0060000
119 #define S_IFDIR 0040000
120 #define S_IFCHR 0020000
121 #define S_IFIFO 0010000
122 #define S_ISUID 0004000
123 #define S_ISGID 0002000
124 #define S_ISVTX 0001000
127 * NOTE: The fields in the superblock are stored in big-endian format on disk.
129 typedef struct xfs_sb {
130 uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */
131 uint32_t sb_blocksize; /* logical block size, bytes */
132 xfs_drfsbno_t sb_dblocks; /* number of data blocks */
133 xfs_drfsbno_t sb_rblocks; /* number of realtime blocks */
134 xfs_drtbno_t sb_rextents; /* number of realtime extents */
135 uuid_t sb_uuid; /* file system unique id */
136 xfs_dfsbno_t sb_logstart; /* starting block of log if internal */
137 xfs_ino_t sb_rootino; /* root inode number */
138 xfs_ino_t sb_rbmino; /* bitmap inode for realtime extents */
139 xfs_ino_t sb_rsumino; /* summary inode for rt bitmap */
140 xfs_agblock_t sb_rextsize; /* realtime extent size, blocks */
141 xfs_agblock_t sb_agblocks; /* size of an allocation group */
142 xfs_agnumber_t sb_agcount; /* number of allocation groups */
143 xfs_extlen_t sb_rbmblocks; /* number of rt bitmap blocks */
144 xfs_extlen_t sb_logblocks; /* number of log blocks */
145 uint16_t sb_versionnum; /* header version == XFS_SB_VERSION */
146 uint16_t sb_sectsize; /* volume sector size, bytes */
147 uint16_t sb_inodesize; /* inode size, bytes */
148 uint16_t sb_inopblock; /* inodes per block */
149 char sb_fname[12]; /* file system name */
150 uint8_t sb_blocklog; /* log2 of sb_blocksize */
151 uint8_t sb_sectlog; /* log2 of sb_sectsize */
152 uint8_t sb_inodelog; /* log2 of sb_inodesize */
153 uint8_t sb_inopblog; /* log2 of sb_inopblock */
154 uint8_t sb_agblklog; /* log2 of sb_agblocks (rounded up) */
155 uint8_t sb_rextslog; /* log2 of sb_rextents */
156 uint8_t sb_inprogress; /* mkfs is in progress, don't mount */
157 uint8_t sb_imax_pct; /* max % of fs for inode space */
158 /* statistics */
160 * These fields must remain contiguous. If you really
161 * want to change their layout, make sure you fix the
162 * code in xfs_trans_apply_sb_deltas().
164 uint64_t sb_icount; /* allocated inodes */
165 uint64_t sb_ifree; /* free inodes */
166 uint64_t sb_fdblocks; /* free data blocks */
167 uint64_t sb_frextents; /* free realtime extents */
169 * End contiguous fields.
171 xfs_ino_t sb_uquotino; /* user quota inode */
172 xfs_ino_t sb_gquotino; /* group quota inode */
173 uint16_t sb_qflags; /* quota flags */
174 uint8_t sb_flags; /* misc. flags */
175 uint8_t sb_shared_vn; /* shared version number */
176 xfs_extlen_t sb_inoalignmt; /* inode chunk alignment, fsblocks */
177 uint32_t sb_unit; /* stripe or raid unit */
178 uint32_t sb_width; /* stripe or raid width */
179 uint8_t sb_dirblklog; /* log2 of dir block size (fsbs) */
180 uint8_t sb_logsectlog; /* log2 of the log sector size */
181 uint16_t sb_logsectsize; /* sector size for the log, bytes */
182 uint32_t sb_logsunit; /* stripe unit size for the log */
183 uint32_t sb_features2; /* additional feature bits */
186 * bad features2 field as a result of failing to pad the sb
187 * structure to 64 bits. Some machines will be using this field
188 * for features2 bits. Easiest just to mark it bad and not use
189 * it for anything else.
191 uint32_t sb_bad_features2;
192 uint8_t pad[304]; /* must be padded to a sector boundary */
193 } __attribute__((__packed__)) xfs_sb_t;
195 /* In-memory structure that stores filesystem-specific information.
196 * The information stored is basically retrieved from the XFS superblock
197 * to be used statically around the driver.
199 struct xfs_fs_info {
200 uint32_t blocksize; /* Filesystem block size */
201 uint8_t block_shift; /* Filesystem block size in bits */
202 uint32_t dirblksize;
203 uint8_t dirblklog;
204 uint8_t inopb_shift;
205 uint8_t agblk_shift;
206 uint32_t dirleafblk;
208 /* AG number bits (MSB of the inode number) */
209 uint8_t ag_number_ino_shift;
211 xfs_ino_t rootino; /* Root inode number for the filesystem */
212 xfs_agblock_t agblocks; /* Size of each AG in blocks */
213 uint8_t agblocks_shift; /* agblocks in bits */
214 xfs_agnumber_t agcount; /* Number of AGs in the filesytem */
215 uint16_t inodesize; /* Size of the inode in bytes */
216 uint8_t inode_shift; /* Inode size in bits */
217 } __attribute__((__packed__));
219 typedef struct xfs_agi {
221 * Common allocation group header information
223 uint32_t agi_magicnum; /* magic number == XFS_AGI_MAGIC */
224 uint32_t agi_versionnum; /* header version == XFS_AGI_VERSION */
225 uint32_t agi_seqno; /* sequence # starting from 0 */
226 uint32_t agi_length; /* size in blocks of a.g. */
228 * Inode information
229 * Inodes are mapped by interpreting the inode number, so no
230 * mapping data is needed here.
232 uint32_t agi_count; /* count of allocated inodes */
233 uint32_t agi_root; /* root of inode btree */
234 uint32_t agi_level; /* levels in inode btree */
235 uint32_t agi_freecount; /* number of free inodes */
236 uint32_t agi_newino; /* new inode just allocated */
237 uint32_t agi_dirino; /* last directory inode chunk */
239 * Hash table of inodes which have been unlinked but are
240 * still being referenced.
242 uint32_t agi_unlinked[XFS_AGI_UNLINKED_BUCKETS];
243 } __attribute__((__packed__)) xfs_agi_t;
245 typedef struct xfs_btree_sblock {
246 uint32_t bb_magic;
247 uint16_t bb_level;
248 uint16_t bb_numrecs;
249 uint32_t bb_leftsib;
250 uint32_t bb_rightsib;
251 } __attribute__((__packed__)) xfs_btree_sblock_t;
253 typedef struct xfs_inobt_rec {
254 uint32_t ir_startino;
255 uint32_t ir_freecount;
256 uint64_t ir_free;
257 } __attribute__((__packed__)) xfs_inobt_rec_t;
260 * Bmap btree record and extent descriptor.
261 * l0:63 is an extent flag (value 1 indicates non-normal).
262 * l0:9-62 are startoff.
263 * l0:0-8 and l1:21-63 are startblock.
264 * l1:0-20 are blockcount.
266 typedef struct xfs_bmbt_rec {
267 uint64_t l0;
268 uint64_t l1;
269 } __attribute__((__packed__)) xfs_bmbt_rec_t;
272 * Possible extent states.
274 typedef enum {
275 XFS_EXT_NORM,
276 XFS_EXT_UNWRITTEN,
277 XFS_EXT_DMAPI_OFFLINE,
278 XFS_EXT_INVALID,
279 } xfs_exntst_t;
281 typedef struct xfs_bmbt_irec
283 xfs_fileoff_t br_startoff; /* starting file offset */
284 xfs_fsblock_t br_startblock; /* starting block number */
285 xfs_filblks_t br_blockcount; /* number of blocks */
286 xfs_exntst_t br_state; /* extent state */
287 } __attribute__((__packed__)) xfs_bmbt_irec_t;
289 static inline void bmbt_irec_get(xfs_bmbt_irec_t *dest,
290 const xfs_bmbt_rec_t *src)
292 uint64_t l0, l1;
294 l0 = be64_to_cpu(src->l0);
295 l1 = be64_to_cpu(src->l1);
297 dest->br_startoff = ((xfs_fileoff_t)l0 & 0x7ffffffffffffe00ULL) >> 9;
298 dest->br_startblock = (((xfs_fsblock_t)l0 & 0x00000000000001ffULL) << 43) |
299 (((xfs_fsblock_t)l1) >> 21);
300 dest->br_blockcount = (xfs_filblks_t)(l1 & 0x00000000001fffffULL);
301 dest->br_state = (l0 & 0x8000000000000000ULL) ?
302 XFS_EXT_UNWRITTEN : XFS_EXT_NORM;
305 typedef struct xfs_timestamp {
306 int32_t t_sec;
307 int32_t t_nsec;
308 } __attribute__((__packed__)) xfs_timestamp_t;
310 typedef enum xfs_dinode_fmt {
311 XFS_DINODE_FMT_DEV,
312 XFS_DINODE_FMT_LOCAL,
313 XFS_DINODE_FMT_EXTENTS,
314 XFS_DINODE_FMT_BTREE,
315 XFS_DINODE_FMT_UUID,
316 } xfs_dinode_fmt_t;
318 typedef struct xfs_dinode {
319 uint16_t di_magic; /* inode magic # = XFS_DINODE_MAGIC */
320 uint16_t di_mode; /* mode and type of file */
321 uint8_t di_version; /* inode version */
322 uint8_t di_format; /* format of di_c data */
323 uint16_t di_onlink; /* old number of links to file */
324 uint32_t di_uid; /* owner's user id */
325 uint32_t di_gid; /* owner's group id */
326 uint32_t di_nlink; /* number of links to file */
327 uint16_t di_projid_lo; /* lower part of owner's project id */
328 uint16_t di_projid_hi; /* higher part owner's project id */
329 uint8_t di_pad[6]; /* unused, zeroed space */
330 uint16_t di_flushiter; /* incremented on flush */
331 xfs_timestamp_t di_atime; /* time last accessed */
332 xfs_timestamp_t di_mtime; /* time last modified */
333 xfs_timestamp_t di_ctime; /* time created/inode modified */
334 uint64_t di_size; /* number of bytes in file */
335 uint64_t di_nblocks; /* # of direct & btree blocks used */
336 uint32_t di_extsize; /* basic/minimum extent size for file */
337 uint32_t di_nextents; /* number of extents in data fork */
338 uint16_t di_anextents; /* number of extents in attribute fork*/
339 uint8_t di_forkoff; /* attr fork offs, <<3 for 64b align */
340 int8_t di_aformat; /* format of attr fork's data */
341 uint32_t di_dmevmask; /* DMIG event mask */
342 uint16_t di_dmstate; /* DMIG state info */
343 uint16_t di_flags; /* random flags, XFS_DIFLAG_... */
344 uint32_t di_gen; /* generation number */
346 /* di_next_unlinked is the only non-core field in the old dinode */
347 uint32_t di_next_unlinked;/* agi unlinked list ptr */
348 uint8_t di_literal_area[1];
349 } __attribute__((packed)) xfs_dinode_t;
351 struct xfs_inode {
352 xfs_agblock_t i_agblock;
353 block_t i_ino_blk;
354 uint64_t i_block_offset;
355 uint64_t i_offset;
356 uint32_t i_cur_extent;
359 typedef struct { uint8_t i[8]; } __attribute__((__packed__)) xfs_dir2_ino8_t;
360 typedef struct { uint8_t i[4]; } __attribute__((__packed__)) xfs_dir2_ino4_t;
362 typedef union {
363 xfs_dir2_ino8_t i8;
364 xfs_dir2_ino4_t i4;
365 } __attribute__((__packed__)) xfs_dir2_inou_t;
367 typedef struct { uint8_t i[2]; } __attribute__((__packed__)) xfs_dir2_sf_off_t;
369 typedef struct xfs_dir2_sf_hdr {
370 uint8_t count; /* count of entries */
371 uint8_t i8count; /* count of 8-byte inode #s */
372 xfs_dir2_inou_t parent; /* parent dir inode number */
373 } __attribute__((__packed__)) xfs_dir2_sf_hdr_t;
375 typedef struct xfs_dir2_sf_entry {
376 uint8_t namelen; /* actual name length */
377 xfs_dir2_sf_off_t offset; /* saved offset */
378 uint8_t name[1]; /* name, variable size */
379 xfs_dir2_inou_t inumber; /* inode number, var. offset */
380 } __attribute__((__packed__)) xfs_dir2_sf_entry_t;
382 typedef struct xfs_dir2_sf {
383 xfs_dir2_sf_hdr_t hdr; /* shortform header */
384 xfs_dir2_sf_entry_t list[1]; /* shortform entries */
385 } __attribute__((__packed__)) xfs_dir2_sf_t;
387 typedef xfs_ino_t xfs_intino_t;
389 static inline xfs_intino_t xfs_dir2_sf_get_inumber(xfs_dir2_sf_t *sfp,
390 xfs_dir2_inou_t *from)
392 return ((sfp)->hdr.i8count == 0 ? \
393 (xfs_intino_t)XFS_GET_DIR_INO4((from)->i4) : \
394 (xfs_intino_t)XFS_GET_DIR_INO8((from)->i8));
398 * DIR2 Data block structures.
400 * A pure data block looks like the following drawing on disk:
402 * +-------------------------------------------------+
403 * | xfs_dir2_data_hdr_t |
404 * +-------------------------------------------------+
405 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
406 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
407 * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
408 * | ... |
409 * +-------------------------------------------------+
410 * | unused space |
411 * +-------------------------------------------------+
413 * As all the entries are variable size structure the accessors below should
414 * be used to iterate over them.
416 * In addition to the pure data blocks for the data and node formats.
417 * most structures are also used for the combined data/freespace "block"
418 * format below.
420 #define XFS_DIR2_DATA_ALIGN_LOG 3
421 #define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
422 #define XFS_DIR2_DATA_FREE_TAG 0xffff
423 #define XFS_DIR2_DATA_FD_COUNT 3
426 * Directory address space divided into sections.
427 * spaces separated by 32GB.
429 #define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
431 typedef struct xfs_dir2_data_free {
432 uint16_t offset;
433 uint16_t length;
434 } __attribute__((__packed__)) xfs_dir2_data_free_t;
436 typedef struct xfs_dir2_data_hdr {
437 uint32_t magic;
438 xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
439 } __attribute__((__packed__)) xfs_dir2_data_hdr_t;
441 typedef struct xfs_dir2_data_entry {
442 uint64_t inumber; /* inode number */
443 uint8_t namelen; /* name length */
444 uint8_t name[]; /* name types, no null */
445 /* uint16_t tag; */ /* starting offset of us */
446 } __attribute__((__packed__)) xfs_dir2_data_entry_t;
448 typedef struct xfs_dir2_data_unused {
449 uint16_t freetag; /* XFS_DIR2_DATA_FREE_TAG */
450 uint16_t length; /* total free length */
451 /* variable offset */
452 /* uint16_t tag; */ /* starting offset of us */
453 } __attribute__((__packed__)) xfs_dir2_data_unused_t;
456 * rol32 - rotate a 32-bit value left
457 * @word: value to rotate
458 * @shift: bits to roll
460 static inline uint32_t rol32(uint32_t word, signed int shift)
462 return (word << shift) | (word >> (32 - shift));
465 #define roundup(x, y) ( \
467 const typeof(y) __y = y; \
468 (((x) + (__y - 1)) / __y) * __y; \
472 static inline int xfs_dir2_data_entsize(int n)
474 return (int)roundup(offsetof(struct xfs_dir2_data_entry, name[0]) + n +
475 (unsigned int)sizeof(uint16_t), XFS_DIR2_DATA_ALIGN);
478 static inline uint16_t *
479 xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry *dep)
481 return (uint16_t *)((char *)dep +
482 xfs_dir2_data_entsize(dep->namelen) - sizeof(uint16_t));
485 static inline uint16_t *
486 xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
488 return (uint16_t *)((char *)dup +
489 be16_to_cpu(dup->length) - sizeof(uint16_t));
492 typedef struct xfs_dir2_block_tail {
493 uint32_t count; /* count of leaf entries */
494 uint32_t stale; /* count of stale lf entries */
495 } __attribute__((__packed__)) xfs_dir2_block_tail_t;
497 static inline struct xfs_dir2_block_tail *
498 xfs_dir2_block_tail_p(struct xfs_fs_info *fs_info, struct xfs_dir2_data_hdr *hdr)
500 return ((struct xfs_dir2_block_tail *)
501 ((char *)hdr + fs_info->dirblksize)) - 1;
504 static inline uint32_t
505 xfs_dir2_db_to_da(struct fs_info *fs, uint32_t db)
507 return db << XFS_INFO(fs)->dirblklog;
510 static inline int64_t
511 xfs_dir2_dataptr_to_byte(uint32_t dp)
513 return (int64_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
516 static inline uint32_t
517 xfs_dir2_byte_to_db(struct fs_info *fs, int64_t by)
519 return (uint32_t)
520 (by >> (XFS_INFO(fs)->block_shift + XFS_INFO(fs)->dirblklog));
523 static inline uint32_t
524 xfs_dir2_dataptr_to_db(struct fs_info *fs, uint32_t dp)
526 return xfs_dir2_byte_to_db(fs, xfs_dir2_dataptr_to_byte(dp));
529 static inline unsigned int
530 xfs_dir2_byte_to_off(struct fs_info *fs, int64_t by)
532 return (unsigned int)(by &
533 (( 1 << (XFS_INFO(fs)->block_shift + XFS_INFO(fs)->dirblklog)) - 1));
536 static inline unsigned int
537 xfs_dir2_dataptr_to_off(struct fs_info *fs, uint32_t dp)
539 return xfs_dir2_byte_to_off(fs, xfs_dir2_dataptr_to_byte(dp));
542 #define XFS_DIR2_LEAF_SPACE 1
543 #define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
544 #define XFS_DIR2_LEAF_FIRSTDB(fs) \
545 xfs_dir2_byte_to_db(fs, XFS_DIR2_LEAF_OFFSET)
547 typedef struct xfs_da_blkinfo {
548 uint32_t forw;
549 uint32_t back;
550 uint16_t magic;
551 uint16_t pad;
552 } __attribute__((__packed__)) xfs_da_blkinfo_t;
554 typedef struct xfs_dir2_leaf_hdr {
555 xfs_da_blkinfo_t info;
556 uint16_t count;
557 uint16_t stale;
558 } __attribute__((__packed__)) xfs_dir2_leaf_hdr_t;
560 typedef struct xfs_dir2_leaf_entry {
561 uint32_t hashval; /* hash value of name */
562 uint32_t address; /* address of data entry */
563 } __attribute__((__packed__)) xfs_dir2_leaf_entry_t;
565 typedef struct xfs_dir2_leaf {
566 xfs_dir2_leaf_hdr_t hdr; /* leaf header */
567 xfs_dir2_leaf_entry_t ents[]; /* entries */
568 } __attribute__((__packed__)) xfs_dir2_leaf_t;
570 #define XFS_DA_NODE_MAGIC 0xfebe /* magic number: non-leaf blocks */
571 #define XFS_ATTR_LEAF_MAGIC 0xfbee /* magic number: attribute leaf blks */
572 #define XFS_DIR2_LEAF1_MAGIC 0xd2f1 /* magic number: v2 dirlf single blks */
573 #define XFS_DIR2_LEAFN_MAGIC 0xd2ff /* magic number: V2 dirlf multi blks */
575 static inline bool xfs_is_valid_magicnum(const xfs_sb_t *sb)
577 return sb->sb_magicnum == *(uint32_t *)XFS_SB_MAGIC;
580 static inline bool xfs_is_valid_agi(xfs_agi_t *agi)
582 return agi->agi_magicnum == *(uint32_t *)XFS_AGI_MAGIC;
585 #endif /* XFS_H_ */