← Documents Documentation/filesystems/ext2.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

The Second Extended Filesystem

ext2의 마운트 옵션, block group과 inode 구조, feature compatibility, 수치 한계와 journaling을 다루는 전문 번역입니다.

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

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

1. 요약·해설

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

요약·해설

ext2.rst:1-398

ext2는 block group 안에 bitmap, inode table, data block을 가까이 배치하고 superblock을 여러 group에 복제하는 전통적 Unix 계열 파일시스템입니다. inode는 이름을 제외한 metadata와 direct·indirect block pointer를 담으며, directory와 symlink, device도 같은 inode 틀을 목적에 맞게 사용합니다.

이 문서의 핵심은 오래된 구현과 새 기능의 공존 방식입니다. `COMPAT`, `RO_COMPAT`, `INCOMPAT` flag가 모르는 kernel의 읽기·쓰기·mount 가능 범위를 구분하고, `e2fsck`는 어떤 종류든 모르는 flag가 있으면 검증을 거부합니다. ext3 journaling도 ext2 on-disk layout을 바꾸지 않고 일반 파일 형태의 journal을 추가하는 방식으로 이어집니다.

ext2 데이터와 복구 경로
superblock이 block size, group 구성, feature flag를 정의inode allocator가 directory와 가까운 block group에 inode 배치block allocator가 inode와 같은 group에 data block 배치direct·indirect pointer로 파일 data를 찾음오류 정책은 continue·read-only 재마운트·panic 중 선택unclean 상태는 e2fsck 또는 journal replay로 복구

파일 생성부터 오류 및 crash 복구까지의 큰 흐름입니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3
4 ==============================
5 The Second Extended Filesystem
6 ==============================
7
8 ext2 was originally released in January 1993. Written by R\'emy Card,
9 Theodore Ts'o and Stephen Tweedie, it was a major rewrite of the
10 Extended Filesystem. It is currently still (April 2001) the predominant
11 filesystem in use by Linux. There are also implementations available
12 for NetBSD, FreeBSD, the GNU HURD, Windows 95/98/NT, OS/2 and RISC OS.
13
14 Options
15 =======
16
17 Most defaults are determined by the filesystem superblock, and can be
18 set using tune2fs(8). Kernel-determined defaults are indicated by (*).
19
20 ==================== === ================================================
21 bsddf (*) Makes ``df`` act like BSD.
22 minixdf Makes ``df`` act like Minix.
23
24 check=none, nocheck (*) Don't do extra checking of bitmaps on mount
25 (check=normal and check=strict options removed)
26
27 dax Use direct access (no page cache). See
28 Documentation/filesystems/dax.rst.
29
30 debug Extra debugging information is sent to the
31 kernel syslog. Useful for developers.
32
33 errors=continue Keep going on a filesystem error.
34 errors=remount-ro Remount the filesystem read-only on an error.
35 errors=panic Panic and halt the machine if an error occurs.
36
37 grpid, bsdgroups Give objects the same group ID as their parent.
38 nogrpid, sysvgroups New objects have the group ID of their creator.
39
40 nouid32 Use 16-bit UIDs and GIDs.
41
42 oldalloc Enable the old block allocator. Orlov should
43 have better performance, we'd like to get some
44 feedback if it's the contrary for you.
45 orlov (*) Use the Orlov block allocator.
46 (See http://lwn.net/Articles/14633/ and
47 http://lwn.net/Articles/14446/.)
48
49 resuid=n The user ID which may use the reserved blocks.
50 resgid=n The group ID which may use the reserved blocks.
51
52 sb=n Use alternate superblock at this location.
53
54 user_xattr Enable "user." POSIX Extended Attributes
55 (requires CONFIG_EXT2_FS_XATTR).
56 nouser_xattr Don't support "user." extended attributes.
57
58 acl Enable POSIX Access Control Lists support
59 (requires CONFIG_EXT2_FS_POSIX_ACL).
60 noacl Don't support POSIX ACLs.
61
62 quota, usrquota Enable user disk quota support
63 (requires CONFIG_QUOTA).
64
65 grpquota Enable group disk quota support
66 (requires CONFIG_QUOTA).
67 ==================== === ================================================
68
69 noquota option ls silently ignored by ext2.
70
71
72 Specification
73 =============
74
75 ext2 shares many properties with traditional Unix filesystems. It has
76 the concepts of blocks, inodes and directories. It has space in the
77 specification for Access Control Lists (ACLs), fragments, undeletion and
78 compression though these are not yet implemented (some are available as
79 separate patches). There is also a versioning mechanism to allow new
80 features (such as journalling) to be added in a maximally compatible
81 manner.
82
83 Blocks
84 ------
85
86 The space in the device or file is split up into blocks. These are
87 a fixed size, of 1024, 2048 or 4096 bytes (8192 bytes on Alpha systems),
88 which is decided when the filesystem is created. Smaller blocks mean
89 less wasted space per file, but require slightly more accounting overhead,
90 and also impose other limits on the size of files and the filesystem.
91
92 Block Groups
93 ------------
94
95 Blocks are clustered into block groups in order to reduce fragmentation
96 and minimise the amount of head seeking when reading a large amount
97 of consecutive data. Information about each block group is kept in a
98 descriptor table stored in the block(s) immediately after the superblock.
99 Two blocks near the start of each group are reserved for the block usage
100 bitmap and the inode usage bitmap which show which blocks and inodes
101 are in use. Since each bitmap is limited to a single block, this means
102 that the maximum size of a block group is 8 times the size of a block.
103
104 The block(s) following the bitmaps in each block group are designated
105 as the inode table for that block group and the remainder are the data
106 blocks. The block allocation algorithm attempts to allocate data blocks
107 in the same block group as the inode which contains them.
108
109 The Superblock
110 --------------
111
112 The superblock contains all the information about the configuration of
113 the filing system. The primary copy of the superblock is stored at an
114 offset of 1024 bytes from the start of the device, and it is essential
115 to mounting the filesystem. Since it is so important, backup copies of
116 the superblock are stored in block groups throughout the filesystem.
117 The first version of ext2 (revision 0) stores a copy at the start of
118 every block group, along with backups of the group descriptor block(s).
119 Because this can consume a considerable amount of space for large
120 filesystems, later revisions can optionally reduce the number of backup
121 copies by only putting backups in specific groups (this is the sparse
122 superblock feature). The groups chosen are 0, 1 and powers of 3, 5 and 7.
123
124 The information in the superblock contains fields such as the total
125 number of inodes and blocks in the filesystem and how many are free,
126 how many inodes and blocks are in each block group, when the filesystem
127 was mounted (and if it was cleanly unmounted), when it was modified,
128 what version of the filesystem it is (see the Revisions section below)
129 and which OS created it.
130
131 If the filesystem is revision 1 or higher, then there are extra fields,
132 such as a volume name, a unique identification number, the inode size,
133 and space for optional filesystem features to store configuration info.
134
135 All fields in the superblock (as in all other ext2 structures) are stored
136 on the disc in little endian format, so a filesystem is portable between
137 machines without having to know what machine it was created on.
138
139 Inodes
140 ------
141
142 The inode (index node) is a fundamental concept in the ext2 filesystem.
143 Each object in the filesystem is represented by an inode. The inode
144 structure contains pointers to the filesystem blocks which contain the
145 data held in the object and all of the metadata about an object except
146 its name. The metadata about an object includes the permissions, owner,
147 group, flags, size, number of blocks used, access time, change time,
148 modification time, deletion time, number of links, fragments, version
149 (for NFS) and extended attributes (EAs) and/or Access Control Lists (ACLs).
150
151 There are some reserved fields which are currently unused in the inode
152 structure and several which are overloaded. One field is reserved for the
153 directory ACL if the inode is a directory and alternately for the top 32
154 bits of the file size if the inode is a regular file (allowing file sizes
155 larger than 2GB). The translator field is unused under Linux, but is used
156 by the HURD to reference the inode of a program which will be used to
157 interpret this object. Most of the remaining reserved fields have been
158 used up for both Linux and the HURD for larger owner and group fields,
159 The HURD also has a larger mode field so it uses another of the remaining
160 fields to store the extra more bits.
161
162 There are pointers to the first 12 blocks which contain the file's data
163 in the inode. There is a pointer to an indirect block (which contains
164 pointers to the next set of blocks), a pointer to a doubly-indirect
165 block (which contains pointers to indirect blocks) and a pointer to a
166 trebly-indirect block (which contains pointers to doubly-indirect blocks).
167
168 The flags field contains some ext2-specific flags which aren't catered
169 for by the standard chmod flags. These flags can be listed with lsattr
170 and changed with the chattr command, and allow specific filesystem
171 behaviour on a per-file basis. There are flags for secure deletion,
172 undeletable, compression, synchronous updates, immutability, append-only,
173 dumpable, no-atime, indexed directories, and data-journaling. Not all
174 of these are supported yet.
175
176 Directories
177 -----------
178
179 A directory is a filesystem object and has an inode just like a file.
180 It is a specially formatted file containing records which associate
181 each name with an inode number. Later revisions of the filesystem also
182 encode the type of the object (file, directory, symlink, device, fifo,
183 socket) to avoid the need to check the inode itself for this information
184 (support for taking advantage of this feature does not yet exist in
185 Glibc 2.2).
186
187 The inode allocation code tries to assign inodes which are in the same
188 block group as the directory in which they are first created.
189
190 The current implementation of ext2 uses a singly-linked list to store
191 the filenames in the directory; a pending enhancement uses hashing of the
192 filenames to allow lookup without the need to scan the entire directory.
193
194 The current implementation never removes empty directory blocks once they
195 have been allocated to hold more files.
196
197 Special files
198 -------------
199
200 Symbolic links are also filesystem objects with inodes. They deserve
201 special mention because the data for them is stored within the inode
202 itself if the symlink is less than 60 bytes long. It uses the fields
203 which would normally be used to store the pointers to data blocks.
204 This is a worthwhile optimisation as it we avoid allocating a full
205 block for the symlink, and most symlinks are less than 60 characters long.
206
207 Character and block special devices never have data blocks assigned to
208 them. Instead, their device number is stored in the inode, again reusing
209 the fields which would be used to point to the data blocks.
210
211 Reserved Space
212 --------------
213
214 In ext2, there is a mechanism for reserving a certain number of blocks
215 for a particular user (normally the super-user). This is intended to
216 allow for the system to continue functioning even if non-privileged users
217 fill up all the space available to them (this is independent of filesystem
218 quotas). It also keeps the filesystem from filling up entirely which
219 helps combat fragmentation.
220
221 Filesystem check
222 ----------------
223
224 At boot time, most systems run a consistency check (e2fsck) on their
225 filesystems. The superblock of the ext2 filesystem contains several
226 fields which indicate whether fsck should actually run (since checking
227 the filesystem at boot can take a long time if it is large). fsck will
228 run if the filesystem was not cleanly unmounted, if the maximum mount
229 count has been exceeded or if the maximum time between checks has been
230 exceeded.
231
232 Feature Compatibility
233 ---------------------
234
235 The compatibility feature mechanism used in ext2 is sophisticated.
236 It safely allows features to be added to the filesystem, without
237 unnecessarily sacrificing compatibility with older versions of the
238 filesystem code. The feature compatibility mechanism is not supported by
239 the original revision 0 (EXT2_GOOD_OLD_REV) of ext2, but was introduced in
240 revision 1. There are three 32-bit fields, one for compatible features
241 (COMPAT), one for read-only compatible (RO_COMPAT) features and one for
242 incompatible (INCOMPAT) features.
243
244 These feature flags have specific meanings for the kernel as follows:
245
246 A COMPAT flag indicates that a feature is present in the filesystem,
247 but the on-disk format is 100% compatible with older on-disk formats, so
248 a kernel which didn't know anything about this feature could read/write
249 the filesystem without any chance of corrupting the filesystem (or even
250 making it inconsistent). This is essentially just a flag which says
251 "this filesystem has a (hidden) feature" that the kernel or e2fsck may
252 want to be aware of (more on e2fsck and feature flags later). The ext3
253 HAS_JOURNAL feature is a COMPAT flag because the ext3 journal is simply
254 a regular file with data blocks in it so the kernel does not need to
255 take any special notice of it if it doesn't understand ext3 journaling.
256
257 An RO_COMPAT flag indicates that the on-disk format is 100% compatible
258 with older on-disk formats for reading (i.e. the feature does not change
259 the visible on-disk format). However, an old kernel writing to such a
260 filesystem would/could corrupt the filesystem, so this is prevented. The
261 most common such feature, SPARSE_SUPER, is an RO_COMPAT feature because
262 sparse groups allow file data blocks where superblock/group descriptor
263 backups used to live, and ext2_free_blocks() refuses to free these blocks,
264 which would leading to inconsistent bitmaps. An old kernel would also
265 get an error if it tried to free a series of blocks which crossed a group
266 boundary, but this is a legitimate layout in a SPARSE_SUPER filesystem.
267
268 An INCOMPAT flag indicates the on-disk format has changed in some
269 way that makes it unreadable by older kernels, or would otherwise
270 cause a problem if an old kernel tried to mount it. FILETYPE is an
271 INCOMPAT flag because older kernels would think a filename was longer
272 than 256 characters, which would lead to corrupt directory listings.
273 The COMPRESSION flag is an obvious INCOMPAT flag - if the kernel
274 doesn't understand compression, you would just get garbage back from
275 read() instead of it automatically decompressing your data. The ext3
276 RECOVER flag is needed to prevent a kernel which does not understand the
277 ext3 journal from mounting the filesystem without replaying the journal.
278
279 For e2fsck, it needs to be more strict with the handling of these
280 flags than the kernel. If it doesn't understand ANY of the COMPAT,
281 RO_COMPAT, or INCOMPAT flags it will refuse to check the filesystem,
282 because it has no way of verifying whether a given feature is valid
283 or not. Allowing e2fsck to succeed on a filesystem with an unknown
284 feature is a false sense of security for the user. Refusing to check
285 a filesystem with unknown features is a good incentive for the user to
286 update to the latest e2fsck. This also means that anyone adding feature
287 flags to ext2 also needs to update e2fsck to verify these features.
288
289 Metadata
290 --------
291
292 It is frequently claimed that the ext2 implementation of writing
293 asynchronous metadata is faster than the ffs synchronous metadata
294 scheme but less reliable. Both methods are equally resolvable by their
295 respective fsck programs.
296
297 If you're exceptionally paranoid, there are 3 ways of making metadata
298 writes synchronous on ext2:
299
300 - per-file if you have the program source: use the O_SYNC flag to open()
301 - per-file if you don't have the source: use "chattr +S" on the file
302 - per-filesystem: add the "sync" option to mount (or in /etc/fstab)
303
304 the first and last are not ext2 specific but do force the metadata to
305 be written synchronously. See also Journaling below.
306
307 Limitations
308 -----------
309
310 There are various limits imposed by the on-disk layout of ext2. Other
311 limits are imposed by the current implementation of the kernel code.
312 Many of the limits are determined at the time the filesystem is first
313 created, and depend upon the block size chosen. The ratio of inodes to
314 data blocks is fixed at filesystem creation time, so the only way to
315 increase the number of inodes is to increase the size of the filesystem.
316 No tools currently exist which can change the ratio of inodes to blocks.
317
318 Most of these limits could be overcome with slight changes in the on-disk
319 format and using a compatibility flag to signal the format change (at
320 the expense of some compatibility).
321
322 ===================== ======= ======= ======= ========
323 Filesystem block size 1kB 2kB 4kB 8kB
324 ===================== ======= ======= ======= ========
325 File size limit 16GB 256GB 2048GB 2048GB
326 Filesystem size limit 2047GB 8192GB 16384GB 32768GB
327 ===================== ======= ======= ======= ========
328
329 There is a 2.4 kernel limit of 2048GB for a single block device, so no
330 filesystem larger than that can be created at this time. There is also
331 an upper limit on the block size imposed by the page size of the kernel,
332 so 8kB blocks are only allowed on Alpha systems (and other architectures
333 which support larger pages).
334
335 There is an upper limit of 32000 subdirectories in a single directory.
336
337 There is a "soft" upper limit of about 10-15k files in a single directory
338 with the current linear linked-list directory implementation. This limit
339 stems from performance problems when creating and deleting (and also
340 finding) files in such large directories. Using a hashed directory index
341 (under development) allows 100k-1M+ files in a single directory without
342 performance problems (although RAM size becomes an issue at this point).
343
344 The (meaningless) absolute upper limit of files in a single directory
345 (imposed by the file size, the realistic limit is obviously much less)
346 is over 130 trillion files. It would be higher except there are not
347 enough 4-character names to make up unique directory entries, so they
348 have to be 8 character filenames, even then we are fairly close to
349 running out of unique filenames.
350
351 Journaling
352 ----------
353
354 A journaling extension to the ext2 code has been developed by Stephen
355 Tweedie. It avoids the risks of metadata corruption and the need to
356 wait for e2fsck to complete after a crash, without requiring a change
357 to the on-disk ext2 layout. In a nutshell, the journal is a regular
358 file which stores whole metadata (and optionally data) blocks that have
359 been modified, prior to writing them into the filesystem. This means
360 it is possible to add a journal to an existing ext2 filesystem without
361 the need for data conversion.
362
363 When changes to the filesystem (e.g. a file is renamed) they are stored in
364 a transaction in the journal and can either be complete or incomplete at
365 the time of a crash. If a transaction is complete at the time of a crash
366 (or in the normal case where the system does not crash), then any blocks
367 in that transaction are guaranteed to represent a valid filesystem state,
368 and are copied into the filesystem. If a transaction is incomplete at
369 the time of the crash, then there is no guarantee of consistency for
370 the blocks in that transaction so they are discarded (which means any
371 filesystem changes they represent are also lost).
372 Check Documentation/filesystems/ext4/ if you want to read more about
373 ext4 and journaling.
374
375 References
376 ==========
377
378 ======================= ===============================================
379 The kernel source file:/usr/src/linux/fs/ext2/
380 e2fsprogs (e2fsck) http://e2fsprogs.sourceforge.net/
381 Design & Implementation http://e2fsprogs.sourceforge.net/ext2intro.html
382 Journaling (ext3) ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/
383 Filesystem Resizing http://ext2resize.sourceforge.net/
384 Compression [1]_ http://e2compr.sourceforge.net/
385 ======================= ===============================================
386
387 Implementations for:
388
389 ======================= ===========================================================
390 Windows 95/98/NT/2000 http://www.chrysocome.net/explore2fs
391 Windows 95 [1]_ http://www.yipton.net/content.html#FSDEXT2
392 DOS client [1]_ ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/
393 OS/2 [2]_ ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/
394 RISC OS client http://www.esw-heim.tu-clausthal.de/~marco/smorbrod/IscaFS/
395 ======================= ===========================================================
396
397 .. [1] no longer actively developed/supported (as of Apr 2001)
398 .. [2] no longer actively developed/supported (as of Mar 2009)
399

3. 한국어 전문 번역

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

역사와 마운트 옵션

1-69

두 번째 확장 파일시스템(ext2)은 1993년 1월 처음 공개되었습니다. Rémy Card, Theodore Ts'o, Stephen Tweedie가 Extended Filesystem을 대폭 다시 작성했으며, 이 문서가 기준으로 삼은 2001년 4월 당시 Linux에서 가장 널리 쓰이던 파일시스템이었습니다. NetBSD, FreeBSD, GNU HURD, Windows 95/98/NT, OS/2, RISC OS용 구현도 있었습니다.

대부분의 기본값은 파일시스템 superblock이 결정하며 `tune2fs(8)`로 설정할 수 있습니다. 아래에서 `(*)`는 커널이 정하는 기본값입니다.

`bsddf`는 `df`를 BSD 방식으로 동작하게 하는 기본 옵션이고, `minixdf`는 Minix 방식을 사용합니다. `check=none`과 `nocheck`는 마운트 때 bitmap을 추가 검사하지 않는 기본 동작입니다. 과거의 `check=normal`과 `check=strict`는 제거되었습니다.

`dax`는 page cache를 거치지 않는 direct access를 사용합니다. 세부 사항은 `Documentation/filesystems/dax.rst`를 참조합니다. `debug`는 개발자가 진단할 수 있도록 추가 정보를 kernel syslog로 보냅니다.

파일시스템 오류가 발생했을 때 `errors=continue`는 계속 실행하고, `errors=remount-ro`는 read-only로 다시 마운트하며, `errors=panic`은 panic을 일으켜 시스템을 멈춥니다.

`grpid` 또는 `bsdgroups`는 새 객체가 부모와 같은 group ID를 갖게 합니다. `nogrpid` 또는 `sysvgroups`는 새 객체를 만든 사용자의 group ID를 부여합니다. `nouid32`는 16-bit UID와 GID를 사용합니다.

`oldalloc`은 이전 block allocator를 켭니다. 기본값인 `orlov`는 Orlov block allocator를 사용하며 일반적으로 더 좋은 성능을 내도록 설계되었습니다. 문서의 두 LWN 링크는 이 allocator의 배경 자료입니다.

`resuid=n`과 `resgid=n`은 reserved block을 사용할 수 있는 user ID와 group ID를 지정합니다. `sb=n`은 지정한 위치의 대체 superblock을 사용합니다.

`user_xattr`은 `user.` POSIX Extended Attributes를 활성화하며 `CONFIG_EXT2_FS_XATTR`가 필요합니다. `nouser_xattr`은 이를 비활성화합니다. `acl`은 `CONFIG_EXT2_FS_POSIX_ACL`이 있을 때 POSIX Access Control Lists를 활성화하고, `noacl`은 ACL을 지원하지 않습니다.

`quota`와 `usrquota`는 `CONFIG_QUOTA`가 필요하며 사용자 disk quota를 활성화합니다. `grpquota`는 그룹 disk quota를 활성화합니다. `noquota` 옵션은 ext2가 오류 없이 조용히 무시합니다.

ext2 마운트 옵션
옵션기본값동작
`bsddf` / `minixdf``bsddf``df`의 BSD/Minix 계산 방식 선택
`check=none`, `nocheck`마운트 시 bitmap 추가 검사 생략
`dax`아니요page cache 없는 direct access
`debug`아니요kernel syslog에 추가 진단 정보 출력
`errors=continue`정책오류 후 계속 실행
`errors=remount-ro`정책오류 시 read-only 재마운트
`errors=panic`정책오류 시 panic 및 정지
`grpid`, `bsdgroups`선택부모의 group ID 상속
`nogrpid`, `sysvgroups`선택생성자의 group ID 사용
`nouid32`아니요16-bit UID/GID 사용
`oldalloc` / `orlov``orlov`이전 allocator 또는 Orlov allocator
`resuid=n`, `resgid=n`설정값reserved block 사용 주체
`sb=n`아니요대체 superblock 위치
`user_xattr` / `nouser_xattr`구성 의존`user.` 확장 속성
`acl` / `noacl`구성 의존POSIX ACL
`quota`, `usrquota`, `grpquota`아니요사용자/그룹 disk quota

원문의 옵션 표를 기능별로 정리한 것입니다.

.. SPDX-License-Identifier: GPL-2.0


==============================
The Second Extended Filesystem
==============================

ext2 was originally released in January 1993.  Written by R\'emy Card,
Theodore Ts'o and Stephen Tweedie, it was a major rewrite of the
Extended Filesystem.  It is currently still (April 2001) the predominant
filesystem in use by Linux.  There are also implementations available
for NetBSD, FreeBSD, the GNU HURD, Windows 95/98/NT, OS/2 and RISC OS.

Options
=======

Most defaults are determined by the filesystem superblock, and can be
set using tune2fs(8). Kernel-determined defaults are indicated by (*).

====================    ===     ================================================
bsddf                        (*)        Makes ``df`` act like BSD.
minixdf                                Makes ``df`` act like Minix.

check=none, nocheck        (*)        Don't do extra checking of bitmaps on mount
                                (check=normal and check=strict options removed)

dax                                Use direct access (no page cache).  See
                                Documentation/filesystems/dax.rst.

debug                                Extra debugging information is sent to the
                                kernel syslog.  Useful for developers.

errors=continue                        Keep going on a filesystem error.
errors=remount-ro                Remount the filesystem read-only on an error.
errors=panic                        Panic and halt the machine if an error occurs.

grpid, bsdgroups                Give objects the same group ID as their parent.
nogrpid, sysvgroups                New objects have the group ID of their creator.

nouid32                                Use 16-bit UIDs and GIDs.

oldalloc                        Enable the old block allocator. Orlov should
                                have better performance, we'd like to get some
                                feedback if it's the contrary for you.
orlov                        (*)        Use the Orlov block allocator.
                                (See http://lwn.net/Articles/14633/ and
                                http://lwn.net/Articles/14446/.)

resuid=n                        The user ID which may use the reserved blocks.
resgid=n                        The group ID which may use the reserved blocks.

sb=n                                Use alternate superblock at this location.

user_xattr                        Enable "user." POSIX Extended Attributes
                                (requires CONFIG_EXT2_FS_XATTR).
nouser_xattr                        Don't support "user." extended attributes.

acl                                Enable POSIX Access Control Lists support
                                (requires CONFIG_EXT2_FS_POSIX_ACL).
noacl                                Don't support POSIX ACLs.

quota, usrquota                        Enable user disk quota support
                                (requires CONFIG_QUOTA).

grpquota                        Enable group disk quota support
                                (requires CONFIG_QUOTA).
====================    ===     ================================================

noquota option ls silently ignored by ext2.

기본 명세, block과 block group

70-107

ext2는 전통적인 Unix 파일시스템과 마찬가지로 block, inode, directory 개념을 사용합니다. 명세에는 ACL, fragment, 삭제 복구, 압축을 위한 공간이 있지만 이 문서 시점에는 구현되지 않았고 일부는 별도 patch로만 제공되었습니다. journalling 같은 새 기능을 가능한 한 호환성 있게 추가할 수 있도록 versioning mechanism도 갖췄습니다.

장치나 파일의 공간은 파일시스템 생성 시 고정 크기의 block으로 나뉩니다. 일반적인 block 크기는 1024, 2048, 4096 bytes이고 Alpha 시스템에서는 8192 bytes도 가능합니다. 작은 block은 파일마다 버리는 공간을 줄이지만 bookkeeping overhead가 조금 늘고 파일 및 파일시스템 크기 한계도 낮아집니다.

fragmentation과 대량 연속 읽기의 head seeking을 줄이기 위해 block을 block group으로 묶습니다. 각 group의 정보는 superblock 바로 다음 block에 있는 descriptor table에 보관합니다.

각 block group 시작 부분 가까이의 두 block은 각각 block usage bitmap과 inode usage bitmap으로 예약됩니다. 각 bitmap이 한 block으로 제한되므로 block group의 최대 크기는 block 크기의 8배라는 제약을 갖습니다.

bitmap 뒤의 block은 그 group의 inode table이고, 나머지는 data block입니다. block allocation algorithm은 데이터가 속한 inode와 같은 block group에 data block을 배치하려고 시도합니다.

ext2 block group 배치
superblock 뒤에 group descriptor table 배치각 group 시작부에 block usage bitmap 배치그 다음 inode usage bitmap 배치bitmap 뒤에 해당 group의 inode table 배치나머지 영역을 data block으로 사용inode와 data를 같은 group에 두어 fragmentation과 seeking 감소

원문의 block group 설명을 물리적 순서와 할당 목적에 맞춰 나타냅니다.



Specification
=============

ext2 shares many properties with traditional Unix filesystems.  It has
the concepts of blocks, inodes and directories.  It has space in the
specification for Access Control Lists (ACLs), fragments, undeletion and
compression though these are not yet implemented (some are available as
separate patches).  There is also a versioning mechanism to allow new
features (such as journalling) to be added in a maximally compatible
manner.

Blocks
------

The space in the device or file is split up into blocks.  These are
a fixed size, of 1024, 2048 or 4096 bytes (8192 bytes on Alpha systems),
which is decided when the filesystem is created.  Smaller blocks mean
less wasted space per file, but require slightly more accounting overhead,
and also impose other limits on the size of files and the filesystem.

Block Groups
------------

Blocks are clustered into block groups in order to reduce fragmentation
and minimise the amount of head seeking when reading a large amount
of consecutive data.  Information about each block group is kept in a
descriptor table stored in the block(s) immediately after the superblock.
Two blocks near the start of each group are reserved for the block usage
bitmap and the inode usage bitmap which show which blocks and inodes
are in use.  Since each bitmap is limited to a single block, this means
that the maximum size of a block group is 8 times the size of a block.

The block(s) following the bitmaps in each block group are designated
as the inode table for that block group and the remainder are the data
blocks.  The block allocation algorithm attempts to allocate data blocks
in the same block group as the inode which contains them.

superblock 복제와 디스크 형식

108-137

superblock에는 파일시스템 구성 정보가 모두 들어 있습니다. primary superblock은 장치 시작점에서 1024 bytes 떨어진 곳에 저장되며 파일시스템을 마운트하는 데 필수입니다. 손상에 대비해 여러 block group에 backup copy를 둡니다.

초기 ext2인 revision 0은 모든 block group 시작에 superblock 사본과 group descriptor block 사본을 저장합니다. 큰 파일시스템에서는 이 공간 비용이 커지므로 이후 revision은 sparse superblock 기능으로 backup을 특정 group에만 둘 수 있습니다. 선택되는 group은 0, 1 및 3, 5, 7의 거듭제곱 번호입니다.

superblock에는 전체 inode와 block 수 및 free 수, block group당 inode와 block 수, mount 시각과 clean unmount 여부, 수정 시각, 파일시스템 revision, 생성한 OS 같은 field가 있습니다.

revision 1 이상에는 volume name, UUID, inode size, optional filesystem feature의 구성 정보를 담을 공간 같은 field가 추가됩니다.

superblock을 포함한 모든 ext2 on-disk structure의 field는 little endian으로 저장됩니다. 따라서 파일시스템을 만든 machine의 byte order를 따로 알지 않아도 서로 다른 machine 사이에서 이동할 수 있습니다.

superblock 보존 방식
구분위치 또는 내용
Primary copy장치 시작 + 1024 bytes
Revision 0 backup모든 block group 시작
Sparse backupgroup 0, 1, 3·5·7의 거듭제곱
핵심 통계inode/block 총수와 free 수, group별 수량
상태·식별mount/수정 시각, clean 여부, revision, 생성 OS
Revision 1+volume name, UUID, inode size, feature 구성
Byte order모든 on-disk field가 little endian

revision에 따른 primary 및 backup superblock 배치를 비교합니다.


The Superblock
--------------

The superblock contains all the information about the configuration of
the filing system.  The primary copy of the superblock is stored at an
offset of 1024 bytes from the start of the device, and it is essential
to mounting the filesystem.  Since it is so important, backup copies of
the superblock are stored in block groups throughout the filesystem.
The first version of ext2 (revision 0) stores a copy at the start of
every block group, along with backups of the group descriptor block(s).
Because this can consume a considerable amount of space for large
filesystems, later revisions can optionally reduce the number of backup
copies by only putting backups in specific groups (this is the sparse
superblock feature).  The groups chosen are 0, 1 and powers of 3, 5 and 7.

The information in the superblock contains fields such as the total
number of inodes and blocks in the filesystem and how many are free,
how many inodes and blocks are in each block group, when the filesystem
was mounted (and if it was cleanly unmounted), when it was modified,
what version of the filesystem it is (see the Revisions section below)
and which OS created it.

If the filesystem is revision 1 or higher, then there are extra fields,
such as a volume name, a unique identification number, the inode size,
and space for optional filesystem features to store configuration info.

All fields in the superblock (as in all other ext2 structures) are stored
on the disc in little endian format, so a filesystem is portable between
machines without having to know what machine it was created on.

inode metadata와 block pointer

138-174

inode(index node)는 ext2의 기본 객체 표현입니다. 모든 파일시스템 객체는 inode 하나로 나타내며, inode에는 객체 이름을 제외한 metadata와 실제 데이터를 담은 filesystem block을 가리키는 pointer가 있습니다.

metadata에는 permission, owner, group, flag, size, 사용 block 수, access/change/modification/deletion time, link 수, fragment, NFS용 version, Extended Attributes(EAs), Access Control Lists(ACLs)가 포함됩니다.

inode structure의 일부 reserved field는 아직 쓰지 않고 일부는 용도에 따라 중첩 사용합니다. 한 field는 directory inode에서는 directory ACL용이지만 regular file에서는 file size의 상위 32 bit로 쓰여 2GB보다 큰 파일을 표현합니다.

translator field는 Linux에서는 사용하지 않지만 GNU HURD에서는 이 객체를 해석할 program의 inode를 참조합니다. Linux와 HURD는 남은 reserved field 상당수를 더 큰 owner/group field로 사용하고, HURD는 mode field도 더 크므로 추가 mode bit를 위해 다른 field 하나를 씁니다.

inode에는 파일 데이터의 첫 12개 block을 직접 가리키는 pointer가 있습니다. 이어서 다음 data block pointer 집합을 담는 indirect block pointer, indirect block들을 가리키는 doubly-indirect block pointer, doubly-indirect block들을 가리키는 trebly-indirect block pointer가 있습니다.

표준 `chmod` flag로 표현할 수 없는 ext2 전용 flag는 `lsattr`로 보고 `chattr`로 바꿀 수 있습니다. secure deletion, undeletable, compression, synchronous updates, immutability, append-only, dumpable, no-atime, indexed directories, data-journaling flag가 있으며 이 문서 시점에는 모두가 지원되는 것은 아닙니다.

inode에서 data block까지
inode가 첫 12개 data block을 direct pointer로 참조indirect pointer가 data block pointer 목록을 담은 block 참조doubly-indirect pointer가 indirect block 목록 참조trebly-indirect pointer가 doubly-indirect block 목록 참조파일 크기가 커질수록 더 높은 간접 단계 사용

직접 및 다단계 간접 pointer가 확장되는 구조입니다.


Inodes
------

The inode (index node) is a fundamental concept in the ext2 filesystem.
Each object in the filesystem is represented by an inode.  The inode
structure contains pointers to the filesystem blocks which contain the
data held in the object and all of the metadata about an object except
its name.  The metadata about an object includes the permissions, owner,
group, flags, size, number of blocks used, access time, change time,
modification time, deletion time, number of links, fragments, version
(for NFS) and extended attributes (EAs) and/or Access Control Lists (ACLs).

There are some reserved fields which are currently unused in the inode
structure and several which are overloaded.  One field is reserved for the
directory ACL if the inode is a directory and alternately for the top 32
bits of the file size if the inode is a regular file (allowing file sizes
larger than 2GB).  The translator field is unused under Linux, but is used
by the HURD to reference the inode of a program which will be used to
interpret this object.  Most of the remaining reserved fields have been
used up for both Linux and the HURD for larger owner and group fields,
The HURD also has a larger mode field so it uses another of the remaining
fields to store the extra more bits.

There are pointers to the first 12 blocks which contain the file's data
in the inode.  There is a pointer to an indirect block (which contains
pointers to the next set of blocks), a pointer to a doubly-indirect
block (which contains pointers to indirect blocks) and a pointer to a
trebly-indirect block (which contains pointers to doubly-indirect blocks).

The flags field contains some ext2-specific flags which aren't catered
for by the standard chmod flags.  These flags can be listed with lsattr
and changed with the chattr command, and allow specific filesystem
behaviour on a per-file basis.  There are flags for secure deletion,
undeletable, compression, synchronous updates, immutability, append-only,
dumpable, no-atime, indexed directories, and data-journaling.  Not all
of these are supported yet.

directory, special file, reserved space와 검사

175-230

directory도 파일과 같은 inode를 가진 파일시스템 객체입니다. 다만 이름과 inode number를 연결하는 record를 담는 특수 형식의 파일입니다. 이후 revision은 file, directory, symlink, device, fifo, socket 같은 객체 type도 directory entry에 기록하여 inode를 다시 확인할 필요를 줄입니다. 문서 시점의 Glibc 2.2는 이 기능을 활용하지 않았습니다.

inode allocator는 새 객체가 처음 만들어진 directory와 같은 block group의 inode를 배정하려고 합니다. 현재 구현은 directory filename을 singly-linked list로 저장하지만, 전체 directory를 선형 scan하지 않도록 filename hashing을 쓰는 개선이 개발되고 있었습니다. 한 번 파일을 담기 위해 할당한 빈 directory block은 현재 구현에서 제거하지 않습니다.

symbolic link도 inode를 갖습니다. symlink가 60 bytes보다 짧으면 평소 data block pointer로 쓰는 inode field 안에 link data 자체를 저장합니다. 대부분의 symlink가 60자보다 짧기 때문에 block 하나를 따로 할당하지 않는 효과적인 최적화입니다.

character device와 block special device에는 data block을 할당하지 않습니다. 대신 data block pointer field를 재사용해 device number를 inode 안에 저장합니다.

ext2는 특정 사용자, 보통 super-user가 쓸 수 있도록 일정 수의 block을 예약할 수 있습니다. 이는 quota와 독립적이며, 일반 사용자가 모든 가용 공간을 채워도 시스템이 계속 동작할 여지를 남깁니다. 파일시스템이 완전히 차는 것도 막아 fragmentation 완화에 도움이 됩니다.

대부분의 시스템은 boot 때 `e2fsck`로 consistency check를 수행합니다. ext2 superblock에는 실제로 `fsck`를 실행해야 하는지 판단하는 field가 있습니다. clean하게 unmount되지 않았거나, 최대 mount 횟수를 넘었거나, 검사 사이의 최대 시간이 지났으면 검사를 실행합니다.

inode를 재사용하는 특수 객체
객체 또는 기능inode/저장 방식
Directory이름과 inode number를 잇는 record를 가진 특수 파일
짧은 symlink60 bytes 미만이면 data pointer field 안에 link data 저장
Character devicedata block 없이 device number를 inode에 저장
Block devicedata block 없이 device number를 inode에 저장
Reserved space지정 사용자용 block을 별도로 확보
`e2fsck` triggerunclean unmount, mount count 초과, 검사 기간 초과

directory와 special file이 inode 및 내부 field를 사용하는 방법입니다.


Directories
-----------

A directory is a filesystem object and has an inode just like a file.
It is a specially formatted file containing records which associate
each name with an inode number.  Later revisions of the filesystem also
encode the type of the object (file, directory, symlink, device, fifo,
socket) to avoid the need to check the inode itself for this information
(support for taking advantage of this feature does not yet exist in
Glibc 2.2).

The inode allocation code tries to assign inodes which are in the same
block group as the directory in which they are first created.

The current implementation of ext2 uses a singly-linked list to store
the filenames in the directory; a pending enhancement uses hashing of the
filenames to allow lookup without the need to scan the entire directory.

The current implementation never removes empty directory blocks once they
have been allocated to hold more files.

Special files
-------------

Symbolic links are also filesystem objects with inodes.  They deserve
special mention because the data for them is stored within the inode
itself if the symlink is less than 60 bytes long.  It uses the fields
which would normally be used to store the pointers to data blocks.
This is a worthwhile optimisation as it we avoid allocating a full
block for the symlink, and most symlinks are less than 60 characters long.

Character and block special devices never have data blocks assigned to
them.  Instead, their device number is stored in the inode, again reusing
the fields which would be used to point to the data blocks.

Reserved Space
--------------

In ext2, there is a mechanism for reserving a certain number of blocks
for a particular user (normally the super-user).  This is intended to
allow for the system to continue functioning even if non-privileged users
fill up all the space available to them (this is independent of filesystem
quotas).  It also keeps the filesystem from filling up entirely which
helps combat fragmentation.

Filesystem check
----------------

At boot time, most systems run a consistency check (e2fsck) on their
filesystems.  The superblock of the ext2 filesystem contains several
fields which indicate whether fsck should actually run (since checking
the filesystem at boot can take a long time if it is large).  fsck will
run if the filesystem was not cleanly unmounted, if the maximum mount
count has been exceeded or if the maximum time between checks has been
exceeded.

COMPAT, RO_COMPAT, INCOMPAT

231-287

ext2의 feature compatibility mechanism은 오래된 파일시스템 코드와의 호환성을 불필요하게 포기하지 않으면서 새 기능을 안전하게 추가합니다. 원래 revision 0인 `EXT2_GOOD_OLD_REV`에는 없고 revision 1에서 도입되었습니다. superblock에는 `COMPAT`, `RO_COMPAT`, `INCOMPAT` 기능을 위한 32-bit field가 각각 하나씩 있습니다.

`COMPAT` flag는 기능이 존재하지만 on-disk format이 구형 형식과 완전히 읽기/쓰기 호환됨을 뜻합니다. 이 기능을 모르는 kernel도 파일시스템을 손상하거나 불일치 상태로 만들 위험 없이 읽고 쓸 수 있습니다. kernel이나 `e2fsck`가 알아두면 좋은 숨은 기능의 존재를 표시하는 셈입니다.

ext3의 `HAS_JOURNAL`은 `COMPAT`입니다. journal이 data block을 가진 일반 파일이므로 ext3 journaling을 이해하지 못하는 kernel도 그 파일 자체를 특별히 처리할 필요가 없기 때문입니다.

`RO_COMPAT` flag는 구형 형식과 읽기는 완전히 호환되지만 구형 kernel이 쓰면 손상될 수 있음을 뜻합니다. 따라서 모르는 kernel의 write mount를 막습니다. 대표적인 `SPARSE_SUPER`에서는 과거 superblock/group descriptor backup이 있던 곳에 일반 file data block을 둘 수 있습니다.

`ext2_free_blocks()`는 backup용 block을 free하지 않으므로 구형 kernel이 sparse layout을 잘못 다루면 bitmap이 불일치할 수 있습니다. 구형 kernel은 group 경계를 가로지르는 block 연속 범위를 free할 때도 오류를 내지만, `SPARSE_SUPER` 파일시스템에서는 이런 배치가 정상입니다.

`INCOMPAT` flag는 on-disk format이 구형 kernel이 읽을 수 없거나 구형 kernel의 mount 자체가 문제를 일으킬 정도로 바뀌었음을 뜻합니다. `FILETYPE`을 모르는 kernel은 filename 길이가 256자를 넘는 것으로 오해해 directory listing을 손상시킬 수 있습니다.

`COMPRESSION`을 모르는 kernel은 `read()` 때 자동 decompression을 하지 못해 압축된 garbage를 반환하므로 명백한 `INCOMPAT`입니다. ext3의 `RECOVER`는 journal을 모르는 kernel이 journal replay 없이 파일시스템을 mount하지 못하게 합니다.

`e2fsck`는 kernel보다 더 엄격합니다. `COMPAT`, `RO_COMPAT`, `INCOMPAT` 중 어떤 종류든 모르는 flag가 하나라도 있으면 해당 기능의 유효성을 검증할 방법이 없으므로 검사를 거부합니다. 알 수 없는 기능에서 검사를 성공 처리하면 사용자에게 거짓 안전감을 주기 때문입니다. 따라서 ext2에 feature flag를 추가하는 개발자는 그 기능을 검증하도록 `e2fsck`도 함께 갱신해야 합니다.

ext2 feature flag 판정
Flag구형 kernel의 허용 범위대표 예
`COMPAT`읽기와 쓰기 허용`HAS_JOURNAL`
`RO_COMPAT`읽기만 허용, 쓰기 금지`SPARSE_SUPER`
`INCOMPAT`mount/해석 금지`FILETYPE`, `COMPRESSION`, `RECOVER`
알 수 없는 flag와 `e2fsck`종류와 무관하게 검사 거부검증 불가능한 기능

모르는 기능을 만난 kernel과 e2fsck의 동작을 구분합니다.


Feature Compatibility
---------------------

The compatibility feature mechanism used in ext2 is sophisticated.
It safely allows features to be added to the filesystem, without
unnecessarily sacrificing compatibility with older versions of the
filesystem code.  The feature compatibility mechanism is not supported by
the original revision 0 (EXT2_GOOD_OLD_REV) of ext2, but was introduced in
revision 1.  There are three 32-bit fields, one for compatible features
(COMPAT), one for read-only compatible (RO_COMPAT) features and one for
incompatible (INCOMPAT) features.

These feature flags have specific meanings for the kernel as follows:

A COMPAT flag indicates that a feature is present in the filesystem,
but the on-disk format is 100% compatible with older on-disk formats, so
a kernel which didn't know anything about this feature could read/write
the filesystem without any chance of corrupting the filesystem (or even
making it inconsistent).  This is essentially just a flag which says
"this filesystem has a (hidden) feature" that the kernel or e2fsck may
want to be aware of (more on e2fsck and feature flags later).  The ext3
HAS_JOURNAL feature is a COMPAT flag because the ext3 journal is simply
a regular file with data blocks in it so the kernel does not need to
take any special notice of it if it doesn't understand ext3 journaling.

An RO_COMPAT flag indicates that the on-disk format is 100% compatible
with older on-disk formats for reading (i.e. the feature does not change
the visible on-disk format).  However, an old kernel writing to such a
filesystem would/could corrupt the filesystem, so this is prevented. The
most common such feature, SPARSE_SUPER, is an RO_COMPAT feature because
sparse groups allow file data blocks where superblock/group descriptor
backups used to live, and ext2_free_blocks() refuses to free these blocks,
which would leading to inconsistent bitmaps.  An old kernel would also
get an error if it tried to free a series of blocks which crossed a group
boundary, but this is a legitimate layout in a SPARSE_SUPER filesystem.

An INCOMPAT flag indicates the on-disk format has changed in some
way that makes it unreadable by older kernels, or would otherwise
cause a problem if an old kernel tried to mount it.  FILETYPE is an
INCOMPAT flag because older kernels would think a filename was longer
than 256 characters, which would lead to corrupt directory listings.
The COMPRESSION flag is an obvious INCOMPAT flag - if the kernel
doesn't understand compression, you would just get garbage back from
read() instead of it automatically decompressing your data.  The ext3
RECOVER flag is needed to prevent a kernel which does not understand the
ext3 journal from mounting the filesystem without replaying the journal.

For e2fsck, it needs to be more strict with the handling of these
flags than the kernel.  If it doesn't understand ANY of the COMPAT,
RO_COMPAT, or INCOMPAT flags it will refuse to check the filesystem,
because it has no way of verifying whether a given feature is valid
or not.  Allowing e2fsck to succeed on a filesystem with an unknown
feature is a false sense of security for the user.  Refusing to check
a filesystem with unknown features is a good incentive for the user to
update to the latest e2fsck.  This also means that anyone adding feature
flags to ext2 also needs to update e2fsck to verify these features.

metadata 동기화와 제한의 근거

288-320

ext2의 asynchronous metadata write가 ffs의 synchronous metadata 방식보다 빠르지만 덜 신뢰할 수 있다는 주장이 흔합니다. 그러나 두 방식 모두 각자의 `fsck` 프로그램으로 같은 수준에서 복구할 수 있다고 문서는 설명합니다.

metadata write를 synchronous하게 만드는 방법은 세 가지입니다. source code를 수정할 수 있으면 파일을 `open()`할 때 `O_SYNC` flag를 사용합니다. source가 없으면 해당 파일에 `chattr +S`를 적용합니다. 파일시스템 전체에는 `mount` 또는 `/etc/fstab`의 `sync` option을 사용합니다. 첫 번째와 세 번째 방법은 ext2 전용은 아니지만 metadata를 synchronous하게 기록하도록 강제합니다.

ext2의 여러 한계는 on-disk layout에서 오고, 일부는 당시 kernel 구현에서 옵니다. 많은 값은 파일시스템을 처음 만들 때 선택한 block size에 따라 결정됩니다.

inode와 data block의 비율도 생성 시 고정됩니다. inode 수를 늘리는 유일한 방법은 파일시스템 크기를 키우는 것이며, 이 문서 시점에는 inode 대 block 비율 자체를 바꾸는 도구가 없습니다.

대부분의 한계는 on-disk format을 조금 바꾸고 compatibility flag로 변경을 알리면 극복할 수 있지만 그만큼 구형 구현과의 호환성을 일부 잃게 됩니다.

metadata 동기 기록 방법
범위방법조건
파일별`open()`에 `O_SYNC`program source를 수정할 수 있음
파일별`chattr +S`program source 없이 적용
파일시스템 전체`mount -o sync` 또는 `/etc/fstab`의 `sync`모든 metadata write에 적용

범위와 적용 지점에 따른 세 가지 방법입니다.


Metadata
--------

It is frequently claimed that the ext2 implementation of writing
asynchronous metadata is faster than the ffs synchronous metadata
scheme but less reliable.  Both methods are equally resolvable by their
respective fsck programs.

If you're exceptionally paranoid, there are 3 ways of making metadata
writes synchronous on ext2:

- per-file if you have the program source: use the O_SYNC flag to open()
- per-file if you don't have the source: use "chattr +S" on the file
- per-filesystem: add the "sync" option to mount (or in /etc/fstab)

the first and last are not ext2 specific but do force the metadata to
be written synchronously.  See also Journaling below.

Limitations
-----------

There are various limits imposed by the on-disk layout of ext2.  Other
limits are imposed by the current implementation of the kernel code.
Many of the limits are determined at the time the filesystem is first
created, and depend upon the block size chosen.  The ratio of inodes to
data blocks is fixed at filesystem creation time, so the only way to
increase the number of inodes is to increase the size of the filesystem.
No tools currently exist which can change the ratio of inodes to blocks.

Most of these limits could be overcome with slight changes in the on-disk
format and using a compatibility flag to signal the format change (at
the expense of some compatibility).

block 크기별 수치 한계

321-350

1KiB block에서는 file size limit가 16GB이고 filesystem size limit가 2047GB입니다. 2KiB에서는 각각 256GB와 8192GB, 4KiB에서는 2048GB와 16384GB, 8KiB에서는 2048GB와 32768GB입니다.

당시 Linux 2.4 kernel은 단일 block device를 2048GB로 제한했으므로 실제로는 그보다 큰 파일시스템을 만들 수 없었습니다. block size도 kernel page size의 상한을 받으므로 8KiB block은 Alpha처럼 큰 page를 지원하는 architecture에서만 허용됩니다.

한 directory가 가질 수 있는 subdirectory의 상한은 32000개입니다. 현재의 linear linked-list directory 구현에서는 한 directory의 파일이 약 10,000~15,000개를 넘으면 생성, 삭제, 검색 성능이 나빠지는 soft limit가 있습니다.

개발 중이던 hashed directory index를 사용하면 성능 문제 없이 100,000개에서 1,000,000개 이상의 파일을 둘 수 있지만 이 정도에서는 RAM 크기가 다른 제약이 됩니다.

파일 크기만으로 계산한 의미 없는 절대 상한은 한 directory당 130 trillion files 이상입니다. 고유한 4-character name 수가 부족해 8-character filename이 필요하며, 그 경우에도 고유 이름 공간을 거의 소진합니다. 현실적인 한계는 이 값보다 훨씬 낮습니다.

ext2 크기 한계
Filesystem block size1KiB2KiB4KiB8KiB
File size limit16GB256GB2048GB2048GB
Filesystem size limit2047GB8192GB16384GB32768GB

원문의 reStructuredText 표를 동일한 값으로 다시 구성했습니다.


=====================  =======    =======    =======   ========
Filesystem block size      1kB        2kB        4kB        8kB
=====================  =======    =======    =======   ========
File size limit           16GB      256GB     2048GB     2048GB
Filesystem size limit   2047GB     8192GB    16384GB    32768GB
=====================  =======    =======    =======   ========

There is a 2.4 kernel limit of 2048GB for a single block device, so no
filesystem larger than that can be created at this time.  There is also
an upper limit on the block size imposed by the page size of the kernel,
so 8kB blocks are only allowed on Alpha systems (and other architectures
which support larger pages).

There is an upper limit of 32000 subdirectories in a single directory.

There is a "soft" upper limit of about 10-15k files in a single directory
with the current linear linked-list directory implementation.  This limit
stems from performance problems when creating and deleting (and also
finding) files in such large directories.  Using a hashed directory index
(under development) allows 100k-1M+ files in a single directory without
performance problems (although RAM size becomes an issue at this point).

The (meaningless) absolute upper limit of files in a single directory
(imposed by the file size, the realistic limit is obviously much less)
is over 130 trillion files.  It would be higher except there are not
enough 4-character names to make up unique directory entries, so they
have to be 8 character filenames, even then we are fairly close to
running out of unique filenames.

journaling 동작과 참고 자료

351-398

Stephen Tweedie가 ext2 코드용 journaling extension을 개발했습니다. 이는 on-disk ext2 layout을 바꾸지 않으면서 metadata corruption 위험과 crash 뒤 `e2fsck` 완료를 기다리는 시간을 줄입니다.

journal은 수정된 metadata block 전체와 선택적으로 data block 전체를 실제 파일시스템에 쓰기 전에 저장하는 일반 파일입니다. 따라서 기존 ext2 파일시스템도 data conversion 없이 journal을 추가할 수 있습니다.

파일 rename 같은 변경은 journal의 transaction으로 저장되며 crash 시점에 complete 또는 incomplete 상태일 수 있습니다. complete transaction의 block은 유효한 파일시스템 상태를 나타냄이 보장되어 파일시스템으로 복사됩니다.

incomplete transaction의 block은 consistency를 보장할 수 없어 모두 버립니다. 그 transaction이 나타내던 파일시스템 변경도 함께 사라집니다. ext4와 journaling의 자세한 설명은 `Documentation/filesystems/ext4/`를 확인합니다.

원문은 kernel source `file:/usr/src/linux/fs/ext2/`, `e2fsprogs`와 design 자료, ext3 journaling, filesystem resizing, compression 자료를 참조합니다. 구현 목록에는 Windows 95/98/NT/2000, Windows 95, DOS client, OS/2, RISC OS client가 포함됩니다.

각주 [1]의 Windows 95 구현과 DOS client 및 compression 자료는 2001년 4월 기준 더 이상 활발히 개발·지원되지 않았습니다. 각주 [2]의 OS/2 구현은 2009년 3월 기준 같은 상태입니다.

journal transaction 복구
수정할 metadata와 선택적 data block을 journal의 transaction에 먼저 기록정상 완료되면 transaction을 complete로 표시complete transaction의 block을 실제 파일시스템에 반영crash 뒤 complete transaction은 유효한 상태로 replayincomplete transaction은 consistency를 보장할 수 없어 폐기

변경 기록부터 crash 복구까지의 판단 흐름입니다.

ext2 참고 자료와 구현
항목경로 또는 URL
Kernel source`file:/usr/src/linux/fs/ext2/`
e2fsprogs (`e2fsck`)`http://e2fsprogs.sourceforge.net/`
Design & Implementation`http://e2fsprogs.sourceforge.net/ext2intro.html`
Journaling (ext3)`ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/`
Filesystem Resizing`http://ext2resize.sourceforge.net/`
Compression [1]`http://e2compr.sourceforge.net/`
Windows 95/98/NT/2000`http://www.chrysocome.net/explore2fs`
Windows 95 [1]`http://www.yipton.net/content.html#FSDEXT2`
DOS client [1]`ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/`
OS/2 [2]`ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/`
RISC OS client`http://www.esw-heim.tu-clausthal.de/~marco/smorbrod/IscaFS/`

원문 표의 경로와 URL을 보존해 용도별로 정리했습니다.

Journaling
----------

A journaling extension to the ext2 code has been developed by Stephen
Tweedie.  It avoids the risks of metadata corruption and the need to
wait for e2fsck to complete after a crash, without requiring a change
to the on-disk ext2 layout.  In a nutshell, the journal is a regular
file which stores whole metadata (and optionally data) blocks that have
been modified, prior to writing them into the filesystem.  This means
it is possible to add a journal to an existing ext2 filesystem without
the need for data conversion.

When changes to the filesystem (e.g. a file is renamed) they are stored in
a transaction in the journal and can either be complete or incomplete at
the time of a crash.  If a transaction is complete at the time of a crash
(or in the normal case where the system does not crash), then any blocks
in that transaction are guaranteed to represent a valid filesystem state,
and are copied into the filesystem.  If a transaction is incomplete at
the time of the crash, then there is no guarantee of consistency for
the blocks in that transaction so they are discarded (which means any
filesystem changes they represent are also lost).
Check Documentation/filesystems/ext4/ if you want to read more about
ext4 and journaling.

References
==========

=======================        ===============================================
The kernel source        file:/usr/src/linux/fs/ext2/
e2fsprogs (e2fsck)        http://e2fsprogs.sourceforge.net/
Design & Implementation        http://e2fsprogs.sourceforge.net/ext2intro.html
Journaling (ext3)        ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/
Filesystem Resizing        http://ext2resize.sourceforge.net/
Compression [1]_        http://e2compr.sourceforge.net/
=======================        ===============================================

Implementations for:

=======================        ===========================================================
Windows 95/98/NT/2000        http://www.chrysocome.net/explore2fs
Windows 95 [1]_                http://www.yipton.net/content.html#FSDEXT2
DOS client [1]_                ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/
OS/2 [2]_                ftp://metalab.unc.edu/pub/Linux/system/filesystems/ext2/
RISC OS client                http://www.esw-heim.tu-clausthal.de/~marco/smorbrod/IscaFS/
=======================        ===========================================================

.. [1] no longer actively developed/supported (as of Apr 2001)
.. [2] no longer actively developed/supported (as of Mar 2009)