ext3のファイル最大長2
ext3のファイル最大長の実装をふまえて、実際の最大サイズを計算してみました。ブロックが1K=2^10、2K=2^1×2^10、4K=2^2×2^10で、ビットシフトは10、11、12となります。
ブロックサイズが1Kの時、 17247252480(slot size)
ブロックサイズが2Kの時、 275415851008(slot size)
ブロックサイズが4Kの時、2194719883264(limit size)
#include <stdio.h> #include <stdlib.h> typedef unsigned long long u64; typedef long long l64; #define EXT3_NDIR_BLOCKS 12 void get_size(int bits); void get_limit(int bits); void main() { printf("limit size\n"); get_limit(10); get_limit(11); get_limit(12); putchar('\n'); printf("slot size\n"); get_size(10); get_size(11); get_size(12); } void get_size(int bits) { u64 res = EXT3_NDIR_BLOCKS; res += 1LL << (bits-2); res += 1LL << (2*(bits-2)); res += 1LL << (3*(bits-2)); res <<= bits; printf("%llu\n", res); } void get_limit(int bits) { u64 meta_blocks; u64 upper_limit; meta_blocks = 1; meta_blocks += 1 + (1LL << (bits-2)); meta_blocks += 1 + (1LL << (bits-2)) + (1LL << (2*(bits-2))); upper_limit = (1LL << 32) - 1; upper_limit >>= (bits - 9); upper_limit -= meta_blocks; upper_limit <<= bits; printf("%llu\n", upper_limit); }
[root@localhost test]# ./a.out limit size 2198955618304 2198484279296 2194719883264 slot size 17247252480 275415851008 4402345721856最大サイズは、limit sizeを超えないslot sizeということで以下のようになります。
ブロックサイズが1Kの時、 17247252480(slot size)
ブロックサイズが2Kの時、 275415851008(slot size)
ブロックサイズが4Kの時、2194719883264(limit size)
[root@localhost lkm]# 10to2 17247252480 0000 0000000000 0000000000 0000010000 0001000000 0100001100 0000000000 0E 0P 0T 16G 64M 268K 0 [root@localhost lkm]# 10to2 275415851008 0000 0000000000 0000000000 0100000000 1000000001 0000011000 0000000000 0E 0P 0T 256G 513M 24K 0 [root@localhost lkm]# 10to2 2194719883264 0000 0000000000 0000000001 1111111011 1111110111 1111110000 0000000000 0E 0P 1T 1019G 1015M 1008K 0資料等には、16G/256G/2Tとされていますが、厳密にいうと16G-64M-268K/256G-513M-24k/1T-1019G-1015M-1008Kサイズとするのが正しいところです。
補足(10to2コマンドです。)
// Copyright (C) Y.Kitamura #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define BIT_SIZE sizeof(long long)*8 char *get_bitstr(char * bits, char* val); void prn_bit(char* bit, int index, int size); void prn_2(char* bit); void prn_10(char* bit); int from2to10(char* bit, int size); int main(int argc, char *argv[]) { char bits[BIT_SIZE]; if (argc != 2) { printf("error:10to2 para\n"); } else { if (get_bitstr(bits, argv[1])) { prn_2(bits); prn_10(bits); } } return 0; } void prn_2(char* bit) { int i, off, index, bitsize; printf("%c%c%c%c ", bit[0], bit[1], bit[2], bit[3]); for (i = 0; i < 6; i++) { off = 4 + i*10; printf("%c%c%c%c%c%c%c%c%c%c ", bit[0 + off], bit[1 + off], bit[2 + off], bit[3 + off], bit[4 + off], bit[5 + off], bit[6 + off], bit[7 + off], bit[8 + off], bit[9 + off]); } putchar('\n'); } void prn_10(char* bit) { int i, val; char tani[] = {'P', 'T', 'G', 'M', 'K', ' '}; val = from2to10(&bit[0], 4); printf("%4dE", val); for (i = 4; i <=54; i += 10) { val = from2to10(&bit[i], 10); printf("%10d%c", val, tani[(i - 4)/10]); } putchar('\n'); } char *get_bitstr(char * bit, char* val) { int i; unsigned long long data = strtoull(val, NULL, 10); if (errno) { printf("must be less than 18,446,744,073,709,551,615\n"); return NULL; } for (i = 0; i < BIT_SIZE; i++) { bit[BIT_SIZE - i - 1] = (data & 1LL << i)? '1': '0'; } return bit; } int from2to10(char* bit, int size) { int val = 0, i; val += (bit[0] - '0'); for (i = 1; i < size; i++) { val = val << 1; val += (bit[i] - '0'); } return val; }