/* Program to seek forward and write a single byte, then stat the file. This lets us probe to find out how the file is structured. If you seek forward by N and write 1 byte, the file will have length N+1. Therefore, this code seeks forward by N-1 and writes 1 byte, so that the file size matches the argument to oneByteFile. With this definition, the last byte of any block requires a seek position that is a multiple of 4096 (the device block size on Puma). Scott D. Anderson scott.anderson@acm.org Spring 2005 */ #include #include #include /* for exit() */ #include /* for open() */ #include #include #include #include /* for sprintf */ #define BSD64 #define __USE_LARGEFILE64 #define __USE_FILE_OFFSET64 /* The following is initialized in main() */ char buf[1]; void oneByteFile(off_t position) { char buf[1]; struct stat statbuf; char filename[100]; char error_message[100]; int fd; sprintf(filename, "file%10.10ld.b", position); fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH ); if ( -1 == fd ) { sprintf(error_message, "opening %s", filename); perror(error_message); return; } /* Note the -1, so that we write to the next position, which will then be the one we want. */ if ( -1 == lseek64(fd, position-1, SEEK_SET) ) perror("seeking"); if ( -1 == write(fd,buf,1)) perror("writing"); if ( 0 != fstat(fd,&statbuf) ) perror("fstatting"); printf("%10ld => %10ld\n", position, (statbuf.st_blocks*512) / statbuf.st_blksize); if (-1 == close(fd)) perror("closing"); } int main( int argc, char* argv[] ) { long long int blk = 4096; int i; long long int pos1 = 12 * blk + 1; /* first byte of first indirect block */ long long int pos2 = blk * (12 + (blk / 4)); /* last byte of last indirect block */ long long int pos3 = pos2 + blk * (blk / 4) * (blk / 4); long long int pos4 = pos3 + blk * (blk / 4) * (blk / 4) * (blk / 4); printf("int %d long %d long long %d off_t %d\n", sizeof(int), sizeof(long), sizeof(long long int), sizeof(off_t)); printf("%12lld %12lld %12lld %12lld\n",pos1, pos2, pos3, pos4); printf("max long = %ld, max long long int = %lld\n", (long) 0x7FFFFFFF, (long long) 0x7FFFFFFFFFFFFFFF); buf[0] = 'A'; for (i = 0; i < 12; i++) { printf("first byte of block %d \t", i); oneByteFile(i * blk + 1); printf(" last byte of block %d \t", i); oneByteFile((i + 1) * blk); } printf("first byte of first indirect block\t"); oneByteFile(pos1); printf(" last byte of last indirect block\t"); oneByteFile(pos2); printf("first byte of first double-indirect block\t"); oneByteFile(pos2 + 1); printf("biggest seekable file"); oneByteFile(0x7FFFFFFF); /* the following are impossible, since lseek only takes a long printf(" last byte of last double-indirect block\t"); oneByteFile(pos3); printf("first byte of first triple-indirect block\t"); oneByteFile(pos3+1); printf(" last byte of last triple-indirect block\t"); oneByteFile(pos4); */ return 0; }