wok annotate fusecloop/stuff/fusecloop.u @ rev 18828

cloop: deduplicate support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Jan 17 14:10:13 2016 +0100 (2016-01-17)
parents e63efbc6b3e3
children 74ce1799eee7
rev   line source
pascal@10932 1 --- compressed_loop.h
pascal@10932 2 +++ compressed_loop.h
pascal@18828 3 @@ -41,6 +41,80 @@
pascal@10932 4 /* data_index (num_blocks 64bit pointers, network order)... */
pascal@10932 5 /* compressed data (gzip block compressed format)... */
pascal@10932 6
pascal@10933 7 +struct cloop_tail
pascal@10933 8 +{
pascal@12214 9 + u_int32_t table_size;
pascal@10933 10 + u_int32_t index_size;
pascal@10933 11 + u_int32_t num_blocks;
pascal@10933 12 +};
pascal@10933 13 +
pascal@10932 14 +struct block_info
pascal@10932 15 +{
pascal@10932 16 + loff_t offset; /* 64-bit offsets of compressed block */
pascal@10932 17 + u_int32_t size; /* 32-bit compressed block size */
pascal@10932 18 + u_int32_t optidx; /* 32-bit index number */
pascal@10932 19 +};
pascal@10932 20 +
pascal@10935 21 +static inline char *build_index(struct block_info *offsets, unsigned long n)
pascal@10932 22 +{
pascal@10932 23 + u_int32_t *ofs32 = (u_int32_t *) offsets;
pascal@10932 24 + loff_t *ofs64 = (loff_t *) offsets;
pascal@10933 25 +
pascal@10932 26 + if (ofs32[0] == 0) {
pascal@10932 27 + if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */
pascal@10933 28 + while (n--) {
pascal@10932 29 + offsets[n].offset = __be64_to_cpu(offsets[n].offset);
pascal@10932 30 + offsets[n].size = ntohl(offsets[n].size);
pascal@10933 31 + }
pascal@12214 32 + return (char *) "128BE accelerated knoppix 1.0";
pascal@10932 33 + }
pascal@10932 34 + else { /* V2.0 */
pascal@10933 35 + loff_t last = __be64_to_cpu(ofs64[n]);
pascal@10933 36 + while (n--) {
pascal@10932 37 + offsets[n].size = last -
pascal@10932 38 + (offsets[n].offset = __be64_to_cpu(ofs64[n]));
pascal@10932 39 + last = offsets[n].offset;
pascal@10933 40 + }
pascal@12214 41 + return (char *) "64BE v2.0";
pascal@10932 42 + }
pascal@10932 43 + }
pascal@10932 44 + else if (ofs32[1] == 0) { /* V1.0 */
pascal@11113 45 + loff_t last = __le64_to_cpu(ofs64[n]);
pascal@10933 46 + while (n--) {
pascal@10932 47 + offsets[n].size = last -
pascal@10932 48 + (offsets[n].offset = __le64_to_cpu(ofs64[n]));
pascal@10932 49 + last = offsets[n].offset;
pascal@10933 50 + }
pascal@12214 51 + return (char *) "64LE v1.0";
pascal@10932 52 + }
pascal@10933 53 + else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
pascal@10933 54 + loff_t last = ntohl(ofs32[n]);
pascal@10933 55 + while (n--) {
pascal@10932 56 + offsets[n].size = last -
pascal@10932 57 + (offsets[n].offset = ntohl(ofs32[n]));
pascal@10932 58 + last = offsets[n].offset;
pascal@10933 59 + }
pascal@12214 60 + return (char *) "32BE v0.68";
pascal@10932 61 + }
pascal@10933 62 + else { /* V3.0 */
pascal@17169 63 + unsigned long i;
pascal@17168 64 + loff_t j;
pascal@10933 65 +
pascal@17169 66 + for (i = n; i-- != 0; )
pascal@10935 67 + offsets[i].size = ntohl(ofs32[i]);
pascal@10935 68 + for (i = 0, j = sizeof(struct cloop_head); i < n; i++) {
pascal@10933 69 + offsets[i].offset = j;
pascal@18828 70 + if (offsets[i].size & 0x80000000) {
pascal@18828 71 + unsigned long k = offset[i].size & 0x7FFFFFFF;
pascal@18828 72 + offsets[i].offset = offsets[k].offset;
pascal@18828 73 + offsets[i].size = offsets[k].size;
pascal@18828 74 + }
pascal@18828 75 + else j += offsets[i].size;
pascal@10933 76 + }
pascal@12214 77 + return (char *) "32BE v3.0";
pascal@10933 78 + }
pascal@10932 79 +}
pascal@10932 80 +
pascal@10932 81 /* Cloop suspend IOCTL */
pascal@10932 82 #define CLOOP_SUSPEND 0x4C07
pascal@10932 83
pascal@10932 84
pascal@10932 85 --- cloopreader.h
pascal@10932 86 +++ cloopreader.h
pascal@10932 87 @@ -33,7 +33,7 @@
pascal@10932 88 int numblocks;
pascal@10932 89 ulong blocksize;
pascal@10932 90
pascal@10932 91 - loff_t* toc; /* Data index */
pascal@10932 92 + struct block_info *toc; /* Data index */
pascal@10932 93 size_t tocsize;
pascal@10932 94
pascal@10932 95 unsigned char* cblock; /* Compressed block */
pascal@10932 96
pascal@10932 97 --- cloopreader.c
pascal@10932 98 +++ cloopreader.c
pascal@12214 99 @@ -59,10 +59,32 @@
pascal@10932 100
pascal@10932 101 ALLOC(c->pblock,c->blocksize);
pascal@10932 102
pascal@10932 103 - c->tocsize=sizeof *c->toc * (c->numblocks+1); /* One extra address is position of EOF */
pascal@12214 104 - ALLOC(c->toc,c->tocsize);
pascal@12214 105 + if (c->numblocks + 1 == 0) {
pascal@10933 106 + struct cloop_tail tail;
pascal@10935 107 + loff_t end = lseek(c->fh,0,SEEK_END); /* lseek(,-n,SEEK_END) buggy ? */
pascal@12214 108 + void *p;
pascal@12214 109 + ulong toclen, len;
pascal@12214 110
pascal@12214 111 - OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
pascal@10935 112 + OP(lseek(c->fh, end - sizeof(tail), SEEK_SET));
pascal@10933 113 + OP(read_all(c->fh, &tail, sizeof(tail)));
pascal@10933 114 + c->numblocks = ntohl(tail.num_blocks);
pascal@12214 115 + c->tocsize = sizeof(*c->toc) * c->numblocks;
pascal@12214 116 + len = ntohl(tail.table_size);
pascal@12214 117 + toclen = (ntohl(tail.index_size) & 255) * c->numblocks;
pascal@12214 118 + OP(lseek(c->fh, end - sizeof(tail) - len, SEEK_SET));
pascal@17168 119 + ALLOC(c->toc, sizeof(*c->toc) * c->numblocks);
pascal@12214 120 + ALLOC(p,len);
pascal@12214 121 + OP(read_all(c->fh,p,len)); /* read Data Index */
pascal@12214 122 + if (uncompress((void *)c->toc,&toclen,p,len) != Z_OK)
pascal@12214 123 + exit(1);
pascal@12214 124 + free(p);
pascal@10933 125 + }
pascal@12214 126 + else {
pascal@12214 127 + c->tocsize = sizeof(*c->toc) * c->numblocks;
pascal@12214 128 + ALLOC(c->toc,c->tocsize);
pascal@12214 129 + OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
pascal@12214 130 + }
pascal@10935 131 + build_index(c->toc, c->numblocks);
pascal@10932 132 c->cblocksizecur=0;
pascal@10932 133 c->curblock=-1;
pascal@10932 134 return 0;
pascal@12214 135 @@ -79,10 +101,10 @@
pascal@10932 136 if(page>=c->numblocks){errno=EFAULT;return -1;}
pascal@10932 137 c->curblock=page;
pascal@10932 138
pascal@10932 139 - bprintf("Seeking to 0x%Lx\n",btc(c->toc[page]));
pascal@10932 140 - OP(lseek(c->fh,btc(c->toc[page]), SEEK_SET));
pascal@10932 141 + bprintf("Seeking to 0x%Lx\n",c->toc[page].offset);
pascal@10932 142 + OP(lseek(c->fh,c->toc[page].offset, SEEK_SET));
pascal@10932 143
pascal@10932 144 - c->cblocksize=btc(c->toc[page+1]) - btc(c->toc[page]);
pascal@10932 145 + c->cblocksize=c->toc[page].size;
pascal@10932 146 bprintf("Compressed size=%lu\n",c->cblocksize);
pascal@10932 147 if(c->cblocksize > c->cblocksizecur){
pascal@10932 148 if(c->cblocksizecur)free(c->cblock);
pascal@10933 149
pascal@10932 150 --- extract_compressed_fs.c
pascal@10932 151 +++ extract_compressed_fs.c
pascal@17885 152 @@ -1,19 +1,23 @@
pascal@10935 153 /* Extracts a filesystem back from a compressed fs file */
pascal@10937 154 +#define _LARGEFILE64_SOURCE
pascal@10935 155 #include "common_header.h"
pascal@12214 156 +#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V2.0 Format\n" "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n"
pascal@10935 157
pascal@10935 158 int main(int argc, char *argv[])
pascal@10935 159 {
pascal@10935 160 int handle;
pascal@10932 161 struct cloop_head head;
pascal@10932 162 unsigned int i;
pascal@17996 163 + unsigned long num_blocks, block_size, zblock_maxsize, lastlen = 0;
pascal@10932 164 unsigned char *buffer, *clear_buffer;
pascal@10932 165 + struct block_info *offsets;
pascal@10932 166
pascal@10935 167 - if (argc != 2) {
pascal@10935 168 - fprintf(stderr, "Need filename\n");
pascal@10935 169 + if (argc < 2 || argv[1][0] == '-') {
pascal@10935 170 + fprintf(stderr, "Usage: extract_compressed_fs file [--convert-to-v2] > output\n");
pascal@10935 171 exit(1);
pascal@10935 172 }
pascal@10932 173
pascal@17885 174 - handle = open(argv[1], O_RDONLY);
pascal@17885 175 + handle = open(argv[1], O_RDONLY|O_LARGEFILE);
pascal@17885 176 if (handle < 0) {
pascal@17885 177 perror("Opening compressed file\n");
pascal@17885 178 exit(1);
pascal@17996 179 @@ -24,44 +28,100 @@
pascal@10935 180 exit(1);
pascal@10935 181 }
pascal@10935 182
pascal@10935 183 - buffer = malloc(ntohl(head.block_size) + ntohl(head.block_size)/1000
pascal@10935 184 - + 12 + 4);
pascal@10935 185 - clear_buffer = malloc(ntohl(head.block_size));
pascal@10935 186 - fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n",
pascal@10935 187 - ntohl(head.num_blocks), ntohl(head.block_size), head.preamble);
pascal@12214 188 + num_blocks = ntohl(head.num_blocks);
pascal@12214 189 + block_size = ntohl(head.block_size);
pascal@12214 190 + zblock_maxsize = block_size + block_size/1000 + 12 + 4;
pascal@12214 191 + buffer = malloc(zblock_maxsize);
pascal@12214 192 + clear_buffer = malloc(block_size);
pascal@12214 193
pascal@10935 194 - for (i = 0; i < ntohl(head.num_blocks); i++) {
pascal@10935 195 - int currpos;
pascal@10935 196 - unsigned long destlen = ntohl(head.block_size);
pascal@10935 197 - loff_t offset[2];
pascal@10935 198 - unsigned int size;
pascal@12214 199 + if (num_blocks == (unsigned long) -1) {
pascal@12214 200 + void *table;
pascal@10933 201 + struct cloop_tail tail;
pascal@12214 202 + unsigned long len, table_size;
pascal@10937 203 + loff_t end = lseek64(handle, 0, SEEK_END);
pascal@12214 204 +
pascal@10937 205 + if (lseek64(handle, end - sizeof(tail), SEEK_SET) < 0 ||
pascal@10933 206 + read(handle, &tail, sizeof(tail)) != sizeof(tail) ||
pascal@10937 207 + lseek64(handle, end - sizeof(tail) -
pascal@12214 208 + ntohl(tail.table_size), SEEK_SET) < 0) {
pascal@10933 209 + perror("Reading tail\n");
pascal@10933 210 + exit(1);
pascal@10933 211 + }
pascal@10933 212 + head.num_blocks = tail.num_blocks;
pascal@10935 213 + num_blocks = ntohl(head.num_blocks);
pascal@12214 214 + table_size = ntohl(tail.table_size);
pascal@12214 215 + table = malloc(table_size);
pascal@12214 216 + len = i = num_blocks * (ntohl(tail.index_size) & 255);
pascal@18001 217 + lastlen = ntohl(tail.index_size) & ~0x1FF;
pascal@12214 218 + offsets = malloc(num_blocks * sizeof(*offsets));
pascal@12214 219 + if (!table || !offsets ||
pascal@12214 220 + read(handle, table, table_size) != table_size ||
pascal@12214 221 + uncompress((void *)offsets, &len, table, table_size) != Z_OK ||
pascal@12214 222 + len != i) {
pascal@12214 223 + perror("Reading index\n");
pascal@12214 224 + exit(1);
pascal@12214 225 + }
pascal@12214 226 + free(table);
pascal@10933 227 + }
pascal@12214 228 + else {
pascal@12214 229 + offsets = malloc(i = num_blocks * sizeof(*offsets));
pascal@12214 230 + if (!offsets || read(handle, offsets, i) != i) {
pascal@12214 231 + perror("Reading index\n");
pascal@12214 232 + exit(1);
pascal@12214 233 + }
pascal@10932 234 + }
pascal@10932 235 +
pascal@12214 236 + fprintf(stderr, "%lu blocks of size %lu. Preamble:\n%s\n",
pascal@12214 237 + num_blocks, block_size, head.preamble);
pascal@10935 238 + fprintf(stderr, "Index %s.\n", build_index(offsets, num_blocks));
pascal@10932 239 +
pascal@10935 240 + if (argc > 2) {
pascal@14712 241 + unsigned n;
pascal@10936 242 + loff_t data, offset = ((num_blocks + 1) * sizeof(offset)) + sizeof(head);
pascal@10935 243 +
pascal@10935 244 + strcpy(head.preamble, CLOOP_PREAMBLE);
pascal@14712 245 + write(STDOUT_FILENO, &head, n = sizeof(head));
pascal@10935 246 + for (i = 0; i < num_blocks; i++) {
pascal@10936 247 + data = __be64_to_cpu(offset);
pascal@10936 248 + write(STDOUT_FILENO, &data, sizeof(data));
pascal@14712 249 + n += sizeof(data);
pascal@10936 250 + offset += offsets[i].size;
pascal@10935 251 + }
pascal@10936 252 + data = __be64_to_cpu(offset);
pascal@10936 253 + write(STDOUT_FILENO, &data, sizeof(data));
pascal@10937 254 + for (i = 0; i < num_blocks && lseek64(handle, offsets[i].offset, SEEK_SET) >= 0; i++) {
pascal@10935 255 + read(handle, buffer, offsets[i].size);
pascal@10935 256 + write(STDOUT_FILENO, buffer, offsets[i].size);
pascal@14712 257 + n += offsets[i].size;
pascal@14712 258 + }
pascal@14712 259 + n &= 0x1FF;
pascal@14712 260 + if (n) {
pascal@14712 261 + memset(buffer, 0, 512);
pascal@14712 262 + write(STDOUT_FILENO, buffer, 512 - n);
pascal@10935 263 + }
pascal@10935 264 + return 0;
pascal@10935 265 + }
pascal@10935 266 +
pascal@10935 267 + for (i = 0; i < num_blocks; i++) {
pascal@10935 268 + unsigned long destlen = block_size;
pascal@10932 269 + unsigned int size = offsets[i].size;
pascal@10932 270
pascal@10932 271 - read(handle, &offset, 2*sizeof(loff_t));
pascal@10932 272 - lseek(handle, -sizeof(loff_t), SEEK_CUR);
pascal@10932 273 -
pascal@10932 274 - currpos = lseek(handle, 0, SEEK_CUR);
pascal@10932 275 - if (lseek(handle, __be64_to_cpu(offset[0]), SEEK_SET) < 0) {
pascal@10937 276 + if (lseek64(handle, offsets[i].offset, SEEK_SET) < 0) {
pascal@10932 277 fprintf(stderr, "lseek to %Lu: %s\n",
pascal@10932 278 - __be64_to_cpu(offset[0]), strerror(errno));
pascal@10932 279 + offsets[i].offset, strerror(errno));
pascal@10932 280 exit(1);
pascal@10932 281 }
pascal@10932 282
pascal@10932 283 - size=__be64_to_cpu(offset[1])-__be64_to_cpu(offset[0]);
pascal@10935 284 - if (size > ntohl(head.block_size) + ntohl(head.block_size)/1000
pascal@10935 285 - + 12 + 4) {
pascal@10935 286 + if (size > zblock_maxsize) {
pascal@10932 287 fprintf(stderr,
pascal@10932 288 "Size %u for block %u (offset %Lu) too big\n",
pascal@10932 289 - size, i, __be64_to_cpu(offset[0]));
pascal@10932 290 + size, i, offsets[i].offset);
pascal@10932 291 exit(1);
pascal@10932 292 }
pascal@10932 293 read(handle, buffer, size);
pascal@10932 294 - if (lseek(handle, currpos, SEEK_SET) < 0) {
pascal@10932 295 - perror("seeking");
pascal@10932 296 - exit(1);
pascal@10932 297 - }
pascal@10932 298
pascal@10935 299 - fprintf(stderr, "Block %u length %u => %lu\n",
pascal@10935 300 - i, size, destlen);
pascal@10935 301 + fprintf(stderr, "Block %u at %llu length %u => %lu\n",
pascal@10935 302 + i, offsets[i].offset, size, destlen);
pascal@10935 303 if (i == 3) {
pascal@10935 304 fprintf(stderr,
pascal@10935 305 "Block head:%02X%02X%02X%02X%02X%02X%02X%02X\n",
pascal@17996 306 @@ -105,12 +165,12 @@
pascal@10937 307 fprintf(stderr, "Uncomp: unknown error %u\n", i);
pascal@10937 308 exit(1);
pascal@10937 309 }
pascal@10937 310 - if (destlen != ntohl(head.block_size)) {
pascal@10937 311 - fprintf(stderr, "Uncomp: bad len %u (%lu not %u)\n", i,
pascal@10937 312 - destlen, ntohl(head.block_size));
pascal@10937 313 + if (destlen != block_size) {
pascal@10937 314 + fprintf(stderr, "Uncomp: bad len %u (%lu not %lu)\n", i,
pascal@10937 315 + destlen, block_size);
pascal@10937 316 exit(1);
pascal@10937 317 }
pascal@10937 318 - write(STDOUT_FILENO, clear_buffer, ntohl(head.block_size));
pascal@17996 319 + write(STDOUT_FILENO, clear_buffer, (lastlen != 0 && (i+1) == num_blocks) ? lastlen : block_size);
pascal@10937 320 }
pascal@10937 321 return 0;
pascal@10937 322 }
pascal@10935 323
pascal@10935 324 --- Makefile
pascal@10935 325 +++ Makefile
pascal@10935 326 @@ -1,16 +1,19 @@
pascal@10935 327 PROGNAME=fusecloop
pascal@10935 328 ARCFILES=*.c *.h *.pl Makefile configure README VERSION HELP INSTALL typescript *.cloop COPYING
pascal@10935 329 -PROGS=fusecloop cloopreaderdemo extract_compressed_fs
pascal@10935 330 +PROGS=fusecloop cloopreaderdemo extract_compressed_fs create_compressed_fs
pascal@10935 331 FUSECFLAGS=`pkg-config fuse --cflags`
pascal@10935 332 FUSELDFLAGS=`pkg-config fuse --libs`
pascal@10935 333
pascal@10935 334 CFLAGS= -Wall
pascal@10935 335
pascal@10935 336 -all: fusecloop extract_compressed_fs
pascal@10935 337 +all: fusecloop extract_compressed_fs create_compressed_fs
pascal@10935 338
pascal@10935 339 extract_compressed_fs: extract_compressed_fs.c
pascal@10935 340 ${CC} ${CFLAGS} ${LDFLAGS} -lz extract_compressed_fs.c -o extract_compressed_fs
pascal@10935 341
pascal@10935 342 +create_compressed_fs: create_compressed_fs.c
pascal@10935 343 + ${CC} ${CFLAGS} ${LDFLAGS} -lz create_compressed_fs.c -o create_compressed_fs
pascal@10935 344 +
pascal@10935 345 fusecloop: fusecloop.c cloopreader.o strver debug.o
pascal@10935 346 ${CC} ${CFLAGS} ${LDFLAGS} -lz cloopreader.o ${FUSECFLAGS} ${FUSELDFLAGS} fusecloop.c debug.o -o fusecloop
pascal@10935 347
pascal@10935 348
pascal@12214 349
pascal@10935 350 --- create_compressed_fs.c
pascal@10935 351 +++ create_compressed_fs.c
pascal@18001 352 @@ -0,0 +1,148 @@
pascal@12214 353 +#ifdef FIND_BEST_COMPRESSION
pascal@12214 354 +#include <compress.h>
pascal@12214 355 +extern "C" {
pascal@12214 356 +#include <stdlib.h>
pascal@12214 357 +#include <string.h>
pascal@12214 358 +
pascal@12214 359 +static int best_compress(unsigned char *compressed,
pascal@12214 360 + unsigned long *compressed_len,
pascal@12214 361 + unsigned char *uncompressed,
pascal@12214 362 + unsigned long uncompressed_len)
pascal@12214 363 +{
pascal@12214 364 + int i, j, err;
pascal@12214 365 + unsigned char *buf[2];
pascal@12214 366 + unsigned len;
pascal@12214 367 + unsigned long llen, best = *compressed_len * 2;
pascal@12214 368 + static unsigned char *buffer;
pascal@12214 369 + static unsigned long buffersz;
pascal@12214 370 +
pascal@12214 371 + if (buffersz < *compressed_len) {
pascal@12214 372 + if (buffer) free(buffer);
pascal@12214 373 + buffer = (unsigned char *) malloc(buffersz = *compressed_len);
pascal@12214 374 + if (!buffer) return Z_MEM_ERROR;
pascal@12214 375 + }
pascal@12214 376 + buf[0] = compressed;
pascal@12214 377 + buf[1] = buffer;
pascal@12214 378 + for (i = j = 0; i <= 10; i++) {
pascal@12214 379 + llen = len = *compressed_len;
pascal@12214 380 + if (i == 10)
pascal@12214 381 + err = (compress_zlib(shrink_extreme, buf[j],
pascal@12214 382 + len, uncompressed,
pascal@12214 383 + uncompressed_len)) ? Z_OK : Z_DATA_ERROR;
pascal@12214 384 + else {
pascal@12214 385 + err = compress2(buf[j], &llen, uncompressed,
pascal@12214 386 + uncompressed_len, i);
pascal@12214 387 + len = llen;
pascal@12214 388 + }
pascal@12214 389 + if (err != Z_OK) return err;
pascal@12214 390 + if (len < best) {
pascal@12214 391 + best = len;
pascal@12214 392 + j = 1 - j;
pascal@12214 393 + }
pascal@12214 394 + }
pascal@12214 395 + *compressed_len = best;
pascal@12214 396 + if (j == 0)
pascal@12214 397 + memcpy(compressed, buffer, best);
pascal@12214 398 + return err;
pascal@12214 399 +}
pascal@12214 400 +#define compress2(a,b,c,d,e) best_compress(a,b,c,d)
pascal@12214 401 +#endif
pascal@12214 402 +
pascal@10935 403 +/* Creates a compressed file */
pascal@10935 404 +#include "common_header.h"
pascal@10935 405 +
pascal@12214 406 +#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V3.0 Format\n" "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n"
pascal@10935 407 +#define CHUNK 65536
pascal@10935 408 +#define DEFAULT_BLOCKSIZE 65536
pascal@10935 409 +
pascal@12214 410 +static void quit(const char *s)
pascal@10935 411 +{
pascal@10935 412 + fprintf(stderr, "%s\n", s);
pascal@10935 413 + exit(1);
pascal@10935 414 +}
pascal@10935 415 +
pascal@10935 416 +static int readblock(unsigned char *buffer, int n)
pascal@10935 417 +{
pascal@10935 418 + int i;
pascal@10935 419 +
pascal@10935 420 + memset(buffer, 0, n);
pascal@10935 421 + for (i = 0 ; i < n;) {
pascal@10935 422 + int j = read(STDIN_FILENO, buffer + i, n - i);
pascal@10935 423 + if (j < 0 && errno == EINTR) continue;
pascal@10935 424 + if (j <= 0) break;
pascal@10935 425 + i += j;
pascal@10935 426 + }
pascal@10935 427 + return i;
pascal@10935 428 +}
pascal@10935 429 +
pascal@10935 430 +int main(int argc, char *argv[])
pascal@10935 431 +{
pascal@10935 432 + struct cloop_head head;
pascal@10935 433 + struct cloop_tail tail;
pascal@10935 434 + unsigned long block_size = 0;
pascal@10935 435 + unsigned char *compressed, *uncompressed;
pascal@10935 436 + unsigned long *index;
pascal@10935 437 + int n, indexmax, zlenmax;
pascal@17996 438 + unsigned long lastlen, len, pos;
pascal@12214 439 + static char padding[512];
pascal@10935 440 +
pascal@10935 441 + if (argc > 1) {
pascal@10935 442 + if (argv[1][0] < '0' || argv[1][0] > '9')
pascal@10935 443 + quit("Usage : create_compressed_fs [block size] < input > output");
pascal@10935 444 + block_size = atoi(argv[1]);
pascal@10935 445 + }
pascal@10935 446 + if (block_size < 4096)
pascal@10935 447 + block_size = DEFAULT_BLOCKSIZE;
pascal@10935 448 + fprintf(stderr, "Block size is %lu\n", block_size);
pascal@10935 449 + zlenmax = block_size + block_size/1000 + 12;
pascal@10935 450 +
pascal@10935 451 + memset(&head, 0, sizeof(head));
pascal@10935 452 + strcpy(head.preamble, CLOOP_PREAMBLE);
pascal@10935 453 + head.num_blocks = -1;
pascal@10935 454 + head.block_size = htonl(block_size);
pascal@10935 455 + write(STDOUT_FILENO, &head, sizeof(head));
pascal@12214 456 + pos = sizeof(head);
pascal@10935 457 +
pascal@12214 458 + compressed = (unsigned char *) malloc(zlenmax);
pascal@12214 459 + uncompressed = (unsigned char *) malloc(block_size);
pascal@12214 460 + index = (unsigned long *) malloc(indexmax = CHUNK);
pascal@10935 461 + if (!compressed || !uncompressed || !index)
pascal@10935 462 + quit("Malloc failed");
pascal@10935 463 +
pascal@17996 464 + for (n = 0; (len = readblock(uncompressed, block_size)) != 0; n++) {
pascal@17997 465 + lastlen = len;
pascal@12214 466 + len = zlenmax;
pascal@17998 467 + if (compress2(compressed, &len, uncompressed, block_size,
pascal@10935 468 + Z_BEST_COMPRESSION) != Z_OK)
pascal@10935 469 + quit("Compression failed");
pascal@10935 470 + fprintf(stderr, "Block %u length %lu => %lu\n",
pascal@10935 471 + n, block_size, len);
pascal@10935 472 + write(STDOUT_FILENO, compressed, len);
pascal@12214 473 + pos += len;
pascal@10935 474 + if (n * sizeof(*index) >= indexmax) {
pascal@12214 475 + index = (unsigned long *) realloc(index,
pascal@12214 476 + indexmax += CHUNK);
pascal@10935 477 + if (!index)
pascal@10935 478 + quit("Realloc");
pascal@10935 479 + }
pascal@10935 480 + index[n] = ntohl(len);
pascal@10935 481 + }
pascal@18001 482 + tail.index_size = ntohl(sizeof(*index) + (lastlen & ~0x1FF));
pascal@10935 483 + tail.num_blocks = ntohl(n);
pascal@12214 484 + n *= sizeof(*index);
pascal@12214 485 + len = n + n/1000 + 12;
pascal@17991 486 + compressed = (unsigned char *) realloc(compressed, len);
pascal@12214 487 + if (!compressed || compress2(compressed, &len, (unsigned char *) index,
pascal@12214 488 + n, Z_BEST_COMPRESSION) != Z_OK)
pascal@12214 489 + quit("Index compression failed");
pascal@12214 490 + tail.table_size = ntohl(len);
pascal@12214 491 + pos += len + sizeof(tail);
pascal@12214 492 + n = pos & 511;
pascal@12214 493 + if (n) write(STDOUT_FILENO, padding, 512 - n);
pascal@12214 494 + write(STDOUT_FILENO, compressed, len);
pascal@10935 495 + write(STDOUT_FILENO, &tail, sizeof(tail));
pascal@10935 496 + return 0;
pascal@10935 497 +}
pascal@12214 498 +#ifdef FIND_BEST_COMPRESSION
pascal@12214 499 +}
pascal@12214 500 +#endif
pascal@12214 501
pascal@10938 502 --- fusecloop.c
pascal@10938 503 +++ fusecloop.c
pascal@10938 504 @@ -65,7 +65,7 @@
pascal@10938 505
pascal@10938 506 memcpy(stbuf,&stb,sizeof stb);
pascal@10938 507 stbuf->st_mode&=~0222;
pascal@10938 508 - stbuf->st_size = cd.blocksize * cd.numblocks;
pascal@10938 509 + stbuf->st_size = (loff_t) cd.blocksize * cd.numblocks;
pascal@10938 510 /*
pascal@10938 511 stbuf->st_mode = S_IFREG | 0444;
pascal@10938 512 stbuf->st_nlink = 1;