【OS入門#2】Operating Systemを学習:ファイルシステムについて
はじめに
前回、OSとは何かというところから、大まかな仕組みを書きましたが、今回はファイルシステムについて書いていこうと思います。前回同様に、Operating System Concepts 10th Editionを参考にしています。ぜひ前回の記事も一緒に読んでいただけると幸いです。
ファイルシステム(file system)
参考にしている恐竜本には以下のように整理されている:
"File systems are implemented as part of the operating system, specifically in the kernel."
"A file system is normally organized into directories for easy navigation and usage. It provides mechanisms for file creation, deletion, reading, writing, and permissions."
つまり、ストレージ上のデータを論理的に構造化し、ユーザやアプリケーションがファイル・ディレクトリという形でアクセスできるようにする仕組みのことをファイルシステムと呼んでいる。
物理的なディスクはただのセクタの集まりであり、ストレージ(HDD/SSD)はバイト列としてデータを保存これに意味ある単位であるファイル名、フォルダ構造を与えるのがOSの役目である。例えば、diskのブロック12345〜12360
をファイルシステムを用いることで、/home/download/hello_world.py
のように扱うことができるのである。
ここらわかるように、ファイルシステムでは、以下の役割を担っている:
- ファイルに人間が読める名前(パス)を与える名前付け
- 階層構造(/etc/, /home/ など)で整理する構造化
- 空き領域・使用中領域を追跡(BitMapやFATなど)する記憶領域管理
- 誰が読み書きできるか(パーミッション)を管理するアクセス制御
- クラッシュ時に整合性を保つ(例:ジャーナリング)整合性維持
- エラー訂正・冗長化(RAIDなど)信頼性
さらにアプリケーションからみたファイルシステムはどうなっているのだろうか?例えばPythonにて以下のコードを実行したとする:
with open("data.txt", "w") as f:
f.write("hello")
このopen()
やwrite()
は、OSが提供するファイルシステムインタフェース(システムコール)を通じて、実際のブロックデバイスにアクセスしており、OSの中核として、つまりkernelの一部の機能として、ファイルシステムは「アプリケーションとハードウェアの橋渡し」をしている。
実際のファイルシステムはOSのカーネルの中(VFS: Virtual File System)にあり、実際のファイルシステムの実装(ext4, NTFS, FAT32など)はプラグインのようにVFSに接続されている。
ここでVFSとは、仮想ファイルシステムであり、複数の異なるファイルシステムを統一的に扱うことができる。アプリケーションから見ればすべて「ファイル」でしかなく、そこからシステムコールを通してカーネル内のファイルシステムがそれを受け取り、ブロックデバイス(ディスク)に実際に書き込むという流れである。
ファイルシステムの操作とコマンド
"Users and programs access files through the file system interface, which abstracts the physical storage into logical units."
ファイルシステムは、単なるデータ保存領域ではなく、OSを介して論理的・構造的にデータを扱うための重要なインターフェースである。ユーザーが日常的に行う操作——ファイルの作成・削除、検索、コピー、権限変更などは、すべてカーネル内のファイルシステムAPIに接続されたコマンド群を通じて実現されている。
これらはユーザー空間からカーネルのファイルAPIを一様に呼び出している。
ここではコマンドを紹介しないが、UNIXコマンドを理解し使いこなすことで、ファイルシステムの動作原理やパフォーマンス特性、さらにはカーネルとの接点までも直感的に把握できるようになると思う。これらの知識はOSの内部設計の理解にも直結するので試してみて!!!
ファイルの種類と属性
"Each file is associated with a set of attributes maintained in the file system structure, such as file type, permissions, owner ID, group ID, size, timestamps, and more."
ファイルとは単なるバイト列の集まりではなく、OSによって明確な「タイプ」と「属性(メタデータ)」が与えられており、これらの情報はファイルシステムによって管理され、カーネルを通じてユーザーに提供される。
ファイルの種類
Unixではすべてを「ファイル」として扱う設計哲学のもと、ファイルは以下のように分類される:
- 通常ファイル(regular file):テキストファイル、実行ファイル、画像、ログなど、一般的な内容を持つファイル。
- ディレクトリ(directory):ファイル名とi-node番号の対応表を保持する特殊ファイル。
- シンボリックリンク(symbolic link):他のファイルへのパスを記録した参照ファイル。異なるファイルシステム間でも使用できる。
- キャラクタデバイスファイル(character device):1文字単位でのデバイス入出力(例:キボード、端末)。
- ブロックデバイスファイル(block device):ブロック単位のI/Oを行う記憶装置(例: HDD, SSD)。
- ソケットファイル(socket):プロセス間通信のためのエンドポイント。
- 名前付きパイプ(FIFO):一時的なプロセス間通信に使われるファイル。
メタデータ(Metadata)の役割
メタデータとは、ファイルそのものではなくファイルに関する情報を指す。これらの情報は、ファイルシステムがファイルを管理し、制御するための基盤となる。
主なメタデータには以下のようなものがある:
- 所有者(User ID)およびグループ(Group ID):誰がそのファイルを作成・管理しているかを示す
- アクセス権限(パーミッション):読み取り(r)、書き込み(w)、実行(x)の可否を、所有者・グループ・その他ユーザー別に設定
- ファイルサイズ:バイト単位でのファイル内容の長さ
- タイムスタンプ:最終アクセス時刻、更新時刻、i-node変更時刻など
- リンク数(link count);同じi-nodeを指しているファイル名(ハードリンク)の数
Unixにおけるファイルシステム構造:i-node
“In UNIX systems, a file is represented by an i-node. The directory structure stores the mapping between filenames and i-node numbers. This separation allows multiple filenames (hard links) to point to the same i-node.”
UNIX系のファイルシステムの中核には、i-node(index node) という仕組みがあり、これは、ファイルの内容そのものではなく、ファイルに関する「メタデータと場所情報」 を保持する構造体である。i-nodeを理解することは、UNIXのファイル管理の本質を知るうえで非常に重要だ。i-nodeが保持している情報として以下のようのものがある:
- ファイルの種類(通常ファイル・ディレクトリなど)
- 所有者(UID)、グループ(GID)
- アクセス権限(パーミッション)
- サイズ(バイト数)
- 最終アクセス・更新時刻
- データブロックへのポインタ
- リンクカウント
ここで重要なこととして、i-nodeはファイル名を保持しない。ファイル名はディレクトリファイルに保存されており、ファイル名 → i-node番号 という対応があるだけである。また、ここでのディレクトリファイルは実体としては 「ファイル名 → i-node番号」のマップ を格納した通常ファイルである。
Unixでは、「すべてのものをファイルとして扱われる」 という哲学により統一されたインターフェース設計により、UNIXのI/Oは非常に柔軟で強力なものとなっている。
現代のファイルシステム技術:ジャーナリングとSSD対応
“Journaling file systems record the intent of changes to the file system in a log before applying the changes, allowing them to quickly recover from crashes.”
現代のコンピュータ環境では、システムの安定性やストレージ性能の向上が求められる中で、ファイルシステムにも高度な機能が取り入れられている。その代表例がジャーナリングファイルシステム(Journaling File System) と、フラッシュメモリ(SSD) に最適化された技術である。
ジャーナリングファイルシステムとは
ジャーナリングファイルシステムの目的は、 システムクラッシュ時のデータ損失・整合性の崩壊を防ぐことである。通常のファイルシステムでは、[ユーザー操作] → ファイルに書き込む → ディスクに保存 → 完了
のような流れでデータが書き込まれる。
しかし、書き込み途中で電源が落ちるなどしてしまうと、i-nodeだけ更新されて中身が未書き込みという状態になってしまったりなど、整合性が崩壊してしまう。
そこでジャーナリングシステムでは、先ほどのファイルシステムの[ユーザー操作] → ファイルに書き込む
という手順の間に、ジャーナル領域に「何をどう書くか」を記録という工程を挟む。そうすることで、クラッシュ後もOSはジャーナルを読み直し、中途半端な操作をロールバックまたはリプレイして整合性を保てるようになる。
ジャーナリングファイルシステムには以下のようなものがある:
- Write-back:メタデータのみジャーナルに記録(高速だが不完全)
- Write-through:メタデータ+データ両方を記録(安全だが低速)
- Ordered:メタデータが先にジャーナルに記録され、データは直後に通常書き込み(バランス型)
フラッシュメモリ(SSD)とファイルシステムの関係
SSDの特徴として、不揮発性(電源を切っても内容が保持される)、ランダムアクセスが高速、**書き込み回数に制限がある(書き換え劣化)**などがある。そうしたSSDに対応するファイルシステムは以下のような配慮が必要となる。
- ウェアレベリング:特定のセルだけが書き換えられ続けないよう、内部的に分散書き込み
- ガベージコレクション:書き換え不能な領域のクリーンアップ処理
- Trimコマンドのサポート:OSから不要ブロックをSSDに通知して再利用可能にする
- F2FS (Flash-Friendly FS):Samsungによって開発されたSSDに特化したファイルシステム
FAT, NTFS, HFS+ など各種ファイルシステムの比較
OSごとに採用されているファイルシステムには、それぞれ設計思想や機能、性能、互換性に違いがある。ここでは代表的なファイルシステムである FAT, NTFS, HFS+, ext系, F2FS を中心に、その特徴を簡単に比較する。
- FAT32:高い互換性を持つが、信頼性・機能面は貧弱
- NTFS:Windows向けの高機能FS。パーミッションやジャーナリングが強力
- HFS+:macOS専用設計。メタデータ重視の構造
- ext4:Linuxで最も一般的な安定・高速なファイルシステム
- F2FS:フラッシュメモリに最適化された最新ファイルシステム
用途や環境によって、適切なファイルシステムを選ぶことが、性能・安定性・互換性を高める鍵になる。
シンボリックリンクとハードリンクの違い
“A symbolic link is a file that contains the name of another file. Unlike hard links, symbolic links can cross file systems and refer to directories. However, they become invalid if the target file is deleted.”
UNIX系ファイルシステムの大きな特徴のひとつが、リンク(Link)機能である。これは1つのファイルに対して複数の名前をつける、または別のファイルへの参照を作成するための仕組みであり、ハードリンク(Hard Link)とシンボリックリンク(Symbolic Link) の2種類がある。
この2つは機能や内部構造が大きく異なるため、下で説明する。
ハードリンクの特徴として、同じi-node番号を持つ複数のファイル名であり、これは実体(データブロック)は共有、名前だけが異なる。ここで、ファイル名の一方を削除しても、他方が存在していれば中身は残る。
また、制限としては、循環参照を防ぐためディレクトリには作れず、異なるファイルシステムをまたげない。
シンボリックリンクとは、ファイルへのパス情報(文字列)を保持する特殊ファイルであり、実体とは異なるi-node番号を持ち、元のファイルが消えると「リンク切れ」になる。
参考文献
- Abraham Silberschatz, Peter B. Galvin, Greg Gagne, Operating System Concepts, 10th Edition, Wiley, 2018.: https://amzn.to/44zHODM
Discussion