Ext/Ext3/Ext4ファイルシステム

はじめに

第20章はじめに

ファイルシステムのextファミリーは、初期の頃からLinux固有であり、利用可能な選択肢の中で最も広く使用されています。ごく最近まで、ext4は、パフォーマンス、整合性、安定性の優れた組み合わせにより、Linuxディストリビューションで最も頻繁に使用されるデフォルトの選択肢でした。


学習目標
この章の終わりまでに、次のことができるようになります。

ext4ファイルシステムの主な機能と、それがディスク上にどのように配置されるかを説明できます。
ブロック グループ、スーパーブロック、データ ブロック、inodeの概念を説明できます。
dumpe2fsとtune2fsのユーティリティを使用できます。
ext4ファイルシステムの拡張機能をリストアップできます。


Ext/Ext3/Ext4ファイルシステム

ext4ファイルシステムの機能
ext2ファイルシステム はLinuxに元々あるファイルシステムであり、すべてのLinuxシステムで使用できますが、今日ではほとんど使用されていません。ext3ファイルシステムは、最初にext2のジャーナリング機能を拡張したものです。ジャーナル ファイルの存在を除いて、ext2とディスク レイアウトが同じでした。

ext4ファイルシステムはカーネルのバージョン2.6.19で初めて登場し、バージョン2.6.28より安定版のファイルシステムとなりました。ファイル ブロックのリストの代わりに、大きなファイルに対してエクステントを使用するなど、重要な拡張機能が含まれています。エクステントは、連続した任意の数のブロックです。これらを使用すると、大容量ファイルのパフォーマンスが向上し断片化（フラグメンテーション）が減少します。ext4は、ほとんどのエンタープライズLinuxディストリビューションのデフォルトのファイルシステムですが、RHEL 7はXFSをデフォルトとして採用しています。

VFSとext2/ext3/ext4ファイルシステムは、お互いを考慮して設計されているため、機能は密接に対応しています。

ファイルシステムの構築時にはブロック サイズが選択されます。 512、1024、2048、または4096バイトにすることができます。デフォルトでは、パーティションが非常に小さい場合を除き、ハードディスク システムには4096バイトが使用されます。小さいファイルが非常に多い場合を除き、ハードディスク アクセスを最小限に抑えるという点で、ブロック サイズを大きくする方が効率的です。

Linuxカーネル メモリ管理システムでは、メモリのページに収まるのは整数個のブロックのみです。したがって、メモリのページが4KBのサイズのx86プラットフォームでは、8KBブロックを使用することはできません。

ファイルシステム上のinodeの数も調整でき、ディスク容量を節約できます。

inode予約と呼ばれる機能は、将来使用されることを期待して、ディレクトリの作成時にいくつかのinodeを予約して作成します。これにより、新しいファイルが作成されたときにディレクトリにすでにinodeが割り当てられているため、パフォーマンスが向上します。

シンボリックリンクのパス名が60文字未満の場合、いわゆる高速シンボリック リンクが作成されます。inodeに直接保存され、データ ブロックを読み取る必要がなくなります。

要約すると、ext4ファイルシステムは次のとおりです。

ext3とext2に対して後方互換性があります。
最大ファイルシステム サイズを（16TBから）1EB に、最大ファイル サイズを（2TBから）16TB に増やしています。これらの制限は、使用されている48ビット アドレッシングに起因しています。将来的には完全な64ビット アドレッシングが行われる可能性がありますが、現時点では実際には必要ありません。
ext3で32Kに制限されていたサブディレクトリの最大数を無制限に増やしています。
間接ブロック マッピングを使用する代わりに、大きなファイルを可能な限り大きなエクステントに分割します。これにより、大容量ファイルのパフォーマンスが向上し、断片化が減少します。
一度に1つのブロックではなく、一度にすべてのスペースを割り当てることができるマルチ ブロック割り当てを使用します。さらに、遅延確保でパフォーマンスを向上させることもできます。
ファイルのディスク領域を事前確保することもできます。その領域の確保は保証されており、かつその領域は連続しています。
データがディスクに書き込まれるまでブロックの割り当てを遅らせるパフォーマンス テクニックであるallocate-on-flush（遅延確保）を使用できます。
高速なfsckを使用します。これにより、ファイルシステム チェックの速度を1桁以上上げることができます。
ジャーナルのチェックサムを使用して、信頼性を向上させます。これにより、ジャーナリング中のディスクI/O待機を安全に回避できるため、パフォーマンスがわずかですが向上します。
ナノ秒単位で測定される、改良されたタイム スタンプを使用します。


ext4レイアウト
ジャーナルを除くすべてのフィールドは、リトルエンディアンの順序でディスクに書き込まれます。

ディスク ブロックはブロック グループに分割され、各グループにはinodeとデータ ブロックが隣接して格納されているため、アクセス時間が短縮されます。

データ ブロックは、実際に使用される前にファイルに事前に割り当てられます。したがって、ファイルのサイズが大きくなっても、隣接する領域はすでに予約しているため、ファイルの断片化が軽減されます。

ファイルシステムのスーパーブロックには、システムの初期化中にファイルシステムが最初にマウントされたときにチェックが必要かどうかを確認するビットフィールドが含まれています。ビットフィールドが表す状態は次のとおりです。

Clean：ファイルシステムは以前に正常にアンマウントされました。
Dirty：通常、マウントされていることを意味します。
Unknown：システムがクラッシュした場合など、正常にアンマウントされていません。

後半2つのケースでは、fsckを実行してファイルシステムをチェックし、マウントする前に問題を修正します。

スーパーブロックの他のフィールドには、ファイルシステムが最後にチェックされた日付とマウント数に関する情報が含まれ、これらの数量が調整可能な制限を超えると自動チェックが実行されます。

ファイルシステムの最初のブロックはいわゆるブート ブロックであり、パーティション ブート セクタ用に予約されています。


ext4スーパーブロックとブロック グループ
スーパーブロックには、次のようなファイルシステムに関するグローバル情報が含まれています。

マウント数と最大マウント数（マウント数は、ディスクが正常にマウントされるたびに増えます。値は最後のfsck以降に行われた回数です。）また、デフォルトで180日後にファイルシステムのチェックを強制することも、tune2fsユーティリティによって別の時間に変更することもできます。
ブロック サイズ（mkfsによって設定されるメモリのページより大きくすることはできません。）
グループごとのブロック数
未使用のブロック数
未使用のinode数
オペレーティング システムID。

図で示すように、スーパーブロックは複数のブロック グループに冗長的に保存されます。

ブート ブロックの後に、それぞれ同じサイズの一連のブロック グループがあります。各ブロック グループのレイアウトを次の図に示します。

ext3とext4ファイルシステムのレイアウト

標準のブロック グループのレイアウトはシンプルです。ブロック グループ0の場合、最初の1024バイトは未使用です（ブート セクタなどが使うため）。スーパーブロックは、ブロック グループ0を除き、最初のブロックから始まります。そして、グループ識別子といくつかのGDT（Group Descriptor Table）ブロックが続きます。これらの後に、データ ブロック ビットマップ、inodeビットマップ、inodeテーブル、データ ブロックが続きます。

最初と2番目のブロックはすべてのブロック グループで同じであり、スーパーブロックとグループ識別子で構成されています。通常の状況では、最初のブロック グループのブロックのみがカーネルによって使用されます。重複しているコピーは、ファイルシステムがチェックされているときにのみ参照されます。すべてが正常であれば、カーネルはそれらを最初のブロック グループから単にコピーします。マスター コピーに問題がある場合、正常なものが見つかるまで次へと移動し、ファイルシステム構成を再構築します。この冗長性により、ファイルシステム チェックが定期的に実行されている限り、ext2/ext3/ext4ファイルシステムが完全に壊されることはありません。

extファイルシステム ファミリーの初期のものは、各ブロック グループには、すべてのブロック グループのグループ識別子とスーパーブロックのコピーが含まれていました。しかし、現在は最適化され、すべてのブロック グループにスーパーブロックとグループ識別子のコピーがあるわけではありません。自分の環境がどうなっているかを確認するには、添付のスクリーンショットのように調べて、（適切なデバイス ノードの中の）正確な配置を確認します。コピーの制限は、sparse_super オプションを使用してファイルシステムを作成したときに起きます。このオプションはデフォルトでオンになります。

dump2fsの使用

ブロック グループの数は、グループ内の使用済みブロックと空きブロックを識別するブロック ビットマップが単一のブロックに収まる必要があるので、その範囲で表せる数に制約されます。そのため、ブロックのサイズが4096バイトの場合、ブロック グループに含めることができるブロック数は最大32K個（128MB）です。したがって、可能な限り最大のブロック グループ サイズを使用するならば、10GBのパーティションには少なくとも80のブロック グループが必要になります。

ブロック アロケータは、各ファイルのブロックを同じブロック グループ内に保持して、シーク時間を短縮しようとします。


データ ブロックとinode
データ ブロック ビットマップとinodeビットマップは、ブロックやinodeが未使用ならば0、使用中であれば1となるビットを持つブロックです。ブロック グループごとにこれらのビットマップはそれぞれ1つ存在します。

inodeテーブルには、ブロック グループ内のinodeの数を対処するために必要な多くの連続したブロックが含まれています。各inodeには128バイトが必要です。このため、4KBブロックは32個のinodeに対応できます。

オペレーティング システムに依存した情報のために予約されている領域があります。Linuxが多くの種類の非ネイティブ ファイルシステムをマウントできるのと同じように、異なるオペレーティング システムが ext2/ext3/ext4ファイルシステムをマウントする可能性があります。

💡
この構造では、inode番号自体はディスクに保存されません。その値は、ブロック グループ番号とinodeテーブル内のオフセットからすばやく計算できます。
 
ext2とext3ファイルシステムには、エクステントを使用して大きなファイルを構成する機能がまだ組み込まれていません。代わりに、inodeは、長さEXT2_N_BLOCKS=15のデータ ブロックへのポインタi_block []配列に記述されます。これを処理する方法は少し複雑です。

この配列の最初の12要素は、ファイルの最初の12個のデータ ブロックを指しています
13番目の要素は、ブロック番号の1段間接ブロックの参照に使われます。14 番目は2段間接ブロック参照、15 番目は3段間接ブロック参照に使われます。

このアルゴリズムにより、小さいファイルのアドレス指定が最速になります。たとえば、ブロック サイズが4KB の場合、48KBファイルを直接アドレス指定できます。2MBファイルには2段階参照、1GBには3段階参照、4GBファイルには4段階参照次が必要です。


dump2fs
既に説明したように、ユーティリティdumpe2fsを使用して、ファイルシステム情報（制限、機能、フラグ、その他の属性）を調べることができます。パーティションで実行すると、以下のような情報が得られます。

$ sudo dumpe2fs /dev/sda1

Filesystem volume name:  RHEL7
Last mounted on:         /
Filesystem UUID:         9d6b5801-9c7e-4c17-9068-49923952338e
Filesystem magic number: 0xEF53
Filesystem revision #:   1 (dynamic)
Filesystem features:     has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super

Filesystem flags:        signed_directory_hash
Default mount options:   user_xattr acl
Filesystem state:        clean
Errors behavior:         Continue
Filesystem OS type:      Linux
Inode count:             1908736
Block count:             7630592
Reserved block count:    381529

Free blocks:             5353383
Free inodes:             1682479
First block:             0
Block size:              4096
Fragment size:           4096
Group descriptor size:   64
Reserved GDT blocks:     1024
Blocks per group:        32768
Fragments per group:     32768
Inodes per group:        8192
Inode blocks per group:  512
Flex block group size:   16
Filesystem created:      Wed Sep 3 03:52:55 2014
Last mount time:         Fri Oct 24 09:18:58 2014
Last write time:         Fri Oct 24 09:18:58 2014
Mount count:             89
Maximum mount count:     -1
Last checked:            Wed Sep 3 03:52:55 2014
Check interval:          0 (<none>)
Lifetime writes:         103 GB
Reserved blocks uid:     0 (user root)
Reserved blocks gid:     0 (group root)
First inode:             11
Inode size:              256
Required extra isize:    28
Desired extra isize:     28
Journal inode:           8
First orphan inode:      396118
Default directory hash:  half_md4
Directory Hash Seed:     e488c43e-241c-4014-91d8-6a9d3d6c7784
Journal backup:          inode blocks
Journal features:        journal_incompat_revoke journal_64bit
Journal size:            128M
Journal length:          32768
Journal sequence:        0x00023592
Journal start:           16394 

Group 0: (Blocks 0-32767) [ITABLE_ZEROED]
    Checksum 0x2921, unused inodes 7738
    Primary superblock at 0, Group descriptors at 1-4
    Reserved GDT blocks at 5-1028
    Block bitmap at 1029 (+1029), Inode bitmap at 1045 (+1045)
        Inode table at 1061-1572 (+1061)
    22880 free blocks, 8174 free inodes, 2 directories, 7738 unused inodes
    Free blocks: 9381-9672, 10180-32767
    Free inodes: 19-8192

Group 1: (Blocks 32768-65535) [INODE_UNINIT, ITABLE_ZEROED]
    Checksum 0x473e, unused inodes 8192
    Backup superblock at 32768, Group descriptors at 32769-32772
    Reserved GDT blocks at 32773-33796
    Block bitmap at 1030 (bg #0 + 1030), Inode bitmap at 1046 (bg #0 + 1046)
    Inode table at 1573-2084 (bg #0 + 1573)
    14918 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
    Free blocks: 33797, 33800-33919, 34108-34511, 34521-34559, 34784-34815, 37053-38015, 38039- 38040, 38080-38527, 38529-38911, Free inodes: 8193-16384
.....

Group 196: (Blocks 6422528-6455295) [INODE_UNINIT, ITABLE_ZEROED]
    Checksum 0x946d, unused inodes 8192
    Block bitmap at 6291460 (bg #192 + 4), Inode bitmap at 6291476 (bg #192 + 20)
    Inode table at 6293536-6294047 (bg #192 + 2080)
    32768 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
    Free blocks: 6422528-6455295
    Free inodes: 1605633-1613824
....

Group 232: (Blocks 7602176-7630591) [INODE_UNINIT, ITABLE_ZEROED]
    Checksum 0xa174, unused inodes 8192
    Block bitmap at 7340040 (bg #224 + 8), Inode bitmap at 7340056 (bg #224 + 24)
    Inode table at 7344160-7344671 (bg #224 + 4128)
    28416 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
    Free blocks: 7602176-7630591
    Free inodes: 1900545-1908736


tune2fs
tune2fsを使用して、ファイルシステムのパラメータを変更できます。

ファイルシステムのチェックを自動で行うタイミングとなるマウント数の、最大回数（max-mount-count）を変更する場合：

$ sudo tune2fs -c 25 /dev/sda1

チェックの間隔（interval-between-checks）を変更する場合：

$ sudo tune2fs -i 10 /dev/sda1

変更可能なパラメータの現在の値を含む、スーパーブロックの内容を一覧表示する場合：

$ sudo tune2fs -l /dev/sda1

以下は実行例です。

$ sudo tune2fs -l /dev/sdb1

tune2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:  RHEL7
Last mounted on:         /
Filesystem UUID:         471dfeba-3ec7-4529-8069-2afe50762c57
Filesystem magic number: 0xEF53
Filesystem revision #:   1 (dynamic)
Filesystem features:     has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:        signed_directory_hash
Default mount options:   user_xattr acl
Filesystem state:        clean
Errors behavior:         Continue
Filesystem OS type:      Linux
Inode count:             1281120
Block count:             5120000
Reserved block count:    256000
Free blocks:             2700371
Free inodes:             1004272
First block:             0
Block size:              4096
Fragment size:           4096
Group descriptor size:   64
Reserved GDT blocks:     1024
Blocks per group:        32768
Fragments per group:     32768
Inodes per group:        8160
Inode blocks per group:  510
Flex block group size:   16
Filesystem created:      Thu Jan 15 13:24:59 2015
Last mount time:         Fri Sep 9 07:00:26 2016
Last write time:         Fri Sep 9 07:00:25 2016
Mount count:             55
Maximum mount count:     100
Last checked:            Wed Jul 20 13:53:02 2016
Check interval:          0 (<none>)
Lifetime writes:         624 GB
Reserved blocks uid:     0 (user root)
Reserved blocks gid:     0 (group root)
First inode:             11
Inode size:              256
Required extra isize:    28
Desired extra isize:     28
Journal inode:           8
First orphan inode:      1057172
Default directory hash:  half_md4
Directory Hash Seed:     f78ac45c-42d4-492b-bbf7-7e987d84bb87
Journal backup:          inode blocks


演習

課題 20.1: Defragmentation（デフラグ）

🚩
以下のPDFドキュメントに埋め込まれた外部URLにアクセスする場合は、常に右クリックして新しいタブまたはウィンドウで開いてください。直接クリックしてURLを開こうとすると、コース ウィンドウ／タブが閉じます。

【【これ以降は橋本さんの訳を挿入】】

Newcomers toLinuxare often surprised at the lack of mention of filesystem defragmentation tools, since such programs areroutinely used in the Windows world.
However, native filesystems in UNIX-type operating systems, including Linux, tend not to suffer serious problems with filesys-tem fragmentation.
This is primarily because they do not try to cram files onto the innermost disk regions where access times are faster. Instead,they spread free space out throughout the disk, so that when a file has to be created there is a much better chance that aregion of free blocks big enough can be found to contain the entire file in either just one or a small number of pieces.
For modern hardware, the concept of innermost disk regions is obscured by the hardware anyway.

Don’t do this

For SSDs defragmentation can actually shorten the lifespan of the storage media due to finite read/erase/write cycles.
On smart operating systems defragmentation is turned off by default on SSD drives.

Furthermore, the newer journalling filesystems (including ext4) work with extents(large contiguous regions) by design.
However, there does exist a tool for de-fragmenting ext4 filesystems:

$ sudo e4defrag
Usage   : e4defrag [-v] file...| directory...| device...
: e4defrag  -c  file...| directory...| device...

e4defrag is part of the e2fsprogs package and should be on all modern Linux distributions.
The only two options are:
•-v: Be verbose.
•-c: Don’t actually do anything, just analyze and report.

The argument can be:
•  A file
•  A directory
•  An entire device

例えば以下のように使います。
$ sudo e4defrag -c /var/log
<Fragmented files>                             now/best       size/ext
1. /var/log/lastlog                              5/1              9 KB
2. /var/log/sa/sa24                              3/1             80 KB
3. /var/log/rhsm/rhsm.log                        2/1            142 KB
4. /var/log/messages                             2/1           4590 KB
5. /var/log/Xorg.1.log.old                       1/1             36 KB
Total/best extents                             120/112
Average size per extent                        220 KB
Fragmentation score                            1
[0-30 no problem: 31-55 a little bit fragmented: 56- needs defrag]
This directory (/var/log) does not need defragmentation.Done.

$ sudo e4defrag  /var/log
ext4 defragmentation for directory(/var/log)
[2/152]/var/log/Xorg.2.log:     100%    [ OK ]
[3/152]/var/log/Xorg.0.log.old: 100%    [ OK ]
[4/152]/var/log/messages-20141019.gz:   100%    [ OK ]
[5/152]/var/log/boot.log:       100%    [ OK ]
[7/152]/var/log/cups/page_log-20140924.gz:      100%    [ OK ]
[8/152]/var/log/cups/access_log-20141019.gz:    100%    [ OK ]
[9/152]/var/log/cups/access_log:        100%    [ OK ]
[10/152]/var/log/cups/error_log-20141018.gz:    100%    [ OK ]
[11/152]/var/log/cups/error_log-20141019.gz:    100%    [ OK ]
[12/152]/var/log/cups/access_log-20141018.gz:   100%    [ OK ]
[14/152]/var/log/cups/page_log-20141018.gz:     100%    [ OK ]
...
[152/152]/var/log/Xorg.1.log.old:       100%    [ OK ]
Success:                        [ 112/152 ]
Failure:                        [ 40/152 ]
Try running e4defrag on various files, directories, and entire devices, always trying with -c first.

You will generally find that Linux filesystems only tend to need defragmentation when they get very full, over 90 percent or so,or when they are small and have relatively large files, like when a boot partition is used.


課題 20.2: tune2fs を使用したファイルシステム パラメータの変更

🚩
以下のPDFドキュメントに埋め込まれた外部URLにアクセスする場合は、常に右クリックして新しいタブまたはウィンドウで開いてください。直接クリックしてURLを開こうとすると、コース ウィンドウ／タブが閉じます。

Exercise 20.2: Modifying Filesystem Parameters with tune2fs

We are going to fiddle with some properties of a formatted ext4 filesystem.  This does not require unmounting the filesystem first.
In the below you can work with an image file you create as in:

$ dd if=/dev/zero of=imagefile bs=1M count=1024
$ mkfs.ext4 imagefile

or you can substitute /dev/sdaX(using whatever partition the filesystem you want to modify is mounted on) forimagefile.

1.  Using dumpe2fs, obtain information about the filesystem whose properties you want to adjust.
Display:
•  The maximum mount count setting (after which a filesystem check will be forced.)
•  The Check interval(the amount of time after which a filesystem check is forced)•  The number of blocks reserved, and the total number of blocks

2.  Change:
•  The maximum mount count to 30.
•  TheCheck intervalto three weeks.
•  The percentage of blocks reserved to 10 percent.

3.  Using dumpe2fs, once again obtain information about the filesystem and compare with the original output.

Solution 20.2

1.$ dumpe2fs imagefile > dumpe2fs-output-initial
dumpe2fs 1.42.9 (28-Dec-2013)

$ grep -i  -e "Mount count" -e "Check interval" -e "Block Count" dumpe2fs-output-initial
Block count:              262144
Reserved block count:     13107
Mount count:              0
Maximum mount count:      -1
Check interval:           0 (<none>)

2.$ tune2fs -c 30 imagefile
tune2fs 1.42.9 (28-Dec-2013)
Setting maximal mount count to 30

$ tune2fs -i 3w imagefile
tune2fs 1.42.9 (28-Dec-2013)
Setting interval between checks to 1814400 seconds

$ tune2fs -m 10 imagefile
tune2fs 1.42.9 (28-Dec-2013)
Setting reserved blocks percentage to 10% (26214 blocks)

3.$ dumpe2fs imagefile > dumpe2fs-output-final
dumpe2fs 1.42.9 (28-Dec-2013)

$ grep -i  -e "Mount count" -e "Check interval" -e "Block Count" dumpe2fs-output-final
Block count:              262144
Reserved block count:     26214
Mount count:              0
Maximum mount count:      30
Check interval:           1814400 (3 weeks)

$ diff dumpe2fs-output-initial dumpe2fs-output-final
14c14
< Reserved block count:     13107
---
> Reserved block count:     26214
29c29
< Last write time:          Wed Oct 26 14:26:19 2016
---
> Last write time:          Wed Oct 26 14:26:20 2016
31c31
< Maximum mount count:      -1
---
> Maximum mount count:      30
33c33,34
< Check interval:           0 (<none>)
---
> Check interval:           1814400 (3 weeks)
> Next check after:         Wed Nov 16 13:26:16


知識チェック

「第20章 - ext2/ext3/ext4ファイルシステム」を完遂しました。おめでとうございます。このクイズに答えて、これまでに学んだ概念の理解度をチェックしてください。

クイズ開始

問題 20.1
/dev/sda1のext3またはext4ファイルシステムで、ファイルシステム チェックを実施する間隔を180日に設定するコマンドはどれですか？

A. tune2fs -c 180 /dev/sda1
B. tune2fs -i 180 /dev/sda1
C. tune2fs -l 180 /dev/sda1



