無料Wikiサービス | デモページ
検索

アクセス数
最近のコメント
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

ext3のファイル最大長


ファイルサイズは、物理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);>>トすることでブロック数に変換します。(<<9でセクタに応じた総バイト数を求めて、>>bitsでブロック数を求めます。)

meta_blocks = 1は階層1のスロット情報のためのブロックで、以下階層2でのスロット情報のブロック数、階層3でのスロット情報のブロック数で、
meta_blocksは、スロット情報を設定するためのブロックの総数となり、それを upper_limit -= meta_blocksで、upper_limitは、実データのみのブロック数となります。upper_limit <<= bitsでそのサイズです。従って物理的にupper_limitを超えたファイルサイズは作成できないということだと思いますが、そうならスーパブロックとかiノードビットマップブロックは考慮しなくていいのでしょうか? なお、ext2についても同様な実装となっていますが、upper_limitにかかる処理はインプリメントされていません。

最終更新 2014/06/21 04:03:08 - north
(2014/06/21 02:57:42 作成)