← Documents Documentation/filesystems/ext4/ifork.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

The Contents of inode.i_block

`inode.i_block`의 심볼릭 링크, block map, extent tree, checksum, inline data 용도를 다룬 전문 번역입니다.

Source pathDocumentation/filesystems/ext4/ifork.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

ifork.rst:1-194

`inode.i_block`의 60바이트는 파일 종류에 따라 짧은 링크, block map, extent tree root 또는 inline data가 됩니다.

ext4 extent tree는 연속 블록을 하나의 entry로 압축하고 외부 tree block은 CRC32C tail로 보호합니다.

핵심 흐름
파일 종류와 inode flag 확인짧은 symlink 또는 inline data면 60바이트에 직접 저장일반 파일이면 extent root 또는 legacy block map 해석외부 extent block은 tail checksum 검증

문서의 주요 관계를 짧게 정리합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 The Contents of inode.i_block
4 ------------------------------
5
6 Depending on the type of file an inode describes, the 60 bytes of
7 storage in ``inode.i_block`` can be used in different ways. In general,
8 regular files and directories will use it for file block indexing
9 information, and special files will use it for special purposes.
10
11 Symbolic Links
12 ~~~~~~~~~~~~~~
13
14 The target of a symbolic link will be stored in this field if the target
15 string is less than 60 bytes long. Otherwise, either extents or block
16 maps will be used to allocate data blocks to store the link target.
17
18 Direct/Indirect Block Addressing
19 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20
21 In ext2/3, file block numbers were mapped to logical block numbers by
22 means of an (up to) three level 1-1 block map. To find the logical block
23 that stores a particular file block, the code would navigate through
24 this increasingly complicated structure. Notice that there is neither a
25 magic number nor a checksum to provide any level of confidence that the
26 block isn't full of garbage.
27
28 .. ifconfig:: builder != 'latex'
29
30 .. include:: blockmap.rst
31
32 .. ifconfig:: builder == 'latex'
33
34 [Table omitted because LaTeX doesn't support nested tables.]
35
36 Note that with this block mapping scheme, it is necessary to fill out a
37 lot of mapping data even for a large contiguous file! This inefficiency
38 led to the creation of the extent mapping scheme, discussed below.
39
40 Notice also that a file using this mapping scheme cannot be placed
41 higher than 2^32 blocks.
42
43 Extent Tree
44 ~~~~~~~~~~~
45
46 In ext4, the file to logical block map has been replaced with an extent
47 tree. Under the old scheme, allocating a contiguous run of 1,000 blocks
48 requires an indirect block to map all 1,000 entries; with extents, the
49 mapping is reduced to a single ``struct ext4_extent`` with
50 ``ee_len = 1000``. If flex_bg is enabled, it is possible to allocate
51 very large files with a single extent, at a considerable reduction in
52 metadata block use, and some improvement in disk efficiency. The inode
53 must have the extents flag (0x80000) flag set for this feature to be in
54 use.
55
56 Extents are arranged as a tree. Each node of the tree begins with a
57 ``struct ext4_extent_header``. If the node is an interior node
58 (``eh.eh_depth`` > 0), the header is followed by ``eh.eh_entries``
59 instances of ``struct ext4_extent_idx``; each of these index entries
60 points to a block containing more nodes in the extent tree. If the node
61 is a leaf node (``eh.eh_depth == 0``), then the header is followed by
62 ``eh.eh_entries`` instances of ``struct ext4_extent``; these instances
63 point to the file's data blocks. The root node of the extent tree is
64 stored in ``inode.i_block``, which allows for the first four extents to
65 be recorded without the use of extra metadata blocks.
66
67 The extent tree header is recorded in ``struct ext4_extent_header``,
68 which is 12 bytes long:
69
70 .. list-table::
71 :widths: 8 8 24 40
72 :header-rows: 1
73
74 * - Offset
75 - Size
76 - Name
77 - Description
78 * - 0x0
79 - __le16
80 - eh_magic
81 - Magic number, 0xF30A.
82 * - 0x2
83 - __le16
84 - eh_entries
85 - Number of valid entries following the header.
86 * - 0x4
87 - __le16
88 - eh_max
89 - Maximum number of entries that could follow the header.
90 * - 0x6
91 - __le16
92 - eh_depth
93 - Depth of this extent node in the extent tree. 0 = this extent node
94 points to data blocks; otherwise, this extent node points to other
95 extent nodes. The extent tree can be at most 5 levels deep: a logical
96 block number can be at most ``2^32``, and the smallest ``n`` that
97 satisfies ``4*(((blocksize - 12)/12)^n) >= 2^32`` is 5.
98 * - 0x8
99 - __le32
100 - eh_generation
101 - Generation of the tree. (Used by Lustre, but not standard ext4).
102
103 Internal nodes of the extent tree, also known as index nodes, are
104 recorded as ``struct ext4_extent_idx``, and are 12 bytes long:
105
106 .. list-table::
107 :widths: 8 8 24 40
108 :header-rows: 1
109
110 * - Offset
111 - Size
112 - Name
113 - Description
114 * - 0x0
115 - __le32
116 - ei_block
117 - This index node covers file blocks from 'block' onward.
118 * - 0x4
119 - __le32
120 - ei_leaf_lo
121 - Lower 32-bits of the block number of the extent node that is the next
122 level lower in the tree. The tree node pointed to can be either another
123 internal node or a leaf node, described below.
124 * - 0x8
125 - __le16
126 - ei_leaf_hi
127 - Upper 16-bits of the previous field.
128 * - 0xA
129 - __u16
130 - ei_unused
131 -
132
133 Leaf nodes of the extent tree are recorded as ``struct ext4_extent``,
134 and are also 12 bytes long:
135
136 .. list-table::
137 :widths: 8 8 24 40
138 :header-rows: 1
139
140 * - Offset
141 - Size
142 - Name
143 - Description
144 * - 0x0
145 - __le32
146 - ee_block
147 - First file block number that this extent covers.
148 * - 0x4
149 - __le16
150 - ee_len
151 - Number of blocks covered by extent. If the value of this field is <=
152 32768, the extent is initialized. If the value of the field is > 32768,
153 the extent is uninitialized and the actual extent length is ``ee_len`` -
154 32768. Therefore, the maximum length of a initialized extent is 32768
155 blocks, and the maximum length of an uninitialized extent is 32767.
156 * - 0x6
157 - __le16
158 - ee_start_hi
159 - Upper 16-bits of the block number to which this extent points.
160 * - 0x8
161 - __le32
162 - ee_start_lo
163 - Lower 32-bits of the block number to which this extent points.
164
165 Prior to the introduction of metadata checksums, the extent header +
166 extent entries always left at least 4 bytes of unallocated space at the
167 end of each extent tree data block (because (2^x % 12) >= 4). Therefore,
168 the 32-bit checksum is inserted into this space. The 4 extents in the
169 inode do not need checksumming, since the inode is already checksummed.
170 The checksum is calculated against the FS UUID, the inode number, the
171 inode generation, and the entire extent block leading up to (but not
172 including) the checksum itself.
173
174 ``struct ext4_extent_tail`` is 4 bytes long:
175
176 .. list-table::
177 :widths: 8 8 24 40
178 :header-rows: 1
179
180 * - Offset
181 - Size
182 - Name
183 - Description
184 * - 0x0
185 - __le32
186 - eb_checksum
187 - Checksum of the extent block, crc32c(uuid+inum+igeneration+extentblock)
188
189 Inline Data
190 ~~~~~~~~~~~
191
192 If the inline data feature is enabled for the filesystem and the flag is
193 set for the inode, it is possible that the first 60 bytes of the file
194 data are stored here.
195

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

직접·간접 블록 주소 지정

17-42

ext2/3에서는 최대 3단계의 1대1 block map으로 파일 블록 번호를 논리 블록 번호에 매핑했습니다. 특정 파일 블록을 저장하는 논리 블록을 찾으려면 단계가 깊어질수록 복잡해지는 구조를 따라가야 합니다.

이 block map에는 magic number도 checksum도 없으므로 읽은 블록이 손상된 쓰레기 데이터가 아니라는 확신을 제공하지 못합니다. 비 LaTeX 빌드에서는 `blockmap.rst`의 표를 포함하고, LaTeX 빌드에서는 중첩 표 미지원으로 해당 표를 생략합니다.

큰 파일이 연속된 블록을 사용해도 많은 매핑 엔트리를 채워야 하는 비효율 때문에 아래의 extent mapping scheme이 만들어졌습니다.

또한 이 매핑 방식을 쓰는 파일은 `2^32` 블록보다 높은 위치에 배치할 수 없습니다.

3단계 block map 탐색
파일 블록 번호 입력direct pointer 범위면 데이터 블록을 바로 선택single indirect 범위면 포인터 블록 1개 통과double indirect 범위면 포인터 블록 2개 통과triple indirect 범위면 포인터 블록 3개 통과magic·checksum 없이 대상 블록 사용

파일 블록에서 데이터 블록까지 직접·간접 포인터를 따라가는 개념적 경로입니다.


Direct/Indirect Block Addressing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In ext2/3, file block numbers were mapped to logical block numbers by
means of an (up to) three level 1-1 block map. To find the logical block
that stores a particular file block, the code would navigate through
this increasingly complicated structure. Notice that there is neither a
magic number nor a checksum to provide any level of confidence that the
block isn't full of garbage.

.. ifconfig:: builder != 'latex'

   .. include:: blockmap.rst

.. ifconfig:: builder == 'latex'

   [Table omitted because LaTeX doesn't support nested tables.]

Note that with this block mapping scheme, it is necessary to fill out a
lot of mapping data even for a large contiguous file! This inefficiency
led to the creation of the extent mapping scheme, discussed below.

Notice also that a file using this mapping scheme cannot be placed
higher than 2^32 blocks.

extent tree와 header

43-102

ext4에서는 파일 블록에서 논리 블록으로 가는 매핑을 extent tree로 대체했습니다. 이전 방식은 연속된 1,000블록을 할당해도 1,000개 매핑 엔트리를 담은 indirect block이 필요했지만, extent에서는 `ee_len = 1000`인 `struct ext4_extent` 하나로 줄어듭니다.

`flex_bg`를 켜면 매우 큰 파일도 하나의 extent로 할당할 수 있어 메타데이터 블록 사용량을 크게 줄이고 디스크 효율도 개선할 수 있습니다. 이 기능을 사용하려면 inode의 extents flag `0x80000`이 설정되어 있어야 합니다.

extent는 tree로 배열됩니다. 각 node는 `struct ext4_extent_header`로 시작합니다. `eh.eh_depth > 0`인 interior node에는 header 다음에 `eh.eh_entries`개의 `struct ext4_extent_idx`가 오고, 각 index entry는 더 아래의 extent tree node가 든 블록을 가리킵니다.

`eh.eh_depth == 0`인 leaf node에는 header 다음에 `eh.eh_entries`개의 `struct ext4_extent`가 오며 파일의 data block을 가리킵니다. extent tree의 root node는 `inode.i_block`에 저장되므로 추가 메타데이터 블록 없이 처음 네 extent를 기록할 수 있습니다.

12바이트 `struct ext4_extent_header`는 magic, 현재 entry 수, 최대 entry 수, node depth, tree generation을 기록합니다. tree depth는 최대 5단계입니다. 논리 블록 번호의 최댓값이 `2^32`이고 `4*(((blocksize - 12)/12)^n) >= 2^32`를 만족하는 가장 작은 `n`이 5이기 때문입니다.

extent tree 탐색
`inode.i_block`에서 `ext4_extent_header` 확인`eh_depth > 0`: `ext4_extent_idx`에서 하위 node 선택필요한 만큼 index node 반복`eh_depth == 0`: `ext4_extent` leaf 선택`ee_start_hi`와 `ee_start_lo`로 실제 블록 시작점 계산

`inode.i_block`의 root에서 파일 데이터 extent까지 내려가는 경로입니다.

`struct ext4_extent_header`
OffsetTypeName설명
`0x0``__le16``eh_magic`magic number `0xF30A`
`0x2``__le16``eh_entries`header 다음의 유효 entry 수
`0x4``__le16``eh_max`header 다음에 올 수 있는 최대 entry 수
`0x6``__le16``eh_depth`0이면 data extent, 0보다 크면 하위 node를 가리킴
`0x8``__le32``eh_generation`tree generation; Lustre에서 사용하며 표준 ext4는 사용하지 않음

모든 extent tree node 앞에 놓이는 12바이트 header입니다.

Extent Tree
~~~~~~~~~~~

In ext4, the file to logical block map has been replaced with an extent
tree. Under the old scheme, allocating a contiguous run of 1,000 blocks
requires an indirect block to map all 1,000 entries; with extents, the
mapping is reduced to a single ``struct ext4_extent`` with
``ee_len = 1000``. If flex_bg is enabled, it is possible to allocate
very large files with a single extent, at a considerable reduction in
metadata block use, and some improvement in disk efficiency. The inode
must have the extents flag (0x80000) flag set for this feature to be in
use.

Extents are arranged as a tree. Each node of the tree begins with a
``struct ext4_extent_header``. If the node is an interior node
(``eh.eh_depth`` > 0), the header is followed by ``eh.eh_entries``
instances of ``struct ext4_extent_idx``; each of these index entries
points to a block containing more nodes in the extent tree. If the node
is a leaf node (``eh.eh_depth == 0``), then the header is followed by
``eh.eh_entries`` instances of ``struct ext4_extent``; these instances
point to the file's data blocks. The root node of the extent tree is
stored in ``inode.i_block``, which allows for the first four extents to
be recorded without the use of extra metadata blocks.

The extent tree header is recorded in ``struct ext4_extent_header``,
which is 12 bytes long:

.. list-table::
   :widths: 8 8 24 40
   :header-rows: 1

   * - Offset
     - Size
     - Name
     - Description
   * - 0x0
     - __le16
     - eh_magic
     - Magic number, 0xF30A.
   * - 0x2
     - __le16
     - eh_entries
     - Number of valid entries following the header.
   * - 0x4
     - __le16
     - eh_max
     - Maximum number of entries that could follow the header.
   * - 0x6
     - __le16
     - eh_depth
     - Depth of this extent node in the extent tree. 0 = this extent node
       points to data blocks; otherwise, this extent node points to other
       extent nodes. The extent tree can be at most 5 levels deep: a logical
       block number can be at most ``2^32``, and the smallest ``n`` that
       satisfies ``4*(((blocksize - 12)/12)^n) >= 2^32`` is 5.
   * - 0x8
     - __le32
     - eh_generation
     - Generation of the tree. (Used by Lustre, but not standard ext4).

extent tree 내부 index node

103-132

extent tree의 내부 node, 즉 index node는 12바이트 `struct ext4_extent_idx`로 기록됩니다.

`ei_block`은 이 index node가 담당하기 시작하는 파일 블록을 나타냅니다. `ei_leaf_hi`와 `ei_leaf_lo`를 결합한 48비트 블록 번호는 tree의 다음 낮은 단계에 있는 node를 가리킵니다. 대상은 또 다른 내부 node일 수도 있고 leaf node일 수도 있습니다.

`struct ext4_extent_idx`
OffsetTypeName설명
`0x0``__le32``ei_block`이 index가 담당하기 시작하는 파일 블록
`0x4``__le32``ei_leaf_lo`하위 extent node 블록 번호의 하위 32비트
`0x8``__le16``ei_leaf_hi`하위 extent node 블록 번호의 상위 16비트
`0xA``__u16``ei_unused`사용하지 않음

extent tree 내부 node의 12바이트 index entry입니다.

Internal nodes of the extent tree, also known as index nodes, are
recorded as ``struct ext4_extent_idx``, and are 12 bytes long:

.. list-table::
   :widths: 8 8 24 40
   :header-rows: 1

   * - Offset
     - Size
     - Name
     - Description
   * - 0x0
     - __le32
     - ei_block
     - This index node covers file blocks from 'block' onward.
   * - 0x4
     - __le32
     - ei_leaf_lo
     - Lower 32-bits of the block number of the extent node that is the next
       level lower in the tree. The tree node pointed to can be either another
       internal node or a leaf node, described below.
   * - 0x8
     - __le16
     - ei_leaf_hi
     - Upper 16-bits of the previous field.
   * - 0xA
     - __u16
     - ei_unused
     -

extent tree leaf entry

133-164

extent tree의 leaf node는 역시 12바이트인 `struct ext4_extent`로 기록되며 파일의 연속된 data block 구간을 설명합니다.

`ee_block`은 extent가 담당하는 첫 파일 블록 번호입니다. `ee_start_hi`와 `ee_start_lo`는 extent가 가리키는 실제 블록 번호의 상·하위 비트입니다.

`ee_len <= 32768`이면 초기화된 extent이며 값 자체가 블록 수입니다. `ee_len > 32768`이면 초기화되지 않은 extent이고 실제 길이는 `ee_len - 32768`입니다. 따라서 초기화된 extent의 최대 길이는 32,768블록, 초기화되지 않은 extent는 32,767블록입니다.

`struct ext4_extent`
OffsetTypeName설명
`0x0``__le32``ee_block`extent가 담당하는 첫 파일 블록 번호
`0x4``__le16``ee_len`블록 수와 initialized/uninitialized 상태
`0x6``__le16``ee_start_hi`대상 블록 번호의 상위 16비트
`0x8``__le32``ee_start_lo`대상 블록 번호의 하위 32비트

leaf node에서 연속된 파일 데이터 구간을 설명하는 12바이트 entry입니다.

Leaf nodes of the extent tree are recorded as ``struct ext4_extent``,
and are also 12 bytes long:

.. list-table::
   :widths: 8 8 24 40
   :header-rows: 1

   * - Offset
     - Size
     - Name
     - Description
   * - 0x0
     - __le32
     - ee_block
     - First file block number that this extent covers.
   * - 0x4
     - __le16
     - ee_len
     - Number of blocks covered by extent. If the value of this field is <=
       32768, the extent is initialized. If the value of the field is > 32768,
       the extent is uninitialized and the actual extent length is ``ee_len`` -
       32768. Therefore, the maximum length of a initialized extent is 32768
       blocks, and the maximum length of an uninitialized extent is 32767.
   * - 0x6
     - __le16
     - ee_start_hi
     - Upper 16-bits of the block number to which this extent points.
   * - 0x8
     - __le32
     - ee_start_lo
     - Lower 32-bits of the block number to which this extent points.

extent block checksum tail

165-188

metadata checksum이 도입되기 전부터 extent header와 entry를 배치하면 모든 extent tree data block 끝에 최소 4바이트의 빈 공간이 남았습니다. 이는 `(2^x % 12) >= 4`이기 때문이며, 이 공간에 32비트 checksum을 넣습니다.

inode 안에 직접 들어 있는 네 extent는 inode 자체의 checksum으로 보호되므로 별도 checksum이 필요하지 않습니다.

extent block checksum은 FS UUID, inode number, inode generation, checksum 필드 직전까지의 extent block 전체를 입력으로 계산합니다.

`struct ext4_extent_tail`은 4바이트이며 offset `0x0`의 `__le32 eb_checksum` 하나만 담습니다. 값은 `crc32c(uuid+inum+igeneration+extentblock)`입니다.

`struct ext4_extent_tail`
OffsetTypeName계산 입력
`0x0``__le32``eb_checksum``crc32c(uuid+inum+igeneration+extentblock)`

extent tree data block의 마지막 4바이트 checksum입니다.

Prior to the introduction of metadata checksums, the extent header +
extent entries always left at least 4 bytes of unallocated space at the
end of each extent tree data block (because (2^x % 12) >= 4). Therefore,
the 32-bit checksum is inserted into this space. The 4 extents in the
inode do not need checksumming, since the inode is already checksummed.
The checksum is calculated against the FS UUID, the inode number, the
inode generation, and the entire extent block leading up to (but not
including) the checksum itself.

``struct ext4_extent_tail`` is 4 bytes long:

.. list-table::
   :widths: 8 8 24 40
   :header-rows: 1

   * - Offset
     - Size
     - Name
     - Description
   * - 0x0
     - __le32
     - eb_checksum
     - Checksum of the extent block, crc32c(uuid+inum+igeneration+extentblock)

`i_block`의 inline data

189-194

파일시스템에서 inline data 기능을 켜고 해당 inode에도 플래그가 설정되어 있으면 파일 데이터의 처음 60바이트를 `inode.i_block`에 직접 저장할 수 있습니다.

`i_block` inline data 판정
filesystem의 inline data feature 확인inode의 inline data flag 확인처음 60 bytes를 `inode.i_block`에 저장더 큰 데이터는 ibody EA 또는 일반 data block 사용

작은 파일의 첫 데이터를 inode 내부에 저장하는 조건입니다.

Inline Data
~~~~~~~~~~~

If the inline data feature is enabled for the filesystem and the flag is
set for the inode, it is possible that the first 60 bytes of the file
data are stored here.