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.
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
30 #include "xfs_types.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);
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) | \
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) | \
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 */
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 */
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.
200 uint32_t blocksize
; /* Filesystem block size */
201 uint8_t block_shift
; /* Filesystem block size in bits */
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. */
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
{
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
;
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
{
269 } __attribute__((__packed__
)) xfs_bmbt_rec_t
;
272 * Possible extent states.
277 XFS_EXT_DMAPI_OFFLINE
,
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
)
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
{
308 } __attribute__((__packed__
)) xfs_timestamp_t
;
310 typedef enum xfs_dinode_fmt
{
312 XFS_DINODE_FMT_LOCAL
,
313 XFS_DINODE_FMT_EXTENTS
,
314 XFS_DINODE_FMT_BTREE
,
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
;
352 xfs_agblock_t i_agblock
;
354 uint64_t i_block_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
;
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 |
409 * +-------------------------------------------------+
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"
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
{
434 } __attribute__((__packed__
)) xfs_dir2_data_free_t
;
436 typedef struct xfs_dir2_data_hdr
{
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
)
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
{
552 } __attribute__((__packed__
)) xfs_da_blkinfo_t
;
554 typedef struct xfs_dir2_leaf_hdr
{
555 xfs_da_blkinfo_t info
;
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
;