xfs_dir2_format.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. /*
  2. * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
  3. * All Rights Reserved.
  4. *
  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.
  8. *
  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.
  13. *
  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
  17. */
  18. #ifndef __XFS_DIR2_FORMAT_H__
  19. #define __XFS_DIR2_FORMAT_H__
  20. /*
  21. * Directory version 2.
  22. *
  23. * There are 4 possible formats:
  24. * - shortform - embedded into the inode
  25. * - single block - data with embedded leaf at the end
  26. * - multiple data blocks, single leaf+freeindex block
  27. * - data blocks, node and leaf blocks (btree), freeindex blocks
  28. *
  29. * Note: many node blocks structures and constants are shared with the attr
  30. * code and defined in xfs_da_btree.h.
  31. */
  32. #define XFS_DIR2_BLOCK_MAGIC 0x58443242 /* XD2B: single block dirs */
  33. #define XFS_DIR2_DATA_MAGIC 0x58443244 /* XD2D: multiblock dirs */
  34. #define XFS_DIR2_FREE_MAGIC 0x58443246 /* XD2F: free index blocks */
  35. /*
  36. * Byte offset in data block and shortform entry.
  37. */
  38. typedef __uint16_t xfs_dir2_data_off_t;
  39. #define NULLDATAOFF 0xffffU
  40. typedef uint xfs_dir2_data_aoff_t; /* argument form */
  41. /*
  42. * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
  43. * Only need 16 bits, this is the byte offset into the single block form.
  44. */
  45. typedef struct { __uint8_t i[2]; } __arch_pack xfs_dir2_sf_off_t;
  46. /*
  47. * Offset in data space of a data entry.
  48. */
  49. typedef __uint32_t xfs_dir2_dataptr_t;
  50. #define XFS_DIR2_MAX_DATAPTR ((xfs_dir2_dataptr_t)0xffffffff)
  51. #define XFS_DIR2_NULL_DATAPTR ((xfs_dir2_dataptr_t)0)
  52. /*
  53. * Byte offset in a directory.
  54. */
  55. typedef xfs_off_t xfs_dir2_off_t;
  56. /*
  57. * Directory block number (logical dirblk in file)
  58. */
  59. typedef __uint32_t xfs_dir2_db_t;
  60. /*
  61. * Inode number stored as 8 8-bit values.
  62. */
  63. typedef struct { __uint8_t i[8]; } xfs_dir2_ino8_t;
  64. /*
  65. * Inode number stored as 4 8-bit values.
  66. * Works a lot of the time, when all the inode numbers in a directory
  67. * fit in 32 bits.
  68. */
  69. typedef struct { __uint8_t i[4]; } xfs_dir2_ino4_t;
  70. typedef union {
  71. xfs_dir2_ino8_t i8;
  72. xfs_dir2_ino4_t i4;
  73. } xfs_dir2_inou_t;
  74. #define XFS_DIR2_MAX_SHORT_INUM ((xfs_ino_t)0xffffffffULL)
  75. /*
  76. * Directory layout when stored internal to an inode.
  77. *
  78. * Small directories are packed as tightly as possible so as to fit into the
  79. * literal area of the inode. These "shortform" directories consist of a
  80. * single xfs_dir2_sf_hdr header followed by zero or more xfs_dir2_sf_entry
  81. * structures. Due the different inode number storage size and the variable
  82. * length name field in the xfs_dir2_sf_entry all these structure are
  83. * variable length, and the accessors in this file should be used to iterate
  84. * over them.
  85. */
  86. typedef struct xfs_dir2_sf_hdr {
  87. __uint8_t count; /* count of entries */
  88. __uint8_t i8count; /* count of 8-byte inode #s */
  89. xfs_dir2_inou_t parent; /* parent dir inode number */
  90. } __arch_pack xfs_dir2_sf_hdr_t;
  91. typedef struct xfs_dir2_sf_entry {
  92. __u8 namelen; /* actual name length */
  93. xfs_dir2_sf_off_t offset; /* saved offset */
  94. __u8 name[]; /* name, variable size */
  95. /*
  96. * A xfs_dir2_ino8_t or xfs_dir2_ino4_t follows here, at a
  97. * variable offset after the name.
  98. */
  99. } __arch_pack xfs_dir2_sf_entry_t;
  100. static inline int xfs_dir2_sf_hdr_size(int i8count)
  101. {
  102. return sizeof(struct xfs_dir2_sf_hdr) -
  103. (i8count == 0) *
  104. (sizeof(xfs_dir2_ino8_t) - sizeof(xfs_dir2_ino4_t));
  105. }
  106. static inline xfs_dir2_data_aoff_t
  107. xfs_dir2_sf_get_offset(xfs_dir2_sf_entry_t *sfep)
  108. {
  109. return get_unaligned_be16(&sfep->offset.i);
  110. }
  111. static inline void
  112. xfs_dir2_sf_put_offset(xfs_dir2_sf_entry_t *sfep, xfs_dir2_data_aoff_t off)
  113. {
  114. put_unaligned_be16(off, &sfep->offset.i);
  115. }
  116. static inline int
  117. xfs_dir2_sf_entsize(struct xfs_dir2_sf_hdr *hdr, int len)
  118. {
  119. return sizeof(struct xfs_dir2_sf_entry) + /* namelen + offset */
  120. len + /* name */
  121. (hdr->i8count ? /* ino */
  122. sizeof(xfs_dir2_ino8_t) :
  123. sizeof(xfs_dir2_ino4_t));
  124. }
  125. static inline struct xfs_dir2_sf_entry *
  126. xfs_dir2_sf_firstentry(struct xfs_dir2_sf_hdr *hdr)
  127. {
  128. return (struct xfs_dir2_sf_entry *)
  129. ((char *)hdr + xfs_dir2_sf_hdr_size(hdr->i8count));
  130. }
  131. static inline struct xfs_dir2_sf_entry *
  132. xfs_dir2_sf_nextentry(struct xfs_dir2_sf_hdr *hdr,
  133. struct xfs_dir2_sf_entry *sfep)
  134. {
  135. return (struct xfs_dir2_sf_entry *)
  136. ((char *)sfep + xfs_dir2_sf_entsize(hdr, sfep->namelen));
  137. }
  138. /*
  139. * Data block structures.
  140. *
  141. * A pure data block looks like the following drawing on disk:
  142. *
  143. * +-------------------------------------------------+
  144. * | xfs_dir2_data_hdr_t |
  145. * +-------------------------------------------------+
  146. * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
  147. * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
  148. * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
  149. * | ... |
  150. * +-------------------------------------------------+
  151. * | unused space |
  152. * +-------------------------------------------------+
  153. *
  154. * As all the entries are variable size structures the accessors below should
  155. * be used to iterate over them.
  156. *
  157. * In addition to the pure data blocks for the data and node formats,
  158. * most structures are also used for the combined data/freespace "block"
  159. * format below.
  160. */
  161. #define XFS_DIR2_DATA_ALIGN_LOG 3 /* i.e., 8 bytes */
  162. #define XFS_DIR2_DATA_ALIGN (1 << XFS_DIR2_DATA_ALIGN_LOG)
  163. #define XFS_DIR2_DATA_FREE_TAG 0xffff
  164. #define XFS_DIR2_DATA_FD_COUNT 3
  165. /*
  166. * Directory address space divided into sections,
  167. * spaces separated by 32GB.
  168. */
  169. #define XFS_DIR2_SPACE_SIZE (1ULL << (32 + XFS_DIR2_DATA_ALIGN_LOG))
  170. #define XFS_DIR2_DATA_SPACE 0
  171. #define XFS_DIR2_DATA_OFFSET (XFS_DIR2_DATA_SPACE * XFS_DIR2_SPACE_SIZE)
  172. #define XFS_DIR2_DATA_FIRSTDB(mp) \
  173. xfs_dir2_byte_to_db(mp, XFS_DIR2_DATA_OFFSET)
  174. /*
  175. * Offsets of . and .. in data space (always block 0)
  176. */
  177. #define XFS_DIR2_DATA_DOT_OFFSET \
  178. ((xfs_dir2_data_aoff_t)sizeof(struct xfs_dir2_data_hdr))
  179. #define XFS_DIR2_DATA_DOTDOT_OFFSET \
  180. (XFS_DIR2_DATA_DOT_OFFSET + xfs_dir2_data_entsize(1))
  181. #define XFS_DIR2_DATA_FIRST_OFFSET \
  182. (XFS_DIR2_DATA_DOTDOT_OFFSET + xfs_dir2_data_entsize(2))
  183. /*
  184. * Describe a free area in the data block.
  185. *
  186. * The freespace will be formatted as a xfs_dir2_data_unused_t.
  187. */
  188. typedef struct xfs_dir2_data_free {
  189. __be16 offset; /* start of freespace */
  190. __be16 length; /* length of freespace */
  191. } xfs_dir2_data_free_t;
  192. /*
  193. * Header for the data blocks.
  194. *
  195. * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
  196. */
  197. typedef struct xfs_dir2_data_hdr {
  198. __be32 magic; /* XFS_DIR2_DATA_MAGIC or */
  199. /* XFS_DIR2_BLOCK_MAGIC */
  200. xfs_dir2_data_free_t bestfree[XFS_DIR2_DATA_FD_COUNT];
  201. } xfs_dir2_data_hdr_t;
  202. /*
  203. * Active entry in a data block.
  204. *
  205. * Aligned to 8 bytes. After the variable length name field there is a
  206. * 2 byte tag field, which can be accessed using xfs_dir2_data_entry_tag_p.
  207. */
  208. typedef struct xfs_dir2_data_entry {
  209. __be64 inumber; /* inode number */
  210. __u8 namelen; /* name length */
  211. __u8 name[]; /* name bytes, no null */
  212. /* __be16 tag; */ /* starting offset of us */
  213. } xfs_dir2_data_entry_t;
  214. /*
  215. * Unused entry in a data block.
  216. *
  217. * Aligned to 8 bytes. Tag appears as the last 2 bytes and must be accessed
  218. * using xfs_dir2_data_unused_tag_p.
  219. */
  220. typedef struct xfs_dir2_data_unused {
  221. __be16 freetag; /* XFS_DIR2_DATA_FREE_TAG */
  222. __be16 length; /* total free length */
  223. /* variable offset */
  224. __be16 tag; /* starting offset of us */
  225. } xfs_dir2_data_unused_t;
  226. /*
  227. * Size of a data entry.
  228. */
  229. static inline int xfs_dir2_data_entsize(int n)
  230. {
  231. return (int)roundup(offsetof(struct xfs_dir2_data_entry, name[0]) + n +
  232. (uint)sizeof(xfs_dir2_data_off_t), XFS_DIR2_DATA_ALIGN);
  233. }
  234. /*
  235. * Pointer to an entry's tag word.
  236. */
  237. static inline __be16 *
  238. xfs_dir2_data_entry_tag_p(struct xfs_dir2_data_entry *dep)
  239. {
  240. return (__be16 *)((char *)dep +
  241. xfs_dir2_data_entsize(dep->namelen) - sizeof(__be16));
  242. }
  243. /*
  244. * Pointer to a freespace's tag word.
  245. */
  246. static inline __be16 *
  247. xfs_dir2_data_unused_tag_p(struct xfs_dir2_data_unused *dup)
  248. {
  249. return (__be16 *)((char *)dup +
  250. be16_to_cpu(dup->length) - sizeof(__be16));
  251. }
  252. /*
  253. * Leaf block structures.
  254. *
  255. * A pure leaf block looks like the following drawing on disk:
  256. *
  257. * +---------------------------+
  258. * | xfs_dir2_leaf_hdr_t |
  259. * +---------------------------+
  260. * | xfs_dir2_leaf_entry_t |
  261. * | xfs_dir2_leaf_entry_t |
  262. * | xfs_dir2_leaf_entry_t |
  263. * | xfs_dir2_leaf_entry_t |
  264. * | ... |
  265. * +---------------------------+
  266. * | xfs_dir2_data_off_t |
  267. * | xfs_dir2_data_off_t |
  268. * | xfs_dir2_data_off_t |
  269. * | ... |
  270. * +---------------------------+
  271. * | xfs_dir2_leaf_tail_t |
  272. * +---------------------------+
  273. *
  274. * The xfs_dir2_data_off_t members (bests) and tail are at the end of the block
  275. * for single-leaf (magic = XFS_DIR2_LEAF1_MAGIC) blocks only, but not present
  276. * for directories with separate leaf nodes and free space blocks
  277. * (magic = XFS_DIR2_LEAFN_MAGIC).
  278. *
  279. * As all the entries are variable size structures the accessors below should
  280. * be used to iterate over them.
  281. */
  282. /*
  283. * Offset of the leaf/node space. First block in this space
  284. * is the btree root.
  285. */
  286. #define XFS_DIR2_LEAF_SPACE 1
  287. #define XFS_DIR2_LEAF_OFFSET (XFS_DIR2_LEAF_SPACE * XFS_DIR2_SPACE_SIZE)
  288. #define XFS_DIR2_LEAF_FIRSTDB(mp) \
  289. xfs_dir2_byte_to_db(mp, XFS_DIR2_LEAF_OFFSET)
  290. /*
  291. * Leaf block header.
  292. */
  293. typedef struct xfs_dir2_leaf_hdr {
  294. xfs_da_blkinfo_t info; /* header for da routines */
  295. __be16 count; /* count of entries */
  296. __be16 stale; /* count of stale entries */
  297. } xfs_dir2_leaf_hdr_t;
  298. /*
  299. * Leaf block entry.
  300. */
  301. typedef struct xfs_dir2_leaf_entry {
  302. __be32 hashval; /* hash value of name */
  303. __be32 address; /* address of data entry */
  304. } xfs_dir2_leaf_entry_t;
  305. /*
  306. * Leaf block tail.
  307. */
  308. typedef struct xfs_dir2_leaf_tail {
  309. __be32 bestcount;
  310. } xfs_dir2_leaf_tail_t;
  311. /*
  312. * Leaf block.
  313. */
  314. typedef struct xfs_dir2_leaf {
  315. xfs_dir2_leaf_hdr_t hdr; /* leaf header */
  316. xfs_dir2_leaf_entry_t ents[]; /* entries */
  317. } xfs_dir2_leaf_t;
  318. /*
  319. * DB blocks here are logical directory block numbers, not filesystem blocks.
  320. */
  321. static inline int xfs_dir2_max_leaf_ents(struct xfs_mount *mp)
  322. {
  323. return (mp->m_dirblksize - (uint)sizeof(struct xfs_dir2_leaf_hdr)) /
  324. (uint)sizeof(struct xfs_dir2_leaf_entry);
  325. }
  326. /*
  327. * Get address of the bestcount field in the single-leaf block.
  328. */
  329. static inline struct xfs_dir2_leaf_tail *
  330. xfs_dir2_leaf_tail_p(struct xfs_mount *mp, struct xfs_dir2_leaf *lp)
  331. {
  332. return (struct xfs_dir2_leaf_tail *)
  333. ((char *)lp + mp->m_dirblksize -
  334. sizeof(struct xfs_dir2_leaf_tail));
  335. }
  336. /*
  337. * Get address of the bests array in the single-leaf block.
  338. */
  339. static inline __be16 *
  340. xfs_dir2_leaf_bests_p(struct xfs_dir2_leaf_tail *ltp)
  341. {
  342. return (__be16 *)ltp - be32_to_cpu(ltp->bestcount);
  343. }
  344. /*
  345. * Convert dataptr to byte in file space
  346. */
  347. static inline xfs_dir2_off_t
  348. xfs_dir2_dataptr_to_byte(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
  349. {
  350. return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
  351. }
  352. /*
  353. * Convert byte in file space to dataptr. It had better be aligned.
  354. */
  355. static inline xfs_dir2_dataptr_t
  356. xfs_dir2_byte_to_dataptr(struct xfs_mount *mp, xfs_dir2_off_t by)
  357. {
  358. return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
  359. }
  360. /*
  361. * Convert byte in space to (DB) block
  362. */
  363. static inline xfs_dir2_db_t
  364. xfs_dir2_byte_to_db(struct xfs_mount *mp, xfs_dir2_off_t by)
  365. {
  366. return (xfs_dir2_db_t)
  367. (by >> (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog));
  368. }
  369. /*
  370. * Convert dataptr to a block number
  371. */
  372. static inline xfs_dir2_db_t
  373. xfs_dir2_dataptr_to_db(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
  374. {
  375. return xfs_dir2_byte_to_db(mp, xfs_dir2_dataptr_to_byte(mp, dp));
  376. }
  377. /*
  378. * Convert byte in space to offset in a block
  379. */
  380. static inline xfs_dir2_data_aoff_t
  381. xfs_dir2_byte_to_off(struct xfs_mount *mp, xfs_dir2_off_t by)
  382. {
  383. return (xfs_dir2_data_aoff_t)(by &
  384. ((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) - 1));
  385. }
  386. /*
  387. * Convert dataptr to a byte offset in a block
  388. */
  389. static inline xfs_dir2_data_aoff_t
  390. xfs_dir2_dataptr_to_off(struct xfs_mount *mp, xfs_dir2_dataptr_t dp)
  391. {
  392. return xfs_dir2_byte_to_off(mp, xfs_dir2_dataptr_to_byte(mp, dp));
  393. }
  394. /*
  395. * Convert block and offset to byte in space
  396. */
  397. static inline xfs_dir2_off_t
  398. xfs_dir2_db_off_to_byte(struct xfs_mount *mp, xfs_dir2_db_t db,
  399. xfs_dir2_data_aoff_t o)
  400. {
  401. return ((xfs_dir2_off_t)db <<
  402. (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) + o;
  403. }
  404. /*
  405. * Convert block (DB) to block (dablk)
  406. */
  407. static inline xfs_dablk_t
  408. xfs_dir2_db_to_da(struct xfs_mount *mp, xfs_dir2_db_t db)
  409. {
  410. return (xfs_dablk_t)(db << mp->m_sb.sb_dirblklog);
  411. }
  412. /*
  413. * Convert byte in space to (DA) block
  414. */
  415. static inline xfs_dablk_t
  416. xfs_dir2_byte_to_da(struct xfs_mount *mp, xfs_dir2_off_t by)
  417. {
  418. return xfs_dir2_db_to_da(mp, xfs_dir2_byte_to_db(mp, by));
  419. }
  420. /*
  421. * Convert block and offset to dataptr
  422. */
  423. static inline xfs_dir2_dataptr_t
  424. xfs_dir2_db_off_to_dataptr(struct xfs_mount *mp, xfs_dir2_db_t db,
  425. xfs_dir2_data_aoff_t o)
  426. {
  427. return xfs_dir2_byte_to_dataptr(mp, xfs_dir2_db_off_to_byte(mp, db, o));
  428. }
  429. /*
  430. * Convert block (dablk) to block (DB)
  431. */
  432. static inline xfs_dir2_db_t
  433. xfs_dir2_da_to_db(struct xfs_mount *mp, xfs_dablk_t da)
  434. {
  435. return (xfs_dir2_db_t)(da >> mp->m_sb.sb_dirblklog);
  436. }
  437. /*
  438. * Convert block (dablk) to byte offset in space
  439. */
  440. static inline xfs_dir2_off_t
  441. xfs_dir2_da_to_byte(struct xfs_mount *mp, xfs_dablk_t da)
  442. {
  443. return xfs_dir2_db_off_to_byte(mp, xfs_dir2_da_to_db(mp, da), 0);
  444. }
  445. /*
  446. * Free space block defintions for the node format.
  447. */
  448. /*
  449. * Offset of the freespace index.
  450. */
  451. #define XFS_DIR2_FREE_SPACE 2
  452. #define XFS_DIR2_FREE_OFFSET (XFS_DIR2_FREE_SPACE * XFS_DIR2_SPACE_SIZE)
  453. #define XFS_DIR2_FREE_FIRSTDB(mp) \
  454. xfs_dir2_byte_to_db(mp, XFS_DIR2_FREE_OFFSET)
  455. typedef struct xfs_dir2_free_hdr {
  456. __be32 magic; /* XFS_DIR2_FREE_MAGIC */
  457. __be32 firstdb; /* db of first entry */
  458. __be32 nvalid; /* count of valid entries */
  459. __be32 nused; /* count of used entries */
  460. } xfs_dir2_free_hdr_t;
  461. typedef struct xfs_dir2_free {
  462. xfs_dir2_free_hdr_t hdr; /* block header */
  463. __be16 bests[]; /* best free counts */
  464. /* unused entries are -1 */
  465. } xfs_dir2_free_t;
  466. static inline int xfs_dir2_free_max_bests(struct xfs_mount *mp)
  467. {
  468. return (mp->m_dirblksize - sizeof(struct xfs_dir2_free_hdr)) /
  469. sizeof(xfs_dir2_data_off_t);
  470. }
  471. /*
  472. * Convert data space db to the corresponding free db.
  473. */
  474. static inline xfs_dir2_db_t
  475. xfs_dir2_db_to_fdb(struct xfs_mount *mp, xfs_dir2_db_t db)
  476. {
  477. return XFS_DIR2_FREE_FIRSTDB(mp) + db / xfs_dir2_free_max_bests(mp);
  478. }
  479. /*
  480. * Convert data space db to the corresponding index in a free db.
  481. */
  482. static inline int
  483. xfs_dir2_db_to_fdindex(struct xfs_mount *mp, xfs_dir2_db_t db)
  484. {
  485. return db % xfs_dir2_free_max_bests(mp);
  486. }
  487. /*
  488. * Single block format.
  489. *
  490. * The single block format looks like the following drawing on disk:
  491. *
  492. * +-------------------------------------------------+
  493. * | xfs_dir2_data_hdr_t |
  494. * +-------------------------------------------------+
  495. * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
  496. * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t |
  497. * | xfs_dir2_data_entry_t OR xfs_dir2_data_unused_t :
  498. * | ... |
  499. * +-------------------------------------------------+
  500. * | unused space |
  501. * +-------------------------------------------------+
  502. * | ... |
  503. * | xfs_dir2_leaf_entry_t |
  504. * | xfs_dir2_leaf_entry_t |
  505. * +-------------------------------------------------+
  506. * | xfs_dir2_block_tail_t |
  507. * +-------------------------------------------------+
  508. *
  509. * As all the entries are variable size structures the accessors below should
  510. * be used to iterate over them.
  511. */
  512. typedef struct xfs_dir2_block_tail {
  513. __be32 count; /* count of leaf entries */
  514. __be32 stale; /* count of stale lf entries */
  515. } xfs_dir2_block_tail_t;
  516. /*
  517. * Pointer to the leaf header embedded in a data block (1-block format)
  518. */
  519. static inline struct xfs_dir2_block_tail *
  520. xfs_dir2_block_tail_p(struct xfs_mount *mp, struct xfs_dir2_data_hdr *hdr)
  521. {
  522. return ((struct xfs_dir2_block_tail *)
  523. ((char *)hdr + mp->m_dirblksize)) - 1;
  524. }
  525. /*
  526. * Pointer to the leaf entries embedded in a data block (1-block format)
  527. */
  528. static inline struct xfs_dir2_leaf_entry *
  529. xfs_dir2_block_leaf_p(struct xfs_dir2_block_tail *btp)
  530. {
  531. return ((struct xfs_dir2_leaf_entry *)btp) - be32_to_cpu(btp->count);
  532. }
  533. #endif /* __XFS_DIR2_FORMAT_H__ */