ls -li
これは VFAT ファイルシステムへのコマンドの出力です。
% ls -li
合計 736
1207 drwxr-xr-x 3 root root 16384 3月 10 10:42 efi
1208 -rwxr-xr-x 1 root root 721720 3月 22 14:15 kernel.bin
1207
1208
ディレクトリとファイルのinode番号。ただし、VFATファイルシステムにはinodeの概念はありません。
Linuxは、inodeの概念を持たないファイルシステムのファイルにinode番号をどのように割り当てますか?
ベストアンサー1
tl;dr: 仮想、揮発性、または inode 独立ファイルシステムの場合、inode 番号は通常、inode が生成されると単調に増加する 32 ビットカウンタで生成されます。残りのinode(権限など)は、基本ファイルシステムの同等のデータから構築された場合、または{uid,gid}=
そのような概念が存在しない場合は、インストール時に設定された値(たとえば)に置き換えられます。
タイトルの質問(つまり、抽象的にLinuxがinodeの概念を持たないファイルシステムにinode番号を割り当てる方法)に答えるには、ファイルシステムによって異なります。一部の仮想またはinodelessファイルシステムでは、inode番号はget_next_ino
インスタンス化時にプールから取得されます。しかし、ここには多くの問題があります。
get_next_ino()
32ビットinode番号は64ビットカーネルでも使用されます。なぜなら、従来の32ビットユーザー領域処理はそうではないからです_FILE_OFFSET_BITS=64
。get_next_ino()
複数のファイルシステムで使用されるグローバル増分カウンタであるため、オーバーフローのリスクがさらに増加します。
この質問も私の理由の一つです。昨年、tmpfsはget_next_inoがサポートしているinodeから離れていました。。
したがって、tmpfsは、ほとんどの揮発性または「ノードレス」ファイルシステム形式の例外です。get_next_ino
5.11以降、ソケット、パイプ、ランプなどは依然としてこのプールを使用しています。
FATファイルシステムに関する具体的な質問は、fs/fat/inode.c
FATファイルシステムに割り当てられたinode番号はどこですか?内部を見るとfat_build_inode
(源泉):
struct inode *fat_build_inode(struct super_block *sb,
struct msdos_dir_entry *de, loff_t i_pos)
{
struct inode *inode;
int err;
fat_lock_build_inode(MSDOS_SB(sb));
inode = fat_iget(sb, i_pos);
if (inode)
goto out;
inode = new_inode(sb);
if (!inode) {
inode = ERR_PTR(-ENOMEM);
goto out;
}
inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
inode_set_iversion(inode, 1);
err = fat_fill_inode(inode, de);
if (err) {
iput(inode);
inode = ERR_PTR(err);
goto out;
}
fat_attach(inode, i_pos);
insert_inode_hash(inode);
out:
fat_unlock_build_inode(MSDOS_SB(sb));
return inode;
}
これは基本的に次のように言います。
- このスーパーブロックのFAT inode生成ロックを取得します。
- スーパーブロックのこの位置にインデックスノードがすでに存在することを確認してください。そうであれば、インデックスノードはロック解除され、返されます。
- それ以外の場合は、新しいインデックスノードを作成します。
- inode番号を取得します
iunique(sb, MSDOS_ROOT_INO)
(後で詳しく説明します)。 - 同等のFATデータ構造から残りのinodeを埋めます。
inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
ここで inode 番号を設定します。iunique
(源泉)は、与えられたスーパーブロックに対して一意のinode番号を提供するファイルシステムに依存しない関数です。これは、スーパーブロック+ inodeベースのハッシュテーブルと単調に増加するカウンタを使用してこれを行います。
ino_t iunique(struct super_block *sb, ino_t max_reserved)
{
static DEFINE_SPINLOCK(iunique_lock);
static unsigned int counter;
ino_t res;
rcu_read_lock();
spin_lock(&iunique_lock);
do {
if (counter <= max_reserved)
counter = max_reserved + 1;
res = counter++;
} while (!test_inode_iunique(sb, res)); /* nb: this checks the hash table */
spin_unlock(&iunique_lock);
rcu_read_unlock();
return res;
}
この点で、これは前述のものと非常によく似ていますget_next_ino
。グローバル(パイプ、ソケットなど)ではなくスーパーブロックごと、基本ハッシュテーブルに基づくいくつかの衝突防止保護機能があります。get_next_ino
従来のアプリケーションで EOVERFLOW を試して防止する方法として 32 ビット inode 番号を使用する動作も継承するため、inode64
今後は 64 ビット inode 修正 (前述の tmpfs 実装など) が必要なファイルシステムが増える可能性があります。
結論として:
- ほとんどの仮想またはinodelessファイルシステムは、単調に増加するカウンタを使用してinode番号を表します。
- このカウンタは、オンディスクノードレスファイルシステム*の場合でも不安定です。ファイルシステムに他の変更なしで再マウントすると、変更されることがあります。
- この状態のほとんどのファイルシステム(tmpfsを除く
inode64
)はまだ32ビットカウンタを使用しているため、過度に使用するとカウンタがオーバーフローし、冗長inodeが発生する可能性があります。
* ...公平に言えば、これは次のファイルシステムの場合でも契約上適用されます。するinodeが変更されたときの概念があります。i_generation
inode 番号は通常、物理的な場所または同様のものに関連しているため、実際には発生する可能性はありません。