ファイル最大長
ファイル最大長は、ブロックサイズ/ブロックビット長で決定されファイルシステムに依存しますが、カーネルとしてサポートする最大長さを超えてはいけません。カーネルとしてサポートする最大長は以下の通りです。
・longが32ビットの時
ファイルの参照は、ファイルそのもの実装だけでなくキャッシュサイズにも影響されます。キャッシュを超えるファイルサイズを参照すると、意味もなくキャッシュ設定/破棄を繰り返すことになり、従ってファイルサイズはキャッシュサイズを超えないようになっています。
キャッシュサイズは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としています。
単位は以下の通りです。
#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 #endifO_LARGEFILEでない時、
MAX_NON_LFS=((1UL<<31) - 1)=2^30x2^1 - 1 = 2G - 1O_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(ヨタ)