Linuxのファイルシステムについて

# ファイルシステムとは
- **記憶装置に保存されたデータを管理し、操作するために必要なOS機能**
- ファイルシステムがないと、データを読み出す際に「〇〇セクタ（ディスク区間）を取ってきて」のような指示をしなければならない
- 主な扱う情報としては、スケーラビリティ, ジャーナル（変更記録情報）による整合性, パフォーマンス等がある
- 具体的には、「データとメタデータをある構造に従ってストレージデバイス上に格納したもの」を指す

## 主なファイルシステムの種類と特徴
- **ext2**
    - 「second extended filesystem」の略で、初期段階のlinuxシステムで使用されていた
    - ファイルサイズは2TiB, 最大ボリュームサイズは16TiB
    - ジャーナルに非対応なため、一度クラッシュすると復旧に時間がかかる
    - 2038年1月18日以降の日付に対応していない
- **ext3**
    - 「third extended file system」の略で、ext2との高い互換性があり変換も可能
    - ファイルサイズは16GiB~2TiB, 最大ボリュームサイズは2Tib~32TiB
    - ここでジャーナルが追加されている
        - ジャーナル・・・稼動中に半自動的に記録する通信記録や更新履歴などの情報
- **ext4**
    - 「fourth extended file system」の略で、現在のLinuxファイルシステムのデファクトスタンダード
    - 最大ファイルサイズは16TiB, 最大ボリュームサイズは1EiB
    - 日付範囲も1901年12月14日から2514年4月25日まで
    - 下位互換もあり、ext3としてマウントすることも可能
- **xfs**
    - CentOS7のデフォルトのファイルシステム
    - ファイルサイズは8EiB, 最大ボリュームサイズは8Eib
    - ext3、ext4からフォーマットすることでxfsへ移行できる
    - メモリを多く消費する事でパフォーマンスを出し、ファイルの読み書きが速い
- その他、**vfat**や**msdosm**, **zsf**等がある

※GiB=2^30, TiB=2^40, EiB=2^60

## VFS（Virtual File System）とは
- Linuxにおけるファイルシステムの規約
- 統一的にファイルシステムを操作できるためのインターフェイスの種類
- ファイルシステムごとの細かな違いを意識することなく共通の方法でファイルやディレクトリに対する基本的な操作を行うことができる

## システム構造
ファイルシステムは、主に以下のブロックから作成される

- ブートブロック
    - OSを起動する情報を保存するブロック
    - 常に先頭に位置し、全てのファイルシステムで空きスペースとして占めている
- スーパブロック
    - ブートブロックの直後に位置する1ブロックの領域
    - i-nodeテーブルサイズ, 論理ブロックサイズ, 論理ブロック数を保存するために利用される
- i-nodeテーブル
    - ファイルシステム内における全てのディレクトリ、ファイルにはi-nodeテーブルで1エントリが占められている
- データブロック
    - ファイルシステムの大半を占めるブロックで、ファイル、ディレクトリを構成する情報を保持する

# i-nodeとは
- **i-nodeはファイルシステムにおけるデータ構造のことで、index-nodeの略**
- 1ファイル、1ディレクトリごとにi-nodeテーブルの1エントリが使用され、1:1対応の管理情報のことを指す
- i-node内には、以下のような情報が保存され、それぞれのi-nodeにはiナンバというユニークな識別番号が付与される
    - ファイルの長さ（バイト数）
    - デバイスID（ファイルを格納しているデバイスを識別）ファイル所有者のユーザーID
    - ファイルのグループID
    - ファイルシステム内でファイルを識別する inode 番号
    - ファイルモード（ファイルパーミッション）
    - 最終inode更新時(ctime)、最終ファイル更新時(mtime)、最終参照時(atime) を示すタイムスタンプ群
    - そのinodeを指すハードリンクがいくつあるかを示す参照カウント
- i-nodeはファイルの属性を管理するがファイル名に関しては別のリストで管理されている

## i-nodeを使用したファイルシステムの構成図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/191919/269c38d2-bc94-6bce-af64-bb47978c3eeb.png)

- 図のように、i-node内に保持するデータブロックへのポインタにより、ファイルデータを持つデータブロックを特定することができる
- これにより、ファイルは連続したブロックを保持する必要がないためディスクを効率良く使用することができ、小さいサイズのファイルに対して低レイテンシ（=通信の遅延時間）でアクセスが可能となっている

## 現在のiノード（inode）領域の使用状況を確認する方法

```
$df -i
```

各フィールドの内容はそれぞれ以下となる

- inodes : そのデバイスで作成できるinodeの限界値
- IUsed : 現在のinode使用量
- IFree : 残り作成できるinode数
- IUse : inodeの使用率（％）

## ファイル・ディレクトリのiノード（inode）番号の確認
上記同様、iオプションをつけることで確認することができる

```
$ls -li
```

## 処理内容の理解
例 : cat kamihork.txtする場合
1. ディレクトリからkamihork.txtと対になる`iナンバ`を特定する
2. `特定したiナンバ`を用いて、i-nodeテーブルから該当する`i-node`を取り出す
3. `i-node中のブロック番号`を取得する
4. ディスク領域で`ブロック番号`が指す箇所を参照
5. その箇所にあるファイルの実態を参照し、出力

### i-nodeで指定できるブロック番号
- 基本的には上記の動きだが、高画質の画像や動画であるとファイルサイズが1ブロックに収まらないため複数ブロックを参照する必要がある
    - 例えば、Linuxにおけるext3はi-nodeのブロック番号を12個まで指定することができる

### 関節指定ポインタ
- 大きいファイルサイズを取得するような場合は、関節指定ポインタを利用するケースがある
- 例えば1つのブロックの上限が1024byteとしても、このブロックに他のブロックを参照する4byteのポインタを256個入れ、これを再帰的に行うことでより大きいファイルサイズにも対応することができる


# mountとは
[ファイルシステム](https://qiita.com/kamihork/items/fbcd116a631324aae05d)を指定したディレクトリ（マウントポイント）と一時的に結びつけてアクセスできるようにするコマンド

## マウント方法
仮に、hoge-deviceというUSBをLinux上でマウントする際は以下の手順で確認することができる。

- dmesgコマンドにより、デバイスが認識されていることを確認する。 `$ dmesg | grep hoge-device`
- 確認した媒体に対してマウントを行う `$ mount /dev/hoge-device /my-mnt`
- マウントの確認 `$ ls my-mnt`
- マウント情報を確認 `$ df -th`

## アンマウント方法
Windowsでいう、タスクバーの「ハードウェアを安全に取り外す」に該当する。
unmountせずに取り外すとファイルシステムの破損に繋がるため気をつける必要がある。

- アンマウント `$ umount /my-mnt`
- マウント情報を確認 `$ df -th`

また、アンマウントできない時に確認する手段としてlsofコマンドがある。
これにより、アクセスをかけているプロセスIDや、そのユーザ名を確認することができる。

- `$ lsof /my-mnt`

## マウントの主なオプション
上記の通り、`mount [オプション] [デバイス] [ディレクトリ（マウスポイント）]` として指定できる。

### 基本的なオプション

| option | 説明 |
|:--|:--|
| -a | /etc/fstabに記載されているファイルシステムをマウント |
| -F | aオプションと合わせて利用。新しくマウントプロセスを生成 |
| -r | ファイルシステムを読み込み専用でマウント |
| -w | ファイルシステムを読み書き可能なモードでマウント |
| -t ファイルタイプ | ファイルタイプを指定 |
| -o マウントオプション | マウントする際のオプションを指定 |

### マウントオプションの指定による詳細なオプション

| option | 説明 |
|:--|:--|
| async | I/Oの非同期化 |
| exec | バイナリの実行を許可 |
| remount | マウントされているファイルシステムを再マウント |
| ro | ファイルシステムを読み込み専用でマウント |
| rw | ファイルシステムを読み書き可能なモードでマウント |
| sync | I/Oが同期化 |

## OS再起動後もmountさせる方法
通常、例えばHDD等の固定デバイスについては、システム起動時に自動的にマウントするように設定されている。
これは、`/etc/fstab`というファイルに設定を記述することで実現できる。

fstab内には以下のような記述が記載される
`/dev/sdb5 /mnt/diskA ext4 defaults 0 0`

| フィールド | 記述内容 |
|:--|:--|
| 第1フィールド | 対象デバイスファイル |
| 第2フィールド | マウントポイント |
| 第3フィールド | ファイルシステム名 |
| 第4フィールド | マウントオプション ※オプションが複数ある場合はカンマ区切りで入力 |
| 第5フィールド | ファイルシステムをdumpコマンドがダンプする必要があるかを記述 |
| 第6フィールド | fsckがブート時にファイルシステムのチェックを実行する順序を決定するための参照 |

なお、fsckとはファイルシステムを検査、修復するコマンド。

# 参考
- [Linuxファイルシステムをまとめてみました](https://qiita.com/sion_cojp/items/c8e015db39ddbf43012e)
- [Linuxのファイル種類と作成方法まとめ](https://eng-entrance.com/linux-make-filesystem)
- [知っておきたいLinuxファイルシステムの概念](https://qiita.com/tutuz/items/539d429729d5819de0aa)
- [VFSとファイルシステムの基礎技術](http://www.atmarkit.co.jp/ait/articles/0305/20/news002.html)
- [Kazumax 自宅でLinuxサーバー i-nodeとは](http://kazmax.zpp.jp/linux_beginner/inode.html)
- [はうすてんぼぶ i-nodeの理解を深める](http://bob-mk2.hateblo.jp/entry/2012/09/12/005550)
- [エンジニアの入り口 Linuxのマウント](https://eng-entrance.com/linux-mount)
- [mount - ファイルシステムをマウントする - Linuxコマンド](https://webkaru.net/linux/mount-command/)
- [Linux ハードディスクをマウント（mount）する](http://kazmax.zpp.jp/linux_beginner/mount_hdd.html)