xref: /openbmc/linux/Documentation/filesystems/ext4/directory.rst (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
18a98ec7cSDarrick J. Wong.. SPDX-License-Identifier: GPL-2.0
28a98ec7cSDarrick J. Wong
38a98ec7cSDarrick J. WongDirectory Entries
48a98ec7cSDarrick J. Wong-----------------
58a98ec7cSDarrick J. Wong
68a98ec7cSDarrick J. WongIn an ext4 filesystem, a directory is more or less a flat file that maps
78a98ec7cSDarrick J. Wongan arbitrary byte string (usually ASCII) to an inode number on the
88a98ec7cSDarrick J. Wongfilesystem. There can be many directory entries across the filesystem
98a98ec7cSDarrick J. Wongthat reference the same inode number--these are known as hard links, and
108a98ec7cSDarrick J. Wongthat is why hard links cannot reference files on other filesystems. As
118a98ec7cSDarrick J. Wongsuch, directory entries are found by reading the data block(s)
128a98ec7cSDarrick J. Wongassociated with a directory file for the particular directory entry that
138a98ec7cSDarrick J. Wongis desired.
148a98ec7cSDarrick J. Wong
158a98ec7cSDarrick J. WongLinear (Classic) Directories
168a98ec7cSDarrick J. Wong~~~~~~~~~~~~~~~~~~~~~~~~~~~~
178a98ec7cSDarrick J. Wong
188a98ec7cSDarrick J. WongBy default, each directory lists its entries in an “almost-linear”
198a98ec7cSDarrick J. Wongarray. I write “almost” because it's not a linear array in the memory
208a98ec7cSDarrick J. Wongsense because directory entries are not split across filesystem blocks.
218a98ec7cSDarrick J. WongTherefore, it is more accurate to say that a directory is a series of
228a98ec7cSDarrick J. Wongdata blocks and that each block contains a linear array of directory
238a98ec7cSDarrick J. Wongentries. The end of each per-block array is signified by reaching the
248a98ec7cSDarrick J. Wongend of the block; the last entry in the block has a record length that
258a98ec7cSDarrick J. Wongtakes it all the way to the end of the block. The end of the entire
268a98ec7cSDarrick J. Wongdirectory is of course signified by reaching the end of the file. Unused
278a98ec7cSDarrick J. Wongdirectory entries are signified by inode = 0. By default the filesystem
288a98ec7cSDarrick J. Wonguses ``struct ext4_dir_entry_2`` for directory entries unless the
298a98ec7cSDarrick J. Wong“filetype” feature flag is not set, in which case it uses
308a98ec7cSDarrick J. Wong``struct ext4_dir_entry``.
318a98ec7cSDarrick J. Wong
328a98ec7cSDarrick J. WongThe original directory entry format is ``struct ext4_dir_entry``, which
338a98ec7cSDarrick J. Wongis at most 263 bytes long, though on disk you'll need to reference
348a98ec7cSDarrick J. Wong``dirent.rec_len`` to know for sure.
358a98ec7cSDarrick J. Wong
368a98ec7cSDarrick J. Wong.. list-table::
378a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
388a98ec7cSDarrick J. Wong   :header-rows: 1
398a98ec7cSDarrick J. Wong
408a98ec7cSDarrick J. Wong   * - Offset
418a98ec7cSDarrick J. Wong     - Size
428a98ec7cSDarrick J. Wong     - Name
438a98ec7cSDarrick J. Wong     - Description
448a98ec7cSDarrick J. Wong   * - 0x0
45*3103084aSWang Jianjian     - __le32
468a98ec7cSDarrick J. Wong     - inode
478a98ec7cSDarrick J. Wong     - Number of the inode that this directory entry points to.
488a98ec7cSDarrick J. Wong   * - 0x4
49*3103084aSWang Jianjian     - __le16
50*3103084aSWang Jianjian     - rec_len
518a98ec7cSDarrick J. Wong     - Length of this directory entry. Must be a multiple of 4.
528a98ec7cSDarrick J. Wong   * - 0x6
53*3103084aSWang Jianjian     - __le16
54*3103084aSWang Jianjian     - name_len
558a98ec7cSDarrick J. Wong     - Length of the file name.
568a98ec7cSDarrick J. Wong   * - 0x8
578a98ec7cSDarrick J. Wong     - char
58*3103084aSWang Jianjian     - name[EXT4_NAME_LEN]
598a98ec7cSDarrick J. Wong     - File name.
608a98ec7cSDarrick J. Wong
618a98ec7cSDarrick J. WongSince file names cannot be longer than 255 bytes, the new directory
62*3103084aSWang Jianjianentry format shortens the name_len field and uses the space for a file
638a98ec7cSDarrick J. Wongtype flag, probably to avoid having to load every inode during directory
648a98ec7cSDarrick J. Wongtree traversal. This format is ``ext4_dir_entry_2``, which is at most
658a98ec7cSDarrick J. Wong263 bytes long, though on disk you'll need to reference
668a98ec7cSDarrick J. Wong``dirent.rec_len`` to know for sure.
678a98ec7cSDarrick J. Wong
688a98ec7cSDarrick J. Wong.. list-table::
698a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
708a98ec7cSDarrick J. Wong   :header-rows: 1
718a98ec7cSDarrick J. Wong
728a98ec7cSDarrick J. Wong   * - Offset
738a98ec7cSDarrick J. Wong     - Size
748a98ec7cSDarrick J. Wong     - Name
758a98ec7cSDarrick J. Wong     - Description
768a98ec7cSDarrick J. Wong   * - 0x0
77*3103084aSWang Jianjian     - __le32
788a98ec7cSDarrick J. Wong     - inode
798a98ec7cSDarrick J. Wong     - Number of the inode that this directory entry points to.
808a98ec7cSDarrick J. Wong   * - 0x4
81*3103084aSWang Jianjian     - __le16
82*3103084aSWang Jianjian     - rec_len
838a98ec7cSDarrick J. Wong     - Length of this directory entry.
848a98ec7cSDarrick J. Wong   * - 0x6
85*3103084aSWang Jianjian     - __u8
86*3103084aSWang Jianjian     - name_len
878a98ec7cSDarrick J. Wong     - Length of the file name.
888a98ec7cSDarrick J. Wong   * - 0x7
89*3103084aSWang Jianjian     - __u8
90*3103084aSWang Jianjian     - file_type
918a98ec7cSDarrick J. Wong     - File type code, see ftype_ table below.
928a98ec7cSDarrick J. Wong   * - 0x8
938a98ec7cSDarrick J. Wong     - char
94*3103084aSWang Jianjian     - name[EXT4_NAME_LEN]
958a98ec7cSDarrick J. Wong     - File name.
968a98ec7cSDarrick J. Wong
978a98ec7cSDarrick J. Wong.. _ftype:
988a98ec7cSDarrick J. Wong
998a98ec7cSDarrick J. WongThe directory file type is one of the following values:
1008a98ec7cSDarrick J. Wong
1018a98ec7cSDarrick J. Wong.. list-table::
1028a98ec7cSDarrick J. Wong   :widths: 16 64
1038a98ec7cSDarrick J. Wong   :header-rows: 1
1048a98ec7cSDarrick J. Wong
1058a98ec7cSDarrick J. Wong   * - Value
1068a98ec7cSDarrick J. Wong     - Description
1078a98ec7cSDarrick J. Wong   * - 0x0
1088a98ec7cSDarrick J. Wong     - Unknown.
1098a98ec7cSDarrick J. Wong   * - 0x1
1108a98ec7cSDarrick J. Wong     - Regular file.
1118a98ec7cSDarrick J. Wong   * - 0x2
1128a98ec7cSDarrick J. Wong     - Directory.
1138a98ec7cSDarrick J. Wong   * - 0x3
1148a98ec7cSDarrick J. Wong     - Character device file.
1158a98ec7cSDarrick J. Wong   * - 0x4
1168a98ec7cSDarrick J. Wong     - Block device file.
1178a98ec7cSDarrick J. Wong   * - 0x5
1188a98ec7cSDarrick J. Wong     - FIFO.
1198a98ec7cSDarrick J. Wong   * - 0x6
1208a98ec7cSDarrick J. Wong     - Socket.
1218a98ec7cSDarrick J. Wong   * - 0x7
1228a98ec7cSDarrick J. Wong     - Symbolic link.
1238a98ec7cSDarrick J. Wong
124471fbbeaSDaniel RosenbergTo support directories that are both encrypted and casefolded directories, we
125471fbbeaSDaniel Rosenbergmust also include hash information in the directory entry. We append
126471fbbeaSDaniel Rosenberg``ext4_extended_dir_entry_2`` to ``ext4_dir_entry_2`` except for the entries
127471fbbeaSDaniel Rosenbergfor dot and dotdot, which are kept the same. The structure follows immediately
128471fbbeaSDaniel Rosenbergafter ``name`` and is included in the size listed by ``rec_len`` If a directory
129471fbbeaSDaniel Rosenbergentry uses this extension, it may be up to 271 bytes.
130471fbbeaSDaniel Rosenberg
131471fbbeaSDaniel Rosenberg.. list-table::
132471fbbeaSDaniel Rosenberg   :widths: 8 8 24 40
133471fbbeaSDaniel Rosenberg   :header-rows: 1
134471fbbeaSDaniel Rosenberg
135471fbbeaSDaniel Rosenberg   * - Offset
136471fbbeaSDaniel Rosenberg     - Size
137471fbbeaSDaniel Rosenberg     - Name
138471fbbeaSDaniel Rosenberg     - Description
139471fbbeaSDaniel Rosenberg   * - 0x0
140*3103084aSWang Jianjian     - __le32
141471fbbeaSDaniel Rosenberg     - hash
142471fbbeaSDaniel Rosenberg     - The hash of the directory name
143471fbbeaSDaniel Rosenberg   * - 0x4
144*3103084aSWang Jianjian     - __le32
145*3103084aSWang Jianjian     - minor_hash
146471fbbeaSDaniel Rosenberg     - The minor hash of the directory name
147471fbbeaSDaniel Rosenberg
148471fbbeaSDaniel Rosenberg
1498a98ec7cSDarrick J. WongIn order to add checksums to these classic directory blocks, a phony
1508a98ec7cSDarrick J. Wong``struct ext4_dir_entry`` is placed at the end of each leaf block to
1518a98ec7cSDarrick J. Wonghold the checksum. The directory entry is 12 bytes long. The inode
152*3103084aSWang Jianjiannumber and name_len fields are set to zero to fool old software into
1538a98ec7cSDarrick J. Wongignoring an apparently empty directory entry, and the checksum is stored
1548a98ec7cSDarrick J. Wongin the place where the name normally goes. The structure is
1558a98ec7cSDarrick J. Wong``struct ext4_dir_entry_tail``:
1568a98ec7cSDarrick J. Wong
1578a98ec7cSDarrick J. Wong.. list-table::
1588a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
1598a98ec7cSDarrick J. Wong   :header-rows: 1
1608a98ec7cSDarrick J. Wong
1618a98ec7cSDarrick J. Wong   * - Offset
1628a98ec7cSDarrick J. Wong     - Size
1638a98ec7cSDarrick J. Wong     - Name
1648a98ec7cSDarrick J. Wong     - Description
1658a98ec7cSDarrick J. Wong   * - 0x0
166*3103084aSWang Jianjian     - __le32
167*3103084aSWang Jianjian     - det_reserved_zero1
1688a98ec7cSDarrick J. Wong     - Inode number, which must be zero.
1698a98ec7cSDarrick J. Wong   * - 0x4
170*3103084aSWang Jianjian     - __le16
171*3103084aSWang Jianjian     - det_rec_len
1728a98ec7cSDarrick J. Wong     - Length of this directory entry, which must be 12.
1738a98ec7cSDarrick J. Wong   * - 0x6
174*3103084aSWang Jianjian     - __u8
175*3103084aSWang Jianjian     - det_reserved_zero2
1768a98ec7cSDarrick J. Wong     - Length of the file name, which must be zero.
1778a98ec7cSDarrick J. Wong   * - 0x7
178*3103084aSWang Jianjian     - __u8
179*3103084aSWang Jianjian     - det_reserved_ft
1808a98ec7cSDarrick J. Wong     - File type, which must be 0xDE.
1818a98ec7cSDarrick J. Wong   * - 0x8
182*3103084aSWang Jianjian     - __le32
183*3103084aSWang Jianjian     - det_checksum
1848a98ec7cSDarrick J. Wong     - Directory leaf block checksum.
1858a98ec7cSDarrick J. Wong
1868a98ec7cSDarrick J. WongThe leaf directory block checksum is calculated against the FS UUID, the
1878a98ec7cSDarrick J. Wongdirectory's inode number, the directory's inode generation number, and
1888a98ec7cSDarrick J. Wongthe entire directory entry block up to (but not including) the fake
1898a98ec7cSDarrick J. Wongdirectory entry.
1908a98ec7cSDarrick J. Wong
1918a98ec7cSDarrick J. WongHash Tree Directories
1928a98ec7cSDarrick J. Wong~~~~~~~~~~~~~~~~~~~~~
1938a98ec7cSDarrick J. Wong
1948a98ec7cSDarrick J. WongA linear array of directory entries isn't great for performance, so a
1958a98ec7cSDarrick J. Wongnew feature was added to ext3 to provide a faster (but peculiar)
1968a98ec7cSDarrick J. Wongbalanced tree keyed off a hash of the directory entry name. If the
197*3103084aSWang JianjianEXT4_INDEX_FL (0x1000) flag is set in the inode, this directory uses a
1988a98ec7cSDarrick J. Wonghashed btree (htree) to organize and find directory entries. For
1998a98ec7cSDarrick J. Wongbackwards read-only compatibility with ext2, this tree is actually
2008a98ec7cSDarrick J. Wonghidden inside the directory file, masquerading as “empty” directory data
2018a98ec7cSDarrick J. Wongblocks! It was stated previously that the end of the linear directory
2028a98ec7cSDarrick J. Wongentry table was signified with an entry pointing to inode 0; this is
2038a98ec7cSDarrick J. Wong(ab)used to fool the old linear-scan algorithm into thinking that the
2048a98ec7cSDarrick J. Wongrest of the directory block is empty so that it moves on.
2058a98ec7cSDarrick J. Wong
2068a98ec7cSDarrick J. WongThe root of the tree always lives in the first data block of the
2078a98ec7cSDarrick J. Wongdirectory. By ext2 custom, the '.' and '..' entries must appear at the
2088a98ec7cSDarrick J. Wongbeginning of this first block, so they are put here as two
209*3103084aSWang Jianjian``struct ext4_dir_entry_2`` s and not stored in the tree. The rest of
2108a98ec7cSDarrick J. Wongthe root node contains metadata about the tree and finally a hash->block
2118a98ec7cSDarrick J. Wongmap to find nodes that are lower in the htree. If
2128a98ec7cSDarrick J. Wong``dx_root.info.indirect_levels`` is non-zero then the htree has two
2138a98ec7cSDarrick J. Wonglevels; the data block pointed to by the root node's map is an interior
2148a98ec7cSDarrick J. Wongnode, which is indexed by a minor hash. Interior nodes in this tree
2158a98ec7cSDarrick J. Wongcontains a zeroed out ``struct ext4_dir_entry_2`` followed by a
216*3103084aSWang Jianjianminor_hash->block map to find leafe nodes. Leaf nodes contain a linear
2178a98ec7cSDarrick J. Wongarray of all ``struct ext4_dir_entry_2``; all of these entries
2188a98ec7cSDarrick J. Wong(presumably) hash to the same value. If there is an overflow, the
2198a98ec7cSDarrick J. Wongentries simply overflow into the next leaf node, and the
2208a98ec7cSDarrick J. Wongleast-significant bit of the hash (in the interior node map) that gets
2218a98ec7cSDarrick J. Wongus to this next leaf node is set.
2228a98ec7cSDarrick J. Wong
2238a98ec7cSDarrick J. WongTo traverse the directory as a htree, the code calculates the hash of
2248a98ec7cSDarrick J. Wongthe desired file name and uses it to find the corresponding block
2258a98ec7cSDarrick J. Wongnumber. If the tree is flat, the block is a linear array of directory
2268a98ec7cSDarrick J. Wongentries that can be searched; otherwise, the minor hash of the file name
2278a98ec7cSDarrick J. Wongis computed and used against this second block to find the corresponding
2288a98ec7cSDarrick J. Wongthird block number. That third block number will be a linear array of
2298a98ec7cSDarrick J. Wongdirectory entries.
2308a98ec7cSDarrick J. Wong
2318a98ec7cSDarrick J. WongTo traverse the directory as a linear array (such as the old code does),
2328a98ec7cSDarrick J. Wongthe code simply reads every data block in the directory. The blocks used
2338a98ec7cSDarrick J. Wongfor the htree will appear to have no entries (aside from '.' and '..')
2348a98ec7cSDarrick J. Wongand so only the leaf nodes will appear to have any interesting content.
2358a98ec7cSDarrick J. Wong
2368a98ec7cSDarrick J. WongThe root of the htree is in ``struct dx_root``, which is the full length
2378a98ec7cSDarrick J. Wongof a data block:
2388a98ec7cSDarrick J. Wong
2398a98ec7cSDarrick J. Wong.. list-table::
2408a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
2418a98ec7cSDarrick J. Wong   :header-rows: 1
2428a98ec7cSDarrick J. Wong
2438a98ec7cSDarrick J. Wong   * - Offset
2448a98ec7cSDarrick J. Wong     - Type
2458a98ec7cSDarrick J. Wong     - Name
2468a98ec7cSDarrick J. Wong     - Description
2478a98ec7cSDarrick J. Wong   * - 0x0
248*3103084aSWang Jianjian     - __le32
2498a98ec7cSDarrick J. Wong     - dot.inode
2508a98ec7cSDarrick J. Wong     - inode number of this directory.
2518a98ec7cSDarrick J. Wong   * - 0x4
252*3103084aSWang Jianjian     - __le16
253*3103084aSWang Jianjian     - dot.rec_len
2548a98ec7cSDarrick J. Wong     - Length of this record, 12.
2558a98ec7cSDarrick J. Wong   * - 0x6
2568a98ec7cSDarrick J. Wong     - u8
257*3103084aSWang Jianjian     - dot.name_len
2588a98ec7cSDarrick J. Wong     - Length of the name, 1.
2598a98ec7cSDarrick J. Wong   * - 0x7
2608a98ec7cSDarrick J. Wong     - u8
261*3103084aSWang Jianjian     - dot.file_type
2628a98ec7cSDarrick J. Wong     - File type of this entry, 0x2 (directory) (if the feature flag is set).
2638a98ec7cSDarrick J. Wong   * - 0x8
2648a98ec7cSDarrick J. Wong     - char
2658a98ec7cSDarrick J. Wong     - dot.name[4]
266*3103084aSWang Jianjian     - “.\0\0\0”
2678a98ec7cSDarrick J. Wong   * - 0xC
268*3103084aSWang Jianjian     - __le32
2698a98ec7cSDarrick J. Wong     - dotdot.inode
2708a98ec7cSDarrick J. Wong     - inode number of parent directory.
2718a98ec7cSDarrick J. Wong   * - 0x10
272*3103084aSWang Jianjian     - __le16
273*3103084aSWang Jianjian     - dotdot.rec_len
274*3103084aSWang Jianjian     - block_size - 12. The record length is long enough to cover all htree
2758a98ec7cSDarrick J. Wong       data.
2768a98ec7cSDarrick J. Wong   * - 0x12
2778a98ec7cSDarrick J. Wong     - u8
278*3103084aSWang Jianjian     - dotdot.name_len
2798a98ec7cSDarrick J. Wong     - Length of the name, 2.
2808a98ec7cSDarrick J. Wong   * - 0x13
2818a98ec7cSDarrick J. Wong     - u8
282*3103084aSWang Jianjian     - dotdot.file_type
2838a98ec7cSDarrick J. Wong     - File type of this entry, 0x2 (directory) (if the feature flag is set).
2848a98ec7cSDarrick J. Wong   * - 0x14
2858a98ec7cSDarrick J. Wong     - char
286*3103084aSWang Jianjian     - dotdot_name[4]
287*3103084aSWang Jianjian     - “..\0\0”
2888a98ec7cSDarrick J. Wong   * - 0x18
289*3103084aSWang Jianjian     - __le32
290*3103084aSWang Jianjian     - struct dx_root_info.reserved_zero
2918a98ec7cSDarrick J. Wong     - Zero.
2928a98ec7cSDarrick J. Wong   * - 0x1C
2938a98ec7cSDarrick J. Wong     - u8
294*3103084aSWang Jianjian     - struct dx_root_info.hash_version
2958a98ec7cSDarrick J. Wong     - Hash type, see dirhash_ table below.
2968a98ec7cSDarrick J. Wong   * - 0x1D
2978a98ec7cSDarrick J. Wong     - u8
298*3103084aSWang Jianjian     - struct dx_root_info.info_length
2998a98ec7cSDarrick J. Wong     - Length of the tree information, 0x8.
3008a98ec7cSDarrick J. Wong   * - 0x1E
3018a98ec7cSDarrick J. Wong     - u8
302*3103084aSWang Jianjian     - struct dx_root_info.indirect_levels
303*3103084aSWang Jianjian     - Depth of the htree. Cannot be larger than 3 if the INCOMPAT_LARGEDIR
3048a98ec7cSDarrick J. Wong       feature is set; cannot be larger than 2 otherwise.
3058a98ec7cSDarrick J. Wong   * - 0x1F
3068a98ec7cSDarrick J. Wong     - u8
307*3103084aSWang Jianjian     - struct dx_root_info.unused_flags
3088a98ec7cSDarrick J. Wong     -
3098a98ec7cSDarrick J. Wong   * - 0x20
310*3103084aSWang Jianjian     - __le16
3118a98ec7cSDarrick J. Wong     - limit
312*3103084aSWang Jianjian     - Maximum number of dx_entries that can follow this header, plus 1 for
3138a98ec7cSDarrick J. Wong       the header itself.
3148a98ec7cSDarrick J. Wong   * - 0x22
315*3103084aSWang Jianjian     - __le16
3168a98ec7cSDarrick J. Wong     - count
317*3103084aSWang Jianjian     - Actual number of dx_entries that follow this header, plus 1 for the
3188a98ec7cSDarrick J. Wong       header itself.
3198a98ec7cSDarrick J. Wong   * - 0x24
320*3103084aSWang Jianjian     - __le32
3218a98ec7cSDarrick J. Wong     - block
3228a98ec7cSDarrick J. Wong     - The block number (within the directory file) that goes with hash=0.
3238a98ec7cSDarrick J. Wong   * - 0x28
324*3103084aSWang Jianjian     - struct dx_entry
3258a98ec7cSDarrick J. Wong     - entries[0]
3268a98ec7cSDarrick J. Wong     - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block.
3278a98ec7cSDarrick J. Wong
3288a98ec7cSDarrick J. Wong.. _dirhash:
3298a98ec7cSDarrick J. Wong
3308a98ec7cSDarrick J. WongThe directory hash is one of the following values:
3318a98ec7cSDarrick J. Wong
3328a98ec7cSDarrick J. Wong.. list-table::
3338a98ec7cSDarrick J. Wong   :widths: 16 64
3348a98ec7cSDarrick J. Wong   :header-rows: 1
3358a98ec7cSDarrick J. Wong
3368a98ec7cSDarrick J. Wong   * - Value
3378a98ec7cSDarrick J. Wong     - Description
3388a98ec7cSDarrick J. Wong   * - 0x0
3398a98ec7cSDarrick J. Wong     - Legacy.
3408a98ec7cSDarrick J. Wong   * - 0x1
3418a98ec7cSDarrick J. Wong     - Half MD4.
3428a98ec7cSDarrick J. Wong   * - 0x2
3438a98ec7cSDarrick J. Wong     - Tea.
3448a98ec7cSDarrick J. Wong   * - 0x3
3458a98ec7cSDarrick J. Wong     - Legacy, unsigned.
3468a98ec7cSDarrick J. Wong   * - 0x4
3478a98ec7cSDarrick J. Wong     - Half MD4, unsigned.
3488a98ec7cSDarrick J. Wong   * - 0x5
3498a98ec7cSDarrick J. Wong     - Tea, unsigned.
350471fbbeaSDaniel Rosenberg   * - 0x6
351471fbbeaSDaniel Rosenberg     - Siphash.
3528a98ec7cSDarrick J. Wong
3538a98ec7cSDarrick J. WongInterior nodes of an htree are recorded as ``struct dx_node``, which is
3548a98ec7cSDarrick J. Wongalso the full length of a data block:
3558a98ec7cSDarrick J. Wong
3568a98ec7cSDarrick J. Wong.. list-table::
3578a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
3588a98ec7cSDarrick J. Wong   :header-rows: 1
3598a98ec7cSDarrick J. Wong
3608a98ec7cSDarrick J. Wong   * - Offset
3618a98ec7cSDarrick J. Wong     - Type
3628a98ec7cSDarrick J. Wong     - Name
3638a98ec7cSDarrick J. Wong     - Description
3648a98ec7cSDarrick J. Wong   * - 0x0
365*3103084aSWang Jianjian     - __le32
3668a98ec7cSDarrick J. Wong     - fake.inode
3678a98ec7cSDarrick J. Wong     - Zero, to make it look like this entry is not in use.
3688a98ec7cSDarrick J. Wong   * - 0x4
369*3103084aSWang Jianjian     - __le16
370*3103084aSWang Jianjian     - fake.rec_len
371*3103084aSWang Jianjian     - The size of the block, in order to hide all of the dx_node data.
3728a98ec7cSDarrick J. Wong   * - 0x6
3738a98ec7cSDarrick J. Wong     - u8
374*3103084aSWang Jianjian     - name_len
3758a98ec7cSDarrick J. Wong     - Zero. There is no name for this “unused” directory entry.
3768a98ec7cSDarrick J. Wong   * - 0x7
3778a98ec7cSDarrick J. Wong     - u8
378*3103084aSWang Jianjian     - file_type
3798a98ec7cSDarrick J. Wong     - Zero. There is no file type for this “unused” directory entry.
3808a98ec7cSDarrick J. Wong   * - 0x8
381*3103084aSWang Jianjian     - __le16
3828a98ec7cSDarrick J. Wong     - limit
383*3103084aSWang Jianjian     - Maximum number of dx_entries that can follow this header, plus 1 for
3848a98ec7cSDarrick J. Wong       the header itself.
3858a98ec7cSDarrick J. Wong   * - 0xA
386*3103084aSWang Jianjian     - __le16
3878a98ec7cSDarrick J. Wong     - count
388*3103084aSWang Jianjian     - Actual number of dx_entries that follow this header, plus 1 for the
3898a98ec7cSDarrick J. Wong       header itself.
3908a98ec7cSDarrick J. Wong   * - 0xE
391*3103084aSWang Jianjian     - __le32
3928a98ec7cSDarrick J. Wong     - block
3938a98ec7cSDarrick J. Wong     - The block number (within the directory file) that goes with the lowest
3948a98ec7cSDarrick J. Wong       hash value of this block. This value is stored in the parent block.
3958a98ec7cSDarrick J. Wong   * - 0x12
396*3103084aSWang Jianjian     - struct dx_entry
3978a98ec7cSDarrick J. Wong     - entries[0]
3988a98ec7cSDarrick J. Wong     - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block.
3998a98ec7cSDarrick J. Wong
4008a98ec7cSDarrick J. WongThe hash maps that exist in both ``struct dx_root`` and
4018a98ec7cSDarrick J. Wong``struct dx_node`` are recorded as ``struct dx_entry``, which is 8 bytes
4028a98ec7cSDarrick J. Wonglong:
4038a98ec7cSDarrick J. Wong
4048a98ec7cSDarrick J. Wong.. list-table::
4058a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
4068a98ec7cSDarrick J. Wong   :header-rows: 1
4078a98ec7cSDarrick J. Wong
4088a98ec7cSDarrick J. Wong   * - Offset
4098a98ec7cSDarrick J. Wong     - Type
4108a98ec7cSDarrick J. Wong     - Name
4118a98ec7cSDarrick J. Wong     - Description
4128a98ec7cSDarrick J. Wong   * - 0x0
413*3103084aSWang Jianjian     - __le32
4148a98ec7cSDarrick J. Wong     - hash
4158a98ec7cSDarrick J. Wong     - Hash code.
4168a98ec7cSDarrick J. Wong   * - 0x4
417*3103084aSWang Jianjian     - __le32
4188a98ec7cSDarrick J. Wong     - block
4198a98ec7cSDarrick J. Wong     - Block number (within the directory file, not filesystem blocks) of the
4208a98ec7cSDarrick J. Wong       next node in the htree.
4218a98ec7cSDarrick J. Wong
4228a98ec7cSDarrick J. Wong(If you think this is all quite clever and peculiar, so does the
4238a98ec7cSDarrick J. Wongauthor.)
4248a98ec7cSDarrick J. Wong
4258a98ec7cSDarrick J. WongIf metadata checksums are enabled, the last 8 bytes of the directory
426*3103084aSWang Jianjianblock (precisely the length of one dx_entry) are used to store a
4278a98ec7cSDarrick J. Wong``struct dx_tail``, which contains the checksum. The ``limit`` and
428*3103084aSWang Jianjian``count`` entries in the dx_root/dx_node structures are adjusted as
429*3103084aSWang Jianjiannecessary to fit the dx_tail into the block. If there is no space for
430*3103084aSWang Jianjianthe dx_tail, the user is notified to run e2fsck -D to rebuild the
4318a98ec7cSDarrick J. Wongdirectory index (which will ensure that there's space for the checksum.
432*3103084aSWang JianjianThe dx_tail structure is 8 bytes long and looks like this:
4338a98ec7cSDarrick J. Wong
4348a98ec7cSDarrick J. Wong.. list-table::
4358a98ec7cSDarrick J. Wong   :widths: 8 8 24 40
4368a98ec7cSDarrick J. Wong   :header-rows: 1
4378a98ec7cSDarrick J. Wong
4388a98ec7cSDarrick J. Wong   * - Offset
4398a98ec7cSDarrick J. Wong     - Type
4408a98ec7cSDarrick J. Wong     - Name
4418a98ec7cSDarrick J. Wong     - Description
4428a98ec7cSDarrick J. Wong   * - 0x0
4438a98ec7cSDarrick J. Wong     - u32
444*3103084aSWang Jianjian     - dt_reserved
4458a98ec7cSDarrick J. Wong     - Zero.
4468a98ec7cSDarrick J. Wong   * - 0x4
447*3103084aSWang Jianjian     - __le32
448*3103084aSWang Jianjian     - dt_checksum
4498a98ec7cSDarrick J. Wong     - Checksum of the htree directory block.
4508a98ec7cSDarrick J. Wong
4518a98ec7cSDarrick J. WongThe checksum is calculated against the FS UUID, the htree index header
452*3103084aSWang Jianjian(dx_root or dx_node), all of the htree indices (dx_entry) that are in
453*3103084aSWang Jianjianuse, and the tail block (dx_tail).
454