xref: /OK3568_Linux_fs/kernel/Documentation/filesystems/ext4/directory.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun.. SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun
3*4882a593SmuzhiyunDirectory Entries
4*4882a593Smuzhiyun-----------------
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunIn an ext4 filesystem, a directory is more or less a flat file that maps
7*4882a593Smuzhiyunan arbitrary byte string (usually ASCII) to an inode number on the
8*4882a593Smuzhiyunfilesystem. There can be many directory entries across the filesystem
9*4882a593Smuzhiyunthat reference the same inode number--these are known as hard links, and
10*4882a593Smuzhiyunthat is why hard links cannot reference files on other filesystems. As
11*4882a593Smuzhiyunsuch, directory entries are found by reading the data block(s)
12*4882a593Smuzhiyunassociated with a directory file for the particular directory entry that
13*4882a593Smuzhiyunis desired.
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunLinear (Classic) Directories
16*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17*4882a593Smuzhiyun
18*4882a593SmuzhiyunBy default, each directory lists its entries in an “almost-linear”
19*4882a593Smuzhiyunarray. I write “almost” because it's not a linear array in the memory
20*4882a593Smuzhiyunsense because directory entries are not split across filesystem blocks.
21*4882a593SmuzhiyunTherefore, it is more accurate to say that a directory is a series of
22*4882a593Smuzhiyundata blocks and that each block contains a linear array of directory
23*4882a593Smuzhiyunentries. The end of each per-block array is signified by reaching the
24*4882a593Smuzhiyunend of the block; the last entry in the block has a record length that
25*4882a593Smuzhiyuntakes it all the way to the end of the block. The end of the entire
26*4882a593Smuzhiyundirectory is of course signified by reaching the end of the file. Unused
27*4882a593Smuzhiyundirectory entries are signified by inode = 0. By default the filesystem
28*4882a593Smuzhiyunuses ``struct ext4_dir_entry_2`` for directory entries unless the
29*4882a593Smuzhiyun“filetype” feature flag is not set, in which case it uses
30*4882a593Smuzhiyun``struct ext4_dir_entry``.
31*4882a593Smuzhiyun
32*4882a593SmuzhiyunThe original directory entry format is ``struct ext4_dir_entry``, which
33*4882a593Smuzhiyunis at most 263 bytes long, though on disk you'll need to reference
34*4882a593Smuzhiyun``dirent.rec_len`` to know for sure.
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun.. list-table::
37*4882a593Smuzhiyun   :widths: 8 8 24 40
38*4882a593Smuzhiyun   :header-rows: 1
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun   * - Offset
41*4882a593Smuzhiyun     - Size
42*4882a593Smuzhiyun     - Name
43*4882a593Smuzhiyun     - Description
44*4882a593Smuzhiyun   * - 0x0
45*4882a593Smuzhiyun     - \_\_le32
46*4882a593Smuzhiyun     - inode
47*4882a593Smuzhiyun     - Number of the inode that this directory entry points to.
48*4882a593Smuzhiyun   * - 0x4
49*4882a593Smuzhiyun     - \_\_le16
50*4882a593Smuzhiyun     - rec\_len
51*4882a593Smuzhiyun     - Length of this directory entry. Must be a multiple of 4.
52*4882a593Smuzhiyun   * - 0x6
53*4882a593Smuzhiyun     - \_\_le16
54*4882a593Smuzhiyun     - name\_len
55*4882a593Smuzhiyun     - Length of the file name.
56*4882a593Smuzhiyun   * - 0x8
57*4882a593Smuzhiyun     - char
58*4882a593Smuzhiyun     - name[EXT4\_NAME\_LEN]
59*4882a593Smuzhiyun     - File name.
60*4882a593Smuzhiyun
61*4882a593SmuzhiyunSince file names cannot be longer than 255 bytes, the new directory
62*4882a593Smuzhiyunentry format shortens the name\_len field and uses the space for a file
63*4882a593Smuzhiyuntype flag, probably to avoid having to load every inode during directory
64*4882a593Smuzhiyuntree traversal. This format is ``ext4_dir_entry_2``, which is at most
65*4882a593Smuzhiyun263 bytes long, though on disk you'll need to reference
66*4882a593Smuzhiyun``dirent.rec_len`` to know for sure.
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun.. list-table::
69*4882a593Smuzhiyun   :widths: 8 8 24 40
70*4882a593Smuzhiyun   :header-rows: 1
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun   * - Offset
73*4882a593Smuzhiyun     - Size
74*4882a593Smuzhiyun     - Name
75*4882a593Smuzhiyun     - Description
76*4882a593Smuzhiyun   * - 0x0
77*4882a593Smuzhiyun     - \_\_le32
78*4882a593Smuzhiyun     - inode
79*4882a593Smuzhiyun     - Number of the inode that this directory entry points to.
80*4882a593Smuzhiyun   * - 0x4
81*4882a593Smuzhiyun     - \_\_le16
82*4882a593Smuzhiyun     - rec\_len
83*4882a593Smuzhiyun     - Length of this directory entry.
84*4882a593Smuzhiyun   * - 0x6
85*4882a593Smuzhiyun     - \_\_u8
86*4882a593Smuzhiyun     - name\_len
87*4882a593Smuzhiyun     - Length of the file name.
88*4882a593Smuzhiyun   * - 0x7
89*4882a593Smuzhiyun     - \_\_u8
90*4882a593Smuzhiyun     - file\_type
91*4882a593Smuzhiyun     - File type code, see ftype_ table below.
92*4882a593Smuzhiyun   * - 0x8
93*4882a593Smuzhiyun     - char
94*4882a593Smuzhiyun     - name[EXT4\_NAME\_LEN]
95*4882a593Smuzhiyun     - File name.
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun.. _ftype:
98*4882a593Smuzhiyun
99*4882a593SmuzhiyunThe directory file type is one of the following values:
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun.. list-table::
102*4882a593Smuzhiyun   :widths: 16 64
103*4882a593Smuzhiyun   :header-rows: 1
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun   * - Value
106*4882a593Smuzhiyun     - Description
107*4882a593Smuzhiyun   * - 0x0
108*4882a593Smuzhiyun     - Unknown.
109*4882a593Smuzhiyun   * - 0x1
110*4882a593Smuzhiyun     - Regular file.
111*4882a593Smuzhiyun   * - 0x2
112*4882a593Smuzhiyun     - Directory.
113*4882a593Smuzhiyun   * - 0x3
114*4882a593Smuzhiyun     - Character device file.
115*4882a593Smuzhiyun   * - 0x4
116*4882a593Smuzhiyun     - Block device file.
117*4882a593Smuzhiyun   * - 0x5
118*4882a593Smuzhiyun     - FIFO.
119*4882a593Smuzhiyun   * - 0x6
120*4882a593Smuzhiyun     - Socket.
121*4882a593Smuzhiyun   * - 0x7
122*4882a593Smuzhiyun     - Symbolic link.
123*4882a593Smuzhiyun
124*4882a593SmuzhiyunTo support directories that are both encrypted and casefolded directories, we
125*4882a593Smuzhiyunmust also include hash information in the directory entry. We append
126*4882a593Smuzhiyun``ext4_extended_dir_entry_2`` to ``ext4_dir_entry_2`` except for the entries
127*4882a593Smuzhiyunfor dot and dotdot, which are kept the same. The structure follows immediately
128*4882a593Smuzhiyunafter ``name`` and is included in the size listed by ``rec_len`` If a directory
129*4882a593Smuzhiyunentry uses this extension, it may be up to 271 bytes.
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun.. list-table::
132*4882a593Smuzhiyun   :widths: 8 8 24 40
133*4882a593Smuzhiyun   :header-rows: 1
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun   * - Offset
136*4882a593Smuzhiyun     - Size
137*4882a593Smuzhiyun     - Name
138*4882a593Smuzhiyun     - Description
139*4882a593Smuzhiyun   * - 0x0
140*4882a593Smuzhiyun     - \_\_le32
141*4882a593Smuzhiyun     - hash
142*4882a593Smuzhiyun     - The hash of the directory name
143*4882a593Smuzhiyun   * - 0x4
144*4882a593Smuzhiyun     - \_\_le32
145*4882a593Smuzhiyun     - minor\_hash
146*4882a593Smuzhiyun     - The minor hash of the directory name
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun
149*4882a593SmuzhiyunIn order to add checksums to these classic directory blocks, a phony
150*4882a593Smuzhiyun``struct ext4_dir_entry`` is placed at the end of each leaf block to
151*4882a593Smuzhiyunhold the checksum. The directory entry is 12 bytes long. The inode
152*4882a593Smuzhiyunnumber and name\_len fields are set to zero to fool old software into
153*4882a593Smuzhiyunignoring an apparently empty directory entry, and the checksum is stored
154*4882a593Smuzhiyunin the place where the name normally goes. The structure is
155*4882a593Smuzhiyun``struct ext4_dir_entry_tail``:
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun.. list-table::
158*4882a593Smuzhiyun   :widths: 8 8 24 40
159*4882a593Smuzhiyun   :header-rows: 1
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun   * - Offset
162*4882a593Smuzhiyun     - Size
163*4882a593Smuzhiyun     - Name
164*4882a593Smuzhiyun     - Description
165*4882a593Smuzhiyun   * - 0x0
166*4882a593Smuzhiyun     - \_\_le32
167*4882a593Smuzhiyun     - det\_reserved\_zero1
168*4882a593Smuzhiyun     - Inode number, which must be zero.
169*4882a593Smuzhiyun   * - 0x4
170*4882a593Smuzhiyun     - \_\_le16
171*4882a593Smuzhiyun     - det\_rec\_len
172*4882a593Smuzhiyun     - Length of this directory entry, which must be 12.
173*4882a593Smuzhiyun   * - 0x6
174*4882a593Smuzhiyun     - \_\_u8
175*4882a593Smuzhiyun     - det\_reserved\_zero2
176*4882a593Smuzhiyun     - Length of the file name, which must be zero.
177*4882a593Smuzhiyun   * - 0x7
178*4882a593Smuzhiyun     - \_\_u8
179*4882a593Smuzhiyun     - det\_reserved\_ft
180*4882a593Smuzhiyun     - File type, which must be 0xDE.
181*4882a593Smuzhiyun   * - 0x8
182*4882a593Smuzhiyun     - \_\_le32
183*4882a593Smuzhiyun     - det\_checksum
184*4882a593Smuzhiyun     - Directory leaf block checksum.
185*4882a593Smuzhiyun
186*4882a593SmuzhiyunThe leaf directory block checksum is calculated against the FS UUID, the
187*4882a593Smuzhiyundirectory's inode number, the directory's inode generation number, and
188*4882a593Smuzhiyunthe entire directory entry block up to (but not including) the fake
189*4882a593Smuzhiyundirectory entry.
190*4882a593Smuzhiyun
191*4882a593SmuzhiyunHash Tree Directories
192*4882a593Smuzhiyun~~~~~~~~~~~~~~~~~~~~~
193*4882a593Smuzhiyun
194*4882a593SmuzhiyunA linear array of directory entries isn't great for performance, so a
195*4882a593Smuzhiyunnew feature was added to ext3 to provide a faster (but peculiar)
196*4882a593Smuzhiyunbalanced tree keyed off a hash of the directory entry name. If the
197*4882a593SmuzhiyunEXT4\_INDEX\_FL (0x1000) flag is set in the inode, this directory uses a
198*4882a593Smuzhiyunhashed btree (htree) to organize and find directory entries. For
199*4882a593Smuzhiyunbackwards read-only compatibility with ext2, this tree is actually
200*4882a593Smuzhiyunhidden inside the directory file, masquerading as “empty” directory data
201*4882a593Smuzhiyunblocks! It was stated previously that the end of the linear directory
202*4882a593Smuzhiyunentry table was signified with an entry pointing to inode 0; this is
203*4882a593Smuzhiyun(ab)used to fool the old linear-scan algorithm into thinking that the
204*4882a593Smuzhiyunrest of the directory block is empty so that it moves on.
205*4882a593Smuzhiyun
206*4882a593SmuzhiyunThe root of the tree always lives in the first data block of the
207*4882a593Smuzhiyundirectory. By ext2 custom, the '.' and '..' entries must appear at the
208*4882a593Smuzhiyunbeginning of this first block, so they are put here as two
209*4882a593Smuzhiyun``struct ext4_dir_entry_2``\ s and not stored in the tree. The rest of
210*4882a593Smuzhiyunthe root node contains metadata about the tree and finally a hash->block
211*4882a593Smuzhiyunmap to find nodes that are lower in the htree. If
212*4882a593Smuzhiyun``dx_root.info.indirect_levels`` is non-zero then the htree has two
213*4882a593Smuzhiyunlevels; the data block pointed to by the root node's map is an interior
214*4882a593Smuzhiyunnode, which is indexed by a minor hash. Interior nodes in this tree
215*4882a593Smuzhiyuncontains a zeroed out ``struct ext4_dir_entry_2`` followed by a
216*4882a593Smuzhiyunminor\_hash->block map to find leafe nodes. Leaf nodes contain a linear
217*4882a593Smuzhiyunarray of all ``struct ext4_dir_entry_2``; all of these entries
218*4882a593Smuzhiyun(presumably) hash to the same value. If there is an overflow, the
219*4882a593Smuzhiyunentries simply overflow into the next leaf node, and the
220*4882a593Smuzhiyunleast-significant bit of the hash (in the interior node map) that gets
221*4882a593Smuzhiyunus to this next leaf node is set.
222*4882a593Smuzhiyun
223*4882a593SmuzhiyunTo traverse the directory as a htree, the code calculates the hash of
224*4882a593Smuzhiyunthe desired file name and uses it to find the corresponding block
225*4882a593Smuzhiyunnumber. If the tree is flat, the block is a linear array of directory
226*4882a593Smuzhiyunentries that can be searched; otherwise, the minor hash of the file name
227*4882a593Smuzhiyunis computed and used against this second block to find the corresponding
228*4882a593Smuzhiyunthird block number. That third block number will be a linear array of
229*4882a593Smuzhiyundirectory entries.
230*4882a593Smuzhiyun
231*4882a593SmuzhiyunTo traverse the directory as a linear array (such as the old code does),
232*4882a593Smuzhiyunthe code simply reads every data block in the directory. The blocks used
233*4882a593Smuzhiyunfor the htree will appear to have no entries (aside from '.' and '..')
234*4882a593Smuzhiyunand so only the leaf nodes will appear to have any interesting content.
235*4882a593Smuzhiyun
236*4882a593SmuzhiyunThe root of the htree is in ``struct dx_root``, which is the full length
237*4882a593Smuzhiyunof a data block:
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun.. list-table::
240*4882a593Smuzhiyun   :widths: 8 8 24 40
241*4882a593Smuzhiyun   :header-rows: 1
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun   * - Offset
244*4882a593Smuzhiyun     - Type
245*4882a593Smuzhiyun     - Name
246*4882a593Smuzhiyun     - Description
247*4882a593Smuzhiyun   * - 0x0
248*4882a593Smuzhiyun     - \_\_le32
249*4882a593Smuzhiyun     - dot.inode
250*4882a593Smuzhiyun     - inode number of this directory.
251*4882a593Smuzhiyun   * - 0x4
252*4882a593Smuzhiyun     - \_\_le16
253*4882a593Smuzhiyun     - dot.rec\_len
254*4882a593Smuzhiyun     - Length of this record, 12.
255*4882a593Smuzhiyun   * - 0x6
256*4882a593Smuzhiyun     - u8
257*4882a593Smuzhiyun     - dot.name\_len
258*4882a593Smuzhiyun     - Length of the name, 1.
259*4882a593Smuzhiyun   * - 0x7
260*4882a593Smuzhiyun     - u8
261*4882a593Smuzhiyun     - dot.file\_type
262*4882a593Smuzhiyun     - File type of this entry, 0x2 (directory) (if the feature flag is set).
263*4882a593Smuzhiyun   * - 0x8
264*4882a593Smuzhiyun     - char
265*4882a593Smuzhiyun     - dot.name[4]
266*4882a593Smuzhiyun     - “.\\0\\0\\0”
267*4882a593Smuzhiyun   * - 0xC
268*4882a593Smuzhiyun     - \_\_le32
269*4882a593Smuzhiyun     - dotdot.inode
270*4882a593Smuzhiyun     - inode number of parent directory.
271*4882a593Smuzhiyun   * - 0x10
272*4882a593Smuzhiyun     - \_\_le16
273*4882a593Smuzhiyun     - dotdot.rec\_len
274*4882a593Smuzhiyun     - block\_size - 12. The record length is long enough to cover all htree
275*4882a593Smuzhiyun       data.
276*4882a593Smuzhiyun   * - 0x12
277*4882a593Smuzhiyun     - u8
278*4882a593Smuzhiyun     - dotdot.name\_len
279*4882a593Smuzhiyun     - Length of the name, 2.
280*4882a593Smuzhiyun   * - 0x13
281*4882a593Smuzhiyun     - u8
282*4882a593Smuzhiyun     - dotdot.file\_type
283*4882a593Smuzhiyun     - File type of this entry, 0x2 (directory) (if the feature flag is set).
284*4882a593Smuzhiyun   * - 0x14
285*4882a593Smuzhiyun     - char
286*4882a593Smuzhiyun     - dotdot\_name[4]
287*4882a593Smuzhiyun     - “..\\0\\0”
288*4882a593Smuzhiyun   * - 0x18
289*4882a593Smuzhiyun     - \_\_le32
290*4882a593Smuzhiyun     - struct dx\_root\_info.reserved\_zero
291*4882a593Smuzhiyun     - Zero.
292*4882a593Smuzhiyun   * - 0x1C
293*4882a593Smuzhiyun     - u8
294*4882a593Smuzhiyun     - struct dx\_root\_info.hash\_version
295*4882a593Smuzhiyun     - Hash type, see dirhash_ table below.
296*4882a593Smuzhiyun   * - 0x1D
297*4882a593Smuzhiyun     - u8
298*4882a593Smuzhiyun     - struct dx\_root\_info.info\_length
299*4882a593Smuzhiyun     - Length of the tree information, 0x8.
300*4882a593Smuzhiyun   * - 0x1E
301*4882a593Smuzhiyun     - u8
302*4882a593Smuzhiyun     - struct dx\_root\_info.indirect\_levels
303*4882a593Smuzhiyun     - Depth of the htree. Cannot be larger than 3 if the INCOMPAT\_LARGEDIR
304*4882a593Smuzhiyun       feature is set; cannot be larger than 2 otherwise.
305*4882a593Smuzhiyun   * - 0x1F
306*4882a593Smuzhiyun     - u8
307*4882a593Smuzhiyun     - struct dx\_root\_info.unused\_flags
308*4882a593Smuzhiyun     -
309*4882a593Smuzhiyun   * - 0x20
310*4882a593Smuzhiyun     - \_\_le16
311*4882a593Smuzhiyun     - limit
312*4882a593Smuzhiyun     - Maximum number of dx\_entries that can follow this header, plus 1 for
313*4882a593Smuzhiyun       the header itself.
314*4882a593Smuzhiyun   * - 0x22
315*4882a593Smuzhiyun     - \_\_le16
316*4882a593Smuzhiyun     - count
317*4882a593Smuzhiyun     - Actual number of dx\_entries that follow this header, plus 1 for the
318*4882a593Smuzhiyun       header itself.
319*4882a593Smuzhiyun   * - 0x24
320*4882a593Smuzhiyun     - \_\_le32
321*4882a593Smuzhiyun     - block
322*4882a593Smuzhiyun     - The block number (within the directory file) that goes with hash=0.
323*4882a593Smuzhiyun   * - 0x28
324*4882a593Smuzhiyun     - struct dx\_entry
325*4882a593Smuzhiyun     - entries[0]
326*4882a593Smuzhiyun     - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block.
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun.. _dirhash:
329*4882a593Smuzhiyun
330*4882a593SmuzhiyunThe directory hash is one of the following values:
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun.. list-table::
333*4882a593Smuzhiyun   :widths: 16 64
334*4882a593Smuzhiyun   :header-rows: 1
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun   * - Value
337*4882a593Smuzhiyun     - Description
338*4882a593Smuzhiyun   * - 0x0
339*4882a593Smuzhiyun     - Legacy.
340*4882a593Smuzhiyun   * - 0x1
341*4882a593Smuzhiyun     - Half MD4.
342*4882a593Smuzhiyun   * - 0x2
343*4882a593Smuzhiyun     - Tea.
344*4882a593Smuzhiyun   * - 0x3
345*4882a593Smuzhiyun     - Legacy, unsigned.
346*4882a593Smuzhiyun   * - 0x4
347*4882a593Smuzhiyun     - Half MD4, unsigned.
348*4882a593Smuzhiyun   * - 0x5
349*4882a593Smuzhiyun     - Tea, unsigned.
350*4882a593Smuzhiyun   * - 0x6
351*4882a593Smuzhiyun     - Siphash.
352*4882a593Smuzhiyun
353*4882a593SmuzhiyunInterior nodes of an htree are recorded as ``struct dx_node``, which is
354*4882a593Smuzhiyunalso the full length of a data block:
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun.. list-table::
357*4882a593Smuzhiyun   :widths: 8 8 24 40
358*4882a593Smuzhiyun   :header-rows: 1
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun   * - Offset
361*4882a593Smuzhiyun     - Type
362*4882a593Smuzhiyun     - Name
363*4882a593Smuzhiyun     - Description
364*4882a593Smuzhiyun   * - 0x0
365*4882a593Smuzhiyun     - \_\_le32
366*4882a593Smuzhiyun     - fake.inode
367*4882a593Smuzhiyun     - Zero, to make it look like this entry is not in use.
368*4882a593Smuzhiyun   * - 0x4
369*4882a593Smuzhiyun     - \_\_le16
370*4882a593Smuzhiyun     - fake.rec\_len
371*4882a593Smuzhiyun     - The size of the block, in order to hide all of the dx\_node data.
372*4882a593Smuzhiyun   * - 0x6
373*4882a593Smuzhiyun     - u8
374*4882a593Smuzhiyun     - name\_len
375*4882a593Smuzhiyun     - Zero. There is no name for this “unused” directory entry.
376*4882a593Smuzhiyun   * - 0x7
377*4882a593Smuzhiyun     - u8
378*4882a593Smuzhiyun     - file\_type
379*4882a593Smuzhiyun     - Zero. There is no file type for this “unused” directory entry.
380*4882a593Smuzhiyun   * - 0x8
381*4882a593Smuzhiyun     - \_\_le16
382*4882a593Smuzhiyun     - limit
383*4882a593Smuzhiyun     - Maximum number of dx\_entries that can follow this header, plus 1 for
384*4882a593Smuzhiyun       the header itself.
385*4882a593Smuzhiyun   * - 0xA
386*4882a593Smuzhiyun     - \_\_le16
387*4882a593Smuzhiyun     - count
388*4882a593Smuzhiyun     - Actual number of dx\_entries that follow this header, plus 1 for the
389*4882a593Smuzhiyun       header itself.
390*4882a593Smuzhiyun   * - 0xE
391*4882a593Smuzhiyun     - \_\_le32
392*4882a593Smuzhiyun     - block
393*4882a593Smuzhiyun     - The block number (within the directory file) that goes with the lowest
394*4882a593Smuzhiyun       hash value of this block. This value is stored in the parent block.
395*4882a593Smuzhiyun   * - 0x12
396*4882a593Smuzhiyun     - struct dx\_entry
397*4882a593Smuzhiyun     - entries[0]
398*4882a593Smuzhiyun     - As many 8-byte ``struct dx_entry`` as fits in the rest of the data block.
399*4882a593Smuzhiyun
400*4882a593SmuzhiyunThe hash maps that exist in both ``struct dx_root`` and
401*4882a593Smuzhiyun``struct dx_node`` are recorded as ``struct dx_entry``, which is 8 bytes
402*4882a593Smuzhiyunlong:
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun.. list-table::
405*4882a593Smuzhiyun   :widths: 8 8 24 40
406*4882a593Smuzhiyun   :header-rows: 1
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun   * - Offset
409*4882a593Smuzhiyun     - Type
410*4882a593Smuzhiyun     - Name
411*4882a593Smuzhiyun     - Description
412*4882a593Smuzhiyun   * - 0x0
413*4882a593Smuzhiyun     - \_\_le32
414*4882a593Smuzhiyun     - hash
415*4882a593Smuzhiyun     - Hash code.
416*4882a593Smuzhiyun   * - 0x4
417*4882a593Smuzhiyun     - \_\_le32
418*4882a593Smuzhiyun     - block
419*4882a593Smuzhiyun     - Block number (within the directory file, not filesystem blocks) of the
420*4882a593Smuzhiyun       next node in the htree.
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun(If you think this is all quite clever and peculiar, so does the
423*4882a593Smuzhiyunauthor.)
424*4882a593Smuzhiyun
425*4882a593SmuzhiyunIf metadata checksums are enabled, the last 8 bytes of the directory
426*4882a593Smuzhiyunblock (precisely the length of one dx\_entry) are used to store a
427*4882a593Smuzhiyun``struct dx_tail``, which contains the checksum. The ``limit`` and
428*4882a593Smuzhiyun``count`` entries in the dx\_root/dx\_node structures are adjusted as
429*4882a593Smuzhiyunnecessary to fit the dx\_tail into the block. If there is no space for
430*4882a593Smuzhiyunthe dx\_tail, the user is notified to run e2fsck -D to rebuild the
431*4882a593Smuzhiyundirectory index (which will ensure that there's space for the checksum.
432*4882a593SmuzhiyunThe dx\_tail structure is 8 bytes long and looks like this:
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun.. list-table::
435*4882a593Smuzhiyun   :widths: 8 8 24 40
436*4882a593Smuzhiyun   :header-rows: 1
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun   * - Offset
439*4882a593Smuzhiyun     - Type
440*4882a593Smuzhiyun     - Name
441*4882a593Smuzhiyun     - Description
442*4882a593Smuzhiyun   * - 0x0
443*4882a593Smuzhiyun     - u32
444*4882a593Smuzhiyun     - dt\_reserved
445*4882a593Smuzhiyun     - Zero.
446*4882a593Smuzhiyun   * - 0x4
447*4882a593Smuzhiyun     - \_\_le32
448*4882a593Smuzhiyun     - dt\_checksum
449*4882a593Smuzhiyun     - Checksum of the htree directory block.
450*4882a593Smuzhiyun
451*4882a593SmuzhiyunThe checksum is calculated against the FS UUID, the htree index header
452*4882a593Smuzhiyun(dx\_root or dx\_node), all of the htree indices (dx\_entry) that are in
453*4882a593Smuzhiyunuse, and the tail block (dx\_tail).
454