# HG changeset patch # User Pascal Bellard # Date 1333399701 -7200 # Node ID 297bc4cc89841e1927f41905303ddfbf79fec08e # Parent 2dde678153c7da81a9ccddb4d20b9542fd6b6aa6 fusecloop: compress index too diff -r 2dde678153c7 -r 297bc4cc8984 fusecloop/receipt --- a/fusecloop/receipt Sun Apr 01 12:41:48 2012 +0200 +++ b/fusecloop/receipt Mon Apr 02 22:48:21 2012 +0200 @@ -8,7 +8,10 @@ TARBALL="$PACKAGE-$VERSION.tar.gz" WEB_SITE="http://fusecloop.sourceforge.net/" WGET_URL="$SF_MIRROR/$PACKAGE/$TARBALL" -DEPENDS="fuse zlib" +ADVANCECOMP_VERSION="1.15" +ADVANCECOMP_TARBALL="advancecomp-$ADVANCECOMP_VERSION.tar.gz" +ADVANCECOMP_URL="$SF_MIRROR/advancemame/$ADVANCECOMP_TARBALL" +DEPENDS="fuse zlib gcc-lib-base" BUILD_DEPENDS="fuse-dev zlib-dev" SUGGESTED="fuseiso" @@ -16,11 +19,22 @@ compile_rules() { cd $src + [ -s $SOURCES_REPOSITORY/$ADVANCECOMP_TARBALL ] || + wget -P $SOURCES_REPOSITORY $ADVANCECOMP_URL + tar xzf $SOURCES_REPOSITORY/$ADVANCECOMP_TARBALL sed -i 's/dprintf/d_printf/g' *.h *.c patch -p0 < $stuff/fusecloop.u + ADVANCECOMP=advancecomp-$ADVANCECOMP_VERSION + cp *.h *.c $ADVANCECOMP + cp create_compressed_fs.c $ADVANCECOMP/redef.cc + sed -i 's/def FIND_BEST_COMPRESSION/ 1/' $ADVANCECOMP/redef.cc ./configure --prefix=/usr --infodir=/usr/share/info \ --mandir=/usr/share/man $CONFIGURE_ARGS && - make + make && + cd $ADVANCECOMP && + ./configure --prefix=/usr --infodir=/usr/share/info \ + --mandir=/usr/share/man $CONFIGURE_ARGS && + make advdef } # Rules to gen a SliTaz package suitable for Tazpkg. @@ -29,6 +43,6 @@ mkdir -p $fs/usr/bin cp $src/fusecloop $fs/usr/bin cp $src/extract_compressed_fs $fs/usr/bin - cp $src/create_compressed_fs $fs/usr/bin + cp $src/advancecomp-*/advdef $fs/usr/bin/create_compressed_fs } diff -r 2dde678153c7 -r 297bc4cc8984 fusecloop/stuff/fusecloop.u --- a/fusecloop/stuff/fusecloop.u Sun Apr 01 12:41:48 2012 +0200 +++ b/fusecloop/stuff/fusecloop.u Mon Apr 02 22:48:21 2012 +0200 @@ -1,11 +1,12 @@ --- compressed_loop.h +++ compressed_loop.h -@@ -41,6 +41,73 @@ +@@ -41,6 +41,74 @@ /* data_index (num_blocks 64bit pointers, network order)... */ /* compressed data (gzip block compressed format)... */ +struct cloop_tail +{ ++ u_int32_t table_size; + u_int32_t index_size; + u_int32_t num_blocks; +}; @@ -28,7 +29,7 @@ + offsets[n].offset = __be64_to_cpu(offsets[n].offset); + offsets[n].size = ntohl(offsets[n].size); + } -+ return "128BE accelerated knoppix 1.0"; ++ return (char *) "128BE accelerated knoppix 1.0"; + } + else { /* V2.0 */ + loff_t last = __be64_to_cpu(ofs64[n]); @@ -37,7 +38,7 @@ + (offsets[n].offset = __be64_to_cpu(ofs64[n])); + last = offsets[n].offset; + } -+ return "64BE v2.0"; ++ return (char *) "64BE v2.0"; + } + } + else if (ofs32[1] == 0) { /* V1.0 */ @@ -47,7 +48,7 @@ + (offsets[n].offset = __le64_to_cpu(ofs64[n])); + last = offsets[n].offset; + } -+ return "64LE v1.0"; ++ return (char *) "64LE v1.0"; + } + else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ + loff_t last = ntohl(ofs32[n]); @@ -56,7 +57,7 @@ + (offsets[n].offset = ntohl(ofs32[n])); + last = offsets[n].offset; + } -+ return "32BE v0.68"; ++ return (char *) "32BE v0.68"; + } + else { /* V3.0 */ + int i, j; @@ -67,7 +68,7 @@ + offsets[i].offset = j; + j += offsets[i].size; + } -+ return "32BE v3.0"; ++ return (char *) "32BE v3.0"; + } +} + @@ -89,30 +90,43 @@ --- cloopreader.c +++ cloopreader.c -@@ -59,10 +59,21 @@ +@@ -59,10 +59,32 @@ ALLOC(c->pblock,c->blocksize); - c->tocsize=sizeof *c->toc * (c->numblocks+1); /* One extra address is position of EOF */ -+ c->tocsize=sizeof(*c->toc) * c->numblocks; -+ if (c->numblocks == -1) { +- ALLOC(c->toc,c->tocsize); ++ if (c->numblocks + 1 == 0) { + struct cloop_tail tail; + loff_t end = lseek(c->fh,0,SEEK_END); /* lseek(,-n,SEEK_END) buggy ? */ -+ ++ void *p; ++ ulong toclen, len; + +- OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */ + OP(lseek(c->fh, end - sizeof(tail), SEEK_SET)); + OP(read_all(c->fh, &tail, sizeof(tail))); + c->numblocks = ntohl(tail.num_blocks); -+ c->tocsize = ntohl(tail.index_size) * c->numblocks; -+ OP(lseek(c->fh, end - sizeof(tail) - c->tocsize, SEEK_SET)); ++ c->tocsize = sizeof(*c->toc) * c->numblocks; ++ len = ntohl(tail.table_size); ++ toclen = (ntohl(tail.index_size) & 255) * c->numblocks; ++ OP(lseek(c->fh, end - sizeof(tail) - len, SEEK_SET)); ++ ALLOC(c->toc,c->tocsize); ++ ALLOC(p,len); ++ OP(read_all(c->fh,p,len)); /* read Data Index */ ++ if (uncompress((void *)c->toc,&toclen,p,len) != Z_OK) ++ exit(1); ++ free(p); + } - ALLOC(c->toc,c->tocsize); - - OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */ ++ else { ++ c->tocsize = sizeof(*c->toc) * c->numblocks; ++ ALLOC(c->toc,c->tocsize); ++ OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */ ++ } + build_index(c->toc, c->numblocks); c->cblocksizecur=0; c->curblock=-1; return 0; -@@ -79,10 +90,10 @@ +@@ -79,10 +101,10 @@ if(page>=c->numblocks){errno=EFAULT;return -1;} c->curblock=page; @@ -133,7 +147,7 @@ /* Extracts a filesystem back from a compressed fs file */ +#define _LARGEFILE64_SOURCE #include "common_header.h" -+#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V2.0 Format\n" "insmod cloop.o file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n" ++#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V2.0 Format\n" "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n" int main(int argc, char *argv[]) { @@ -151,7 +165,7 @@ exit(1); } -@@ -24,44 +28,77 @@ +@@ -24,44 +28,91 @@ exit(1); } @@ -160,42 +174,55 @@ - clear_buffer = malloc(ntohl(head.block_size)); - fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n", - ntohl(head.num_blocks), ntohl(head.block_size), head.preamble); -- ++ num_blocks = ntohl(head.num_blocks); ++ block_size = ntohl(head.block_size); ++ zblock_maxsize = block_size + block_size/1000 + 12 + 4; ++ buffer = malloc(zblock_maxsize); ++ clear_buffer = malloc(block_size); + - for (i = 0; i < ntohl(head.num_blocks); i++) { - int currpos; - unsigned long destlen = ntohl(head.block_size); - loff_t offset[2]; - unsigned int size; -+ num_blocks = ntohl(head.num_blocks); -+ block_size = ntohl(head.block_size); -+ zblock_maxsize = block_size + block_size/1000 + 12 + 4; -+ buffer = malloc(zblock_maxsize); -+ clear_buffer = malloc(block_size); -+ fprintf(stderr, "%lu blocks of size %lu. Preamble:\n%s\n", -+ num_blocks, block_size, head.preamble); -+ -+ if (num_blocks == -1) { ++ if (num_blocks == (unsigned long) -1) { ++ void *table; + struct cloop_tail tail; ++ unsigned long len, table_size; + loff_t end = lseek64(handle, 0, SEEK_END); ++ + if (lseek64(handle, end - sizeof(tail), SEEK_SET) < 0 || + read(handle, &tail, sizeof(tail)) != sizeof(tail) || + lseek64(handle, end - sizeof(tail) - -+ (ntohl(tail.num_blocks) * ntohl(tail.index_size)), -+ SEEK_SET) < 0) { ++ ntohl(tail.table_size), SEEK_SET) < 0) { + perror("Reading tail\n"); + exit(1); + } + head.num_blocks = tail.num_blocks; + num_blocks = ntohl(head.num_blocks); -+ i = num_blocks * ntohl(tail.index_size); ++ table_size = ntohl(tail.table_size); ++ table = malloc(table_size); ++ len = i = num_blocks * (ntohl(tail.index_size) & 255); ++ offsets = malloc(num_blocks * sizeof(*offsets)); ++ if (!table || !offsets || ++ read(handle, table, table_size) != table_size || ++ uncompress((void *)offsets, &len, table, table_size) != Z_OK || ++ len != i) { ++ perror("Reading index\n"); ++ exit(1); ++ } ++ free(table); + } -+ else i = num_blocks * sizeof(*offsets); -+ offsets = malloc(i); -+ if (!offsets || read(handle, offsets, i) != i) { -+ perror("Reading index\n"); -+ exit(1); ++ else { ++ offsets = malloc(i = num_blocks * sizeof(*offsets)); ++ if (!offsets || read(handle, offsets, i) != i) { ++ perror("Reading index\n"); ++ exit(1); ++ } + } + ++ fprintf(stderr, "%lu blocks of size %lu. Preamble:\n%s\n", ++ num_blocks, block_size, head.preamble); + fprintf(stderr, "Index %s.\n", build_index(offsets, num_blocks)); + + if (argc > 2) { @@ -256,7 +283,7 @@ if (i == 3) { fprintf(stderr, "Block head:%02X%02X%02X%02X%02X%02X%02X%02X\n", -@@ -105,12 +142,12 @@ +@@ -105,12 +156,12 @@ fprintf(stderr, "Uncomp: unknown error %u\n", i); exit(1); } @@ -299,17 +326,68 @@ ${CC} ${CFLAGS} ${LDFLAGS} -lz cloopreader.o ${FUSECFLAGS} ${FUSELDFLAGS} fusecloop.c debug.o -o fusecloop + --- create_compressed_fs.c +++ create_compressed_fs.c -@@ -0,0 +1,80 @@ +@@ -0,0 +1,147 @@ ++#ifdef FIND_BEST_COMPRESSION ++#include ++extern "C" { ++#include ++#include ++ ++static int best_compress(unsigned char *compressed, ++ unsigned long *compressed_len, ++ unsigned char *uncompressed, ++ unsigned long uncompressed_len) ++{ ++ int i, j, err; ++ unsigned char *buf[2]; ++ unsigned len; ++ unsigned long llen, best = *compressed_len * 2; ++ static unsigned char *buffer; ++ static unsigned long buffersz; ++ ++ if (buffersz < *compressed_len) { ++ if (buffer) free(buffer); ++ buffer = (unsigned char *) malloc(buffersz = *compressed_len); ++ if (!buffer) return Z_MEM_ERROR; ++ } ++ buf[0] = compressed; ++ buf[1] = buffer; ++ for (i = j = 0; i <= 10; i++) { ++ llen = len = *compressed_len; ++ if (i == 10) ++ err = (compress_zlib(shrink_extreme, buf[j], ++ len, uncompressed, ++ uncompressed_len)) ? Z_OK : Z_DATA_ERROR; ++ else { ++ err = compress2(buf[j], &llen, uncompressed, ++ uncompressed_len, i); ++ len = llen; ++ } ++ if (err != Z_OK) return err; ++ if (len < best) { ++ best = len; ++ j = 1 - j; ++ } ++ } ++ *compressed_len = best; ++ if (j == 0) ++ memcpy(compressed, buffer, best); ++ return err; ++} ++#define compress2(a,b,c,d,e) best_compress(a,b,c,d) ++#endif ++ +/* Creates a compressed file */ +#include "common_header.h" + -+#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V3.0 Format\n" "insmod cloop.o file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n" ++#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V3.0 Format\n" "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n" +#define CHUNK 65536 +#define DEFAULT_BLOCKSIZE 65536 + -+static void quit(char *s) ++static void quit(const char *s) +{ + fprintf(stderr, "%s\n", s); + exit(1); @@ -337,6 +415,8 @@ + unsigned char *compressed, *uncompressed; + unsigned long *index; + int n, indexmax, zlenmax; ++ unsigned long len, pos; ++ static char padding[512]; + + if (argc > 1) { + if (argv[1][0] < '0' || argv[1][0] > '9') @@ -353,35 +433,51 @@ + head.num_blocks = -1; + head.block_size = htonl(block_size); + write(STDOUT_FILENO, &head, sizeof(head)); ++ pos = sizeof(head); + -+ compressed = malloc(zlenmax); -+ uncompressed = malloc(block_size); -+ index = malloc(indexmax = CHUNK); ++ compressed = (unsigned char *) malloc(zlenmax); ++ uncompressed = (unsigned char *) malloc(block_size); ++ index = (unsigned long *) malloc(indexmax = CHUNK); + if (!compressed || !uncompressed || !index) + quit("Malloc failed"); + + for (n = 0; readblock(uncompressed, block_size); n++) { -+ unsigned long len = zlenmax; -+ ++ len = zlenmax; + if (compress2(compressed, &len, uncompressed, block_size, + Z_BEST_COMPRESSION) != Z_OK) + quit("Compression failed"); + fprintf(stderr, "Block %u length %lu => %lu\n", + n, block_size, len); + write(STDOUT_FILENO, compressed, len); ++ pos += len; + if (n * sizeof(*index) >= indexmax) { -+ index = realloc(index, indexmax += CHUNK); ++ index = (unsigned long *) realloc(index, ++ indexmax += CHUNK); + if (!index) + quit("Realloc"); + } + index[n] = ntohl(len); + } -+ write(STDOUT_FILENO, index, n * sizeof(*index)); + tail.index_size = ntohl(sizeof(*index)); + tail.num_blocks = ntohl(n); ++ n *= sizeof(*index); ++ len = n + n/1000 + 12; ++ compressed = (unsigned char *) realloc(compressed, n); ++ if (!compressed || compress2(compressed, &len, (unsigned char *) index, ++ n, Z_BEST_COMPRESSION) != Z_OK) ++ quit("Index compression failed"); ++ tail.table_size = ntohl(len); ++ pos += len + sizeof(tail); ++ n = pos & 511; ++ if (n) write(STDOUT_FILENO, padding, 512 - n); ++ write(STDOUT_FILENO, compressed, len); + write(STDOUT_FILENO, &tail, sizeof(tail)); + return 0; +} ++#ifdef FIND_BEST_COMPRESSION ++} ++#endif + --- fusecloop.c +++ fusecloop.c @@ -65,7 +65,7 @@