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

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

ファイル最大長


ファイル最大長は、ブロックサイズ/ブロックビット長で決定されファイルシステムに依存しますが、カーネルとしてサポートする最大長さを超えてはいけません。カーネルとしてサポートする最大長は以下の通りです。
#define PAGE_SHIFT      12
#define PAGE_SIZE       (1 << PAGE_SHIFT)
#define PAGE_CACHE_SIZE         PAGE_SIZE

#define MAX_NON_LFS     ((1UL<<31) - 1)

#if BITS_PER_LONG==32
#define MAX_LFS_FILESIZE        (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1) 
#elif BITS_PER_LONG==64
#define MAX_LFS_FILESIZE        0x7fffffffffffffffUL
#endif
O_LARGEFILEでない時、
MAX_NON_LFS=((1UL<<31) - 1)=2^30x2^1 - 1 = 2G - 1
O_LARGEFILEの時
・longが32ビットの時
MAX_NON_LFS= (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
           = 2^12x2^31 - 1 
           = 2^40x2^3 - 1
           = 8T - 1
・longが64ビットの時
MAX_NON_LFS=(((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
           = 2^12x2^63 - 1
           = 2^70x2^5 - 1
           = 32Z - 1
ですが、32Z - 1は64ビットのサイズを超えてしまうので、64ビットの符号有りの最大値となり
MAX_NON_LFS= 0x7fffffffffffffffUL
           = (((u64)1 << (BITS_PER_LONG-1))-1)
           = 2^63 - 1 
           = 2^60x2^3 - 1
           = 8E - 1
ファイルサイズはstruct super_blockのloff_t s_maxbytesに設定され、loff_tはlong long型で64ビット故、32ビット/64ビットに関係なく、O_LARGEFILE時も0x7fffffffffffffffULとしてもいいのではと。思ってしまいます。

ファイルの参照は、ファイルそのもの実装だけでなくキャッシュサイズにも影響されます。キャッシュを超えるファイルサイズを参照すると、意味もなくキャッシュ設定/破棄を繰り返すことになり、従ってファイルサイズはキャッシュサイズを超えないようになっています。

キャッシュサイズはpage->indexにstruct fileのf_posをpageサイズ毎の位置をインデックスとし、page->indexをradix treeのインデックスとしてに設定していきます。従ってpage->indexを超えるpageを設定することはできない故の設定となっています。

page->indexの型はunsigned longで、故32ビット時は、ファイルサイズは(((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)で最大キャッシュサイズとなっているのではと思います。たぶん。

なお、f_posの型はloff_tでlongです。page->indexの型はunsigned longですが、pageを管理する場合、f_posのlong型でのサイズとなり、PAGE_CACHE_SIZEをシフトする処理で、BITS_PER_LONG-1としています。

補足

ファイルサイズの変更は、inode->i_sizeを更新します。32ビットでlongが64ビットの時、inode->i_sizeを参照/更新は、ロックして処理しなければならなくなります。
static inline void i_size_write(struct inode *inode, loff_t i_size)
{
#if BITS_PER_LONG==32 && defined(CONFIG_SMP)
       write_seqcount_begin(&inode->i_size_seqcount);
       inode->i_size = i_size;
       write_seqcount_end(&inode->i_size_seqcount);
#elif BITS_PER_LONG==32 && defined(CONFIG_PREEMPT)
       preempt_disable();
       inode->i_size = i_size;
       preempt_enable();
#else
       inode->i_size = i_size;
#endif
}

単位は以下の通りです。
2^10:K(キロ)
2^20:M(メガ)
2^30:G(ギガ)
2^40:T(テラ)
2^50:P(ペタ)
2^60:E(エクサ)
2^70:Z(ゼタ)
2^80:Y(ヨタ)

最終更新 2014/06/04 12:05:00 - north
(2014/06/03 23:56:32 作成)