/* * Execution of this program creates a large (looking) file at * local system. The execution of this program stops at offset * which is just beyond what the local filesystem can support. * * In case the local filesystem is EXT2 or UFS, the triply- * indirection scheme can support up to following sizes per * filesystem basic block size: * * 512 2 GB + epsilon * 1k 16 GB + epsilon * 2k 128 GB + epsilon * 4k 1024 GB + epsilon * 8k 8192 GB + epsilon ( not without PAGE_SIZE >= 8 kB ) * * However, the basic block device layer can support only up to * 4G blocks of 512 bytes; being at safe side, lets say 2G blocks * of 512 bytes: 1024 GB without epsilon. * * The basic filesystem block size supportable at given system is * currently dependent on what the system page cache page size is. * If the filesystem basic block exceeds of the system page size, * the system does not work currently. (2.2.* series kernels.) * * * bb = sizeof(basic block) * B = bb / 4 * MaxSize = bb * (B^3 + B^2 + B + 10) * = bb^4 / 4^3 + bb^3 / 4^2 + bb^2 / 4^1 + 10 * bb * = bb^4 / 64 + bb^3 / 16 + bb^2 / 4 + 10 * bb * * The primary term (bb^4/64) yields that 16 GB for bb=1k * The 'epsilon' is all the rest, and is less than 1/250 of * the primary term for 1kB, even less for larger bb values. * * * The EXT2 (and UFS) can address up to 4G of "basic blocks", however * that limit will likely to be beyond of other limitations from other * parts of the system. * */ #include #include #include #include #define O_LARGEFILE 0100000 /* For i386 only ! */ extern loff_t llseek(int fd, loff_t pos, int whence); #define LFS "lfs-test.dat" int main() { int fd; loff_t off, pos; int rc; fd = open(LFS,O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE,0644); if (fd < 0) { perror("open('"LFS"',O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE,0644)"); exit(88); } off = 0LL; while (1) { off += 0x2000000LL; /* 32 MB */ pos = llseek(fd, off - 4LL, SEEK_SET); if (pos == (loff_t)-1LL) { fprintf(stdout,"llseek(fd,off,SEEK_SET) off=%Ld; errno=%s\n", off,strerror(errno)); break; } fprintf(stdout,"llseek(fd,off,SEEK_SET) new pos = %Ld\n",pos); if (write(fd,"01234567",8) != 8) { perror("write(fd,'....',8) failed"); break; } } close(fd); exit(99); }