[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[fol] Re: linux で扱える最大ファイルサイズは?


佐野@浜松です。

In article <y5a3dmwb1dw.fsf _at_ kgh12351.nifty.ne.jp>,
  at "02 Jun 2000 23:31:23 +0900', I wrote:

>  generic_file_write() ってどこにあるのかな、と思って検索したら、
>  mm/filemap.c にあるんですね。これには特にサイズの制限は無さそう。

ちょっと誤解してたかも。ここで言おうとしたのは

 generic_file_write(struct file *file, const char *buf,
                   size_t count, loff_t *ppos)

なので、すくなくとも ppos は 64bit だから count が 32bit でも
繰り返し write していけば 32bit 以上書くことが可能かも、という
ことだったのですが、

        unsigned long   pos = *ppos;
        unsigned long   limit = current->rlim[RLIMIT_FSIZE].rlim_cur;

って書いてあって

        /*
         * Check whether we've reached the file size limit.
         */
        status = -EFBIG;
        if (pos >= limit) {
                send_sig(SIGXFSZ, current, 0);
                goto out;
        }

        status  = 0;
        /*
         * Check whether to truncate the write,
         * and send the signal if we do.
         */
        if (count > limit - pos) {
                send_sig(SIGXFSZ, current, 0);
                count = limit - pos;
        }


とあるので、やっぱり long が 32bit な CPU 上では 32bit で制限されて
しまうような気が。違うのかな ? 

size_t が unsigned long な alpha, ia64, mips64, 
 ppc, sparc64 については、long が 64bit (だったと思う) であれば
 64bit が制限ですね。

> 結局 2.4.x 系カーネルの ext2 fs の制限としては
> 
> /*
>  * Make sure the offset never goes beyond the 32-bit mark..
>  */
> static loff_t ext2_file_lseek(
> ...
>         if (offset<0)
>                 return -EINVAL;
>         if (((unsigned long long) offset >> 32) != 0) {
>                 if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
>                         return -EINVAL;
>         } 
> 
> だけのような感じ。

これは

static loff_t ext2_file_lseek(
        struct file *file,
        loff_t offset,
        int origin)

なので offset は loff_t なんですが、

struct file_operations ext2_file_operations = {
        llseek:         ext2_file_lseek,
        read:           generic_file_read,
        write:          generic_file_write,
        ioctl:          ext2_ioctl,
        mmap:           generic_file_mmap,
        open:           ext2_open_file,
        release:        ext2_release_file,
        fsync:          ext2_sync_file,
};

として llseek(2) で使われるものです。 device file に直接アクセス
するなら、例えば /dev/hda とかを open(2) して llseek(2) で 2GB を
超える領域まで進んで write(2) とかできていたので、ext2fs でも同様
なことができるのかも、と思ったのですが、上記のように generic_file_write
に 32bit の制限があるとすれば、それはダメかもしれません。

> で、この ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)] は
> どうも filesystem の block サイズ (1024k - 8192k) によって
> 決まり、
> 
> #define EXT2_MAX_SIZE(bits)                                                     
> \
>         (((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) +                             
> \
>            (1LL << (bits - 2)) * (1LL << (bits - 2)) +                          
> \
>            (1LL << (bits - 2)) * (1LL << (bits - 2)) * (1LL << (bits - 2))) *   
> \
>           (1LL << bits)) - 1)
> 
> static long long ext2_max_sizes[] = {
> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
> EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
> };
> 
> から計算される数値になるんじゃないかと思います。
> 
>  1024k block (10bit) なら 2^33 程度、8192k block (13bit) なら 2^45 程度、
> という感じなのかな。

これは、ext2fs 上ではこの制限を超えると llseek(2) すらできない、という
ことですので、2.4.x 系では gcc の long が 32bit な CPU 上ではもちろん、
 long が 64bit な CPU 上であっても ext2 fs 上ではファイル容量について
 full 64bit なサポートは提供してない、ということのような気がします。

過去の Linux が ext から ext2 に移行してきたように、ext2 fs も今後は
だんだん使われなくなっていって、現在開発中のより新しいファイルシステムが
メインのファイルシステムになっていく、のかも。

 # 最近 reiser FS をテストしてるって話をちょこちょこ目にするような
 # 気がするんだけど、あれはサイズの制限とかどうなってるんでしたっけ。

そういえば、最近 Visual Technologies から Alpha マシンの特価販売で
 10 万以下という話もあるみたいなので、どうしても 2GB を超えるファイル
を Linux で扱いたいという人は、そっちを試してみるというのもいいかも。

もう一台 i386 を入手して BSD 系 or Solaris 8 を使う、というほうが
おそらくコスト的には安くつくでしょうけど、full 64bit な環境という
意味では i386 以外のハードウェアというのも面白そうですよね。
Alpha なら FreeBSD や NetBSD も動くし (というか NetBSD のほうが
マルチアーキテクチャ対応という意味では大先輩なんですが)。

-- 
     #わたしのおうちは浜松市、「夜のお菓子」で有名さ。
    <sano _at_ localhost> : Taketoshi Sano (佐野 武俊)

この情報があなたの探していたものかどうか選択してください。
yes/まさにこれだ!   no/違うなぁ   part/一部見つかった   try/これで試してみる

あなたが探していた情報はどのようなことか、ご自由に記入下さい。特に「まさにこれだ!」と言う場合は記入をお願いします。
例:「複数のマシンからCATV経由でipmasqueradeを利用してWebを参照したい場合の設定について」
References: