I successfully created a big file on Linux. 2 Terabytes minus
4 Kilobytes.
Here's the session.
spindle ~> cc -o bigfile3 bigfile3.c -D_LARGEFILE64_SOURCE
spindle ~> ./bigfile3
Wrote to 1 (0x1)
Wrote to 2 (0x2)
Wrote to 4 (0x4)
Wrote to 8 (0x8)
Wrote to 16 (0x10)
Wrote to 32 (0x20)
Wrote to 64 (0x40)
Wrote to 128 (0x80)
Wrote to 256 (0x100)
Wrote to 512 (0x200)
Wrote to 1024 (0x400)
Wrote to 2048 (0x800)
Wrote to 4096 (0x1000)
Wrote to 8192 (0x2000)
Wrote to 16384 (0x4000)
Wrote to 32768 (0x8000)
Wrote to 65536 (0x10000)
Wrote to 131072 (0x20000)
Wrote to 262144 (0x40000)
Wrote to 524288 (0x80000)
Wrote to 1048576 (0x100000)
Wrote to 2097152 (0x200000)
Wrote to 4194304 (0x400000)
Wrote to 8388608 (0x800000)
Wrote to 16777216 (0x1000000)
Wrote to 33554432 (0x2000000)
Wrote to 67108864 (0x4000000)
Wrote to 134217728 (0x8000000)
Wrote to 268435456 (0x10000000)
Wrote to 536870912 (0x20000000)
Wrote to 1073741824 (0x40000000)
Wrote to 2147483648 (0x80000000)
Wrote to 4294967296 (0x100000000)
Wrote to 8589934592 (0x200000000)
Wrote to 17179869184 (0x400000000)
Wrote to 34359738368 (0x800000000)
Wrote to 68719476736 (0x1000000000)
Wrote to 137438953472 (0x2000000000)
Wrote to 274877906944 (0x4000000000)
Wrote to 549755813888 (0x8000000000)
Wrote to 1099511627776 (0x10000000000)
seek(2199023255551): Invalid argument
Wrote to 1649267441664 (0x18000000000)
Wrote to 1924145348608 (0x1c000000000)
Wrote to 2061584302080 (0x1e000000000)
Wrote to 2130303778816 (0x1f000000000)
Wrote to 2164663517184 (0x1f800000000)
Wrote to 2181843386368 (0x1fc00000000)
Wrote to 2190433320960 (0x1fe00000000)
Wrote to 2194728288256 (0x1ff00000000)
Wrote to 2196875771904 (0x1ff80000000)
Wrote to 2197949513728 (0x1ffc0000000)
Wrote to 2198486384640 (0x1ffe0000000)
Wrote to 2198754820096 (0x1fff0000000)
Wrote to 2198889037824 (0x1fff8000000)
Wrote to 2198956146688 (0x1fffc000000)
Wrote to 2198989701120 (0x1fffe000000)
Wrote to 2199006478336 (0x1ffff000000)
Wrote to 2199014866944 (0x1ffff800000)
Wrote to 2199019061248 (0x1ffffc00000)
Wrote to 2199021158400 (0x1ffffe00000)
Wrote to 2199022206976 (0x1fffff00000)
Wrote to 2199022731264 (0x1fffff80000)
Wrote to 2199022993408 (0x1fffffc0000)
Wrote to 2199023124480 (0x1fffffe0000)
Wrote to 2199023190016 (0x1ffffff0000)
Wrote to 2199023222784 (0x1ffffff8000)
Wrote to 2199023239168 (0x1ffffffc000)
Wrote to 2199023247360 (0x1ffffffe000)
Wrote to 2199023251456 (0x1fffffff000)
seek(2199023253503): Invalid argument
seek(2199023252479): Invalid argument
seek(2199023251967): Invalid argument
seek(2199023251711): Invalid argument
seek(2199023251583): Invalid argument
seek(2199023251519): Invalid argument
seek(2199023251487): Invalid argument
seek(2199023251471): Invalid argument
seek(2199023251463): Invalid argument
seek(2199023251459): Invalid argument
seek(2199023251457): Invalid argument
Filesize limit exceeded (core dumped)
spindle ~> ls -lsh a-big-file
456k -rw-r--r-- 1 kbob kbob 2.0T May 21 13:21
spindle ~> ls -l a-big-file
-rw-r--r-- 1 kbob kbob 2199023251456 May 21 13:21 a-big-file
spindle ~> bc
2^41
2199023255552
2^41 - 2199023251456
4096
spindle ~> df .
Filesystem Size Used Avail Use% Mounted on
/dev/hda1 3.7G 1.2G 2.3G 33% /
spindle ~> grep hda1 /etc/mtab
/dev/hda1 / ext2 rw,errors=remount-ro 0 0
spindle ~> cat /proc/version
Linux version 2.4.18-686 (herbert@gondolin) (gcc version 2.95.4
20011002 (Debian prerelease)) #1 Sun Apr 14 11:32:47 EST 2002
So it seems to work (though it dumped core when I seeked to the wrong
place).
The keys were:
Add the O_LARGEFILE flag to open().
Compile with -D_LARGEFILE64_SOURCE.
Use __off64_t and lseek64.
This is on a very recently updated Debian Woody system running the
distributed 2.4.18 kernel with an ext2 filesystem (!). The source
file is attached.
I hope this is useful to some of you.
--
Bob Miller K<bob>
kbobsoft software consulting
http://kbobsoft.com [EMAIL PROTECTED]
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define OFFSET 0x10000000LL
#ifndef BF_off_t
typedef __off64_t BF_off_t;
#define BF_lseek lseek64
#endif
const char filename[] = "a-big-file";
typedef enum { false = 0, true = 1 } bool;
/* write one byte of "k" just before the specified offset. */
bool writeabyte(int fd, BF_off_t offset)
{
if (offset <= 0) {
fprintf(stderr, "writeabyte: invalid argument %lld\n", offset);
exit(1);
}
if (BF_lseek(fd, offset - 1, SEEK_SET) != offset - 1) {
fprintf(stderr, "seek(%lld): %s\n", offset - 1, strerror(errno));
return false;
}
if (write(fd, "k", 1) != 1) {
fprintf(stderr, "write at %lld: %s\n", offset - 1, strerror(errno));
return false;
}
printf("Wrote to %lld (0x%llx)\n", offset, offset);
return true;
}
int main()
{
BF_off_t offset, bump;
int fd;
assert(sizeof offset == 8);
(void) unlink(filename);
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY | O_LARGEFILE, 0666);
if (fd < 0) {
perror("creat");
exit(1);
}
for (offset = 1; offset != 0; offset <<= 1)
if (!writeabyte(fd, offset))
break;
offset >>= 1;
for (bump = offset >> 1; bump != 0; bump >>= 1) {
if (writeabyte(fd, offset + bump))
offset += bump;
}
execl("/bin/ls", "ls", "-sl", filename, NULL);
perror("execl");
return 1;
}