ext3のファイル最大長
Rev.1を表示中。最新版はこちら。
ファイルサイズは、物理inodeに設定できるブロックスロットの総数で決まり、最大サイズはブロックスロット総数×ブロックサイズとなります。ext3ファイルシステムマウント時、ext3_fill_super()で、struct super_blockのメンバs_maxbytesに、ext3_max_size()で取得したファイルの最大サイズ値を設定されます。
ext3のスロットは4バイトで、直接設定できる12個のスロットに、1階層ノード、2階層ノード、3階層ノードを1つづつ有しています。階層となるノードのブロックIDが設定され、従って、下位層はブロックサイズに応じたスロット数ないしノード数を有することになります。ビット演算でのこなれた実装のため、取っ付き難いかもしれませんが、実態はいたってシンプルです。
static int ext3_fill_super (struct super_block *sb, void *data, int silent) { : sb->s_maxbytes = ext3_max_size(sb->s_blocksize_bits); : }bitsはビットシフトでのブロックサイズです。まずresにスロット数を加算していきます。
res = EXT3_NDIR_BLOCKSは直接のスロットID数です。 res += 1LL << (bits-2)は1階層でのスロットID数です。 res += 1LL << (2*(bits-2))は2階層でのスロットID数です。 res += 1LL << (3*(bits-2))は3階層でのスロットID数です。bits-2でシフトするのは、まず<<bitsで、ブロックサイズとし、<< -2で1スロット4バイトのため、ブロックサイズを4バイトで除算することで、ブロックサイズに有するスロット数を算出することになります。それを1/2/3階層に応じて求めます。
で、resは総スロット数となり、1スロットが1ブロックで、res <<= bitsで総サイズとなります。
#define EXT3_NDIR_BLOCKS 12 static loff_t ext3_max_size(int bits) { loff_t res = EXT3_NDIR_BLOCKS; int meta_blocks; loff_t upper_limit; upper_limit = (1LL << 32) - 1; upper_limit >>= (bits - 9); meta_blocks = 1; meta_blocks += 1 + (1LL << (bits-2)); meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2))); upper_limit -= meta_blocks; upper_limit <<= bits; res += 1LL << (bits-2); res += 1LL << (2*(bits-2)); res += 1LL << (3*(bits-2)); res <<= bits; if (res > upper_limit) res = upper_limit; if (res > MAX_LFS_FILESIZE) res = MAX_LFS_FILESIZE; return res; }上で求めたresサイズは、ファイルシステムとしての最大値upper_limit以下でなければなりません。またページキャッシュに依存するカーネルとしての最大サイズ以下でなければなりません。
補足
upper_limit = (1LL << 32) - 1は、LBAが32ビットということではないでしょうか。でupper_limitがファイルシステムとしての最大容量ということです。LBAということでセクタ数(通常512バイト)で、それを (bits - 9);シフトすることでブロック数に変換します。meta_blocks = 1は階層1のスロット情報のためのブロックで、以下階層2でのスロット情報のブロック数、階層3でのスロット情報のブロック数で、
meta_blocksは、スロット情報を設定するためのブロックの総数となり、それを upper_limit -= meta_blocksで、upper_limitは、実データのみのブロック数となります。upper_limit <<= bitsでそのサイズです。従って物理的にupper_limitを超えたファイルサイズは作成できないというわけです。たぶん。