# HG changeset patch # User Pascal Bellard # Date 1588676804 0 # Node ID cea6e929d21e881a91ab090cab42cb1d79a509be # Parent 36e9a3dcd5de642da255f9bd7b1198d9704966ca fusecloop, linux-cloop, qemu: multicompressor support diff -r 36e9a3dcd5de -r cea6e929d21e fusecloop/stuff/fusecloop.u --- a/fusecloop/stuff/fusecloop.u Mon May 04 09:05:12 2020 +0000 +++ b/fusecloop/stuff/fusecloop.u Tue May 05 11:06:44 2020 +0000 @@ -1809,3 +1809,299 @@ } flush_index(0); return 0; +--- compressed_loop.h ++++ compressed_loop.h +@@ -92,9 +92,8 @@ + struct cloop_tail + { + u_int32_t table_size; +- u_int32_t index_size; /* size:4 comp:3 ctrl-c:1 lastlen:24 */ ++ u_int32_t index_size; /* size:4 unused:3 ctrl-c:1 lastlen:24 */ + #define CLOOP3_INDEX_SIZE(x) ((unsigned int)((x) & 0xF)) +-#define CLOOP3_BLOCKS_FLAGS(x) ((unsigned int)((x) & 0x70) >> 4) + #define CLOOP3_TRUNCATED(x) ((unsigned int)((x) & 0x80) >> 7) + #define CLOOP3_LASTLEN(x) (unsigned int)((x) >> 8) + u_int32_t num_blocks; +@@ -107,12 +106,12 @@ + loff_t offset; /* 64-bit offsets of compressed block */ + u_int32_t size; /* 32-bit compressed block size */ + u_int32_t flags; /* 32-bit compression flags */ +- + }; + +-static inline char *build_index(struct block_info *offsets, unsigned long n, +- unsigned long block_size, unsigned global_flags) ++static inline char *build_index(struct block_info *offsets, unsigned long n, unsigned long block_size) + { ++ static char v[sizeof("64BE v4.0a")]; ++ u_int32_t flags; + u_int32_t *ofs32 = (u_int32_t *) offsets; + loff_t *ofs64 = (loff_t *) offsets; + +@@ -137,8 +136,6 @@ + } + else { /* V2.0/V4.0 */ + loff_t last = CLOOP_BLOCK_OFFSET(__be64_to_cpu(ofs64[n])); +- u_int32_t flags; +- static char v4[11]; + unsigned long i = n; + + for (flags = 0; n-- ;) { +@@ -156,12 +153,7 @@ + offsets[i] = offsets[offsets[i].offset]; + } + } +- strcpy(v4, (char *) "64BE v4.0a"); +- v4[10] = 'a' + ((flags-1) & 0xF); // compressors used +- if (flags > 0x10) { // with links ? +- v4[10] += 'A' - 'a'; +- } +- return v4; ++ strcpy(v, (char *) "64BE v4.0a"); + } + } + else if (ofs32[1] == 0 && v3_64 == 0) { /* V1.0 */ +@@ -174,44 +166,50 @@ + } + return (char *) "64LE v1.0"; + } +- else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ +- loff_t last = ntohl(ofs32[n]); +- while (n--) { +- offsets[n].size = last - +- (offsets[n].offset = ntohl(ofs32[n])); +- last = offsets[n].offset; +- offsets[n].flags = 0; +- } +- return (char *) "32BE v0.68"; +- } +- else { /* V3.0 */ ++ else { /* V3.0 or V0.68 */ + unsigned long i; + loff_t j; +- static char v3[11]; + +- v3_64 = (ofs32[1] == 0) ? 2 : 1; +- for (i = n; i-- != 0; ) +- offsets[i].size = ntohl(ofs32[i*v3_64]); ++ for (i = 0; i < n && ntohl(ofs32[i]) < ntohl(ofs32[i+1]); i++); ++ if (i == n && ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ ++ loff_t last = ntohl(ofs32[n]); ++ while (n--) { ++ offsets[n].size = last - ++ (offsets[n].offset = ntohl(ofs32[n])); ++ last = offsets[n].offset; ++ offsets[n].flags = 0; ++ } ++ return (char *) "32BE v0.68"; ++ } ++ ++ v3_64 = (ofs32[1] == 0); ++ for (i = n; i-- != 0; ) { ++ offsets[i].size = ntohl(ofs32[i << v3_64]); ++ if (offsets[i].size == 0xFFFFFFFF) { ++ offsets[i].size = 0x10000000 | block_size; ++ } ++ offsets[i].flags = (offsets[i].size >> 28); ++ offsets[i].size &= 0x0FFFFFFF; ++ } + for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { + offsets[i].offset = j; +- offsets[i].flags = global_flags; +- if ((offsets[i].size & 0x80000000) == 0) { ++ if (offsets[i].flags < 8) { + j += offsets[i].size; + } +- else if (offsets[i].size == 0xFFFFFFFF) { +- offsets[i].flags = CLOOP_COMPRESSOR_NONE; +- j += offsets[i].size = block_size; +- } + } + for (i = 0; i < n; i++) { +- if (offsets[i].size & 0x80000000) { +- offsets[i] = offsets[offsets[i].size & 0x7FFFFFFF]; ++ flags |= 1 << offsets[i].flags; ++ if (offsets[i].flags >= 8) { ++ offsets[i] = offsets[offsets[i].size]; + } + } +- strcpy(v3, (char *) (--v3_64) ? "64BE v3.0a" : "32BE v3.0a"); +- v3[10] += global_flags; +- return v3; ++ strcpy(v, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a"); ++ } ++ v[10] = 'a' + ((flags-1) & 0xF); // compressors used ++ if (flags > 0x10) { // with links ? ++ v[10] += 'A' - 'a'; + } ++ return v; + } + + /* Cloop suspend IOCTL */ +--- cloopreader.c ++++ cloopreader.c +@@ -52,7 +52,7 @@ + bfuncinfo("fh=%d",fh); + c->fh=fh; + struct cloop_head head; +- int v4_header_last, flags; ++ int v4_header_last; + loff_t end; + + for (v4_header_last=0;;v4_header_last++) { +@@ -83,23 +83,21 @@ + c->numblocks = ntohl(tail.num_blocks); + c->tocsize = sizeof(*c->toc) * c->numblocks; + len = ntohl(tail.table_size); +- flags = CLOOP3_BLOCKS_FLAGS(ntohl(tail.index_size)); + toclen = CLOOP3_INDEX_SIZE(ntohl(tail.index_size)) * c->numblocks; + OP(lseek(c->fh, end - sizeof(tail) - len, SEEK_SET)); + ALLOC(c->toc, sizeof(*c->toc) * c->numblocks); + ALLOC(p,len); + OP(read_all(c->fh,p,len)); /* read Data Index */ +- if (unpack[flags]((void *)c->toc,&toclen,p,len) != Z_OK) ++ if (unpack[CLOOP_COMPRESSOR_ZLIB]((void *)c->toc,&toclen,p,len) != Z_OK) + exit(1); + free(p); + } + else { +- flags = 0; + 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->blocksize, flags); ++ build_index(c->toc, c->numblocks, c->blocksize); + c->cblocksizecur=0; + c->curblock=-1; + return 0; +--- create_compressed_fs.c ++++ create_compressed_fs.c +@@ -179,7 +179,6 @@ + static unsigned long block_size = 0; + static void flush_index(int sig) + { +- static char padding[512]; + struct cloop_tail tail; + unsigned long len; + int flags = 0; +@@ -187,24 +186,21 @@ + fprintf(stderr, "Write index for %u blocks\n", n); + if (block_size >= 0x1000000) lastlen = 0; + if (sig) flags = 0x80; +- if (compress3 == xz_compress) { +- flags |= (CLOOP_COMPRESSOR_XZ << 4); +- } +- if (compress3 == lz4_compress) { +- flags |= (CLOOP_COMPRESSOR_LZ4 << 4); +- } + tail.index_size = ntohl(sizeof(*block_index) + flags + 256*(lastlen % 0xFFffFF)); + tail.num_blocks = ntohl(n); + n *= sizeof(*block_index); + len = GZIP_MAX_BUFFER(n); + compressed = (unsigned char *) realloc(compressed, len); +- if (!compressed || compress3(compressed, &len, (unsigned char *) block_index, ++#ifdef FIND_BEST_COMPRESSION ++ if (!compressed || best_compress(compressed, &len, (unsigned char *) block_index, ++#else ++ if (!compressed || compress2(compressed, &len, (unsigned char *) block_index, ++#endif + n, Z_BEST_SPEED) != 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)); + exit(sig != 0); +@@ -242,7 +238,7 @@ + #endif + block_size = atoi(argv[1]); + } +- if (block_size < 4096) ++ if (block_size < 4096 || block_size > 0x0FFFFFFF) + block_size = DEFAULT_BLOCKSIZE; + fprintf(stderr, "Block size is %lu\n", block_size); + zlenmax = block_size + block_size/1000 + 12; +@@ -280,7 +276,7 @@ + quit("Realloc hash"); + } + hash[n] = md5sum(uncompressed, len); +- j = 0x7FFFFFFF; ++ j = 0x0FFFFFFF; + if (n < j) + j = n; + for (i = 0; i < j; i++) { +@@ -289,7 +285,7 @@ + break; + } + if (i != j) { +- block_index[n] = ntohl(0x80000000 | i); ++ block_index[n] = ntohl((CLOOP_COMPRESSOR_LINK >> 28) | i); + fprintf(stderr, "Block %u length %lu => duplicate %u\n", + n, block_size, i); + continue; +@@ -299,7 +295,7 @@ + if (compress3(compressed, &len, uncompressed, lastlen, + Z_BEST_SPEED) != Z_OK || len >= lastlen) { + len = lastlen; +- block_index[n] = ntohl(0xFFFFFFFF); ++ block_index[n] = ntohl((CLOOP_COMPRESSOR_NONE >> 28) | lastlen); + write(STDOUT_FILENO, uncompressed, len); + } + else { +--- extract_compressed_fs.c ++++ extract_compressed_fs.c +@@ -69,9 +69,8 @@ + + int main(int argc, char *argv[]) + { +- int flags; + struct cloop_head head; +- unsigned int i, v4_header_last, global_flags; ++ unsigned int i, v4_header_last; + unsigned long n, len; + uLongf ulen; + loff_t end; +@@ -128,12 +127,6 @@ + table_size = ntohl(tail.table_size); + table = malloc(table_size); + len = num_blocks * CLOOP3_INDEX_SIZE(ntohl(tail.index_size)); +- global_flags = CLOOP3_BLOCKS_FLAGS(ntohl(tail.index_size)); +- if (global_flags > CLOOP_COMPRESSOR_MAX) { +- fprintf(stderr, "Unsupported compression %d\n", +- global_flags); +- exit(1); +- } + ulen = num_blocks * sizeof(*offsets); + offsets = malloc(ulen); + if (!table || !offsets || !buffer || !clear_buffer) { +@@ -144,16 +137,15 @@ + perror("Reading index\n"); + exit(1); + } +- err = unpack[global_flags]((void *) offsets, &ulen, table, table_size); ++ err = unpack[CLOOP_COMPRESSOR_ZLIB]((void *) offsets, &ulen, table, table_size); + if (err != Z_OK) { + fprintf(stderr, "Unpack %s index error %d\n", +- packnames[global_flags],err); ++ packnames[CLOOP_COMPRESSOR_ZLIB],err); + exit(1); + } + free(table); + } + else { +- global_flags = 0; + len = num_blocks * sizeof(*offsets); + offsets = malloc(len); + if (v4_header_last) { +@@ -182,7 +174,7 @@ + exit(0); + } + #endif +- fprintf(stderr, "Index %s.\n", build_index(offsets, num_blocks, block_size, global_flags)); ++ fprintf(stderr, "Index %s.\n", build_index(offsets, num_blocks, block_size)); + + #if 1 + if (getenv("CLOOP_TABLE") != NULL) { diff -r 36e9a3dcd5de -r cea6e929d21e linux-cloop/stuff/cloop.u --- a/linux-cloop/stuff/cloop.u Mon May 04 09:05:12 2020 +0000 +++ b/linux-cloop/stuff/cloop.u Tue May 05 11:06:44 2020 +0000 @@ -1373,3 +1373,178 @@ } return 0; init_out_dealloc: +--- cloop.h ++++ cloop.h +@@ -86,11 +86,8 @@ + struct cloop_tail + { + u_int32_t table_size; +- u_int32_t index_size; /* size:4 comp:3 ctrl-c:1 lastlen:24 */ ++ u_int32_t index_size; /* size:4 unused:3 ctrl-c:1 lastlen:24 */ + #define CLOOP3_INDEX_SIZE(x) ((unsigned int)((x) & 0xF)) +-#define CLOOP3_BLOCKS_FLAGS(x) ((unsigned int)((x) & 0x70) >> 4) +-#define CLOOP3_TRUNCATED(x) ((unsigned int)((x) & 0x80) >> 7) +-#define CLOOP3_LASTLEN(x) (unsigned int)((x) >> 8) + u_int32_t num_blocks; + }; + +@@ -104,8 +101,10 @@ + }; + + static inline char *build_index(struct block_info *offsets, unsigned long n, +- unsigned long block_size, unsigned global_flags) ++ unsigned long block_size) + { ++ static char v[11]; ++ u_int32_t flags = 0; + u_int32_t *ofs32 = (u_int32_t *) offsets; + loff_t *ofs64 = (loff_t *) offsets; + +@@ -130,8 +129,6 @@ + } + else { /* V2.0/V4.0 */ + loff_t last = CLOOP_BLOCK_OFFSET(__be64_to_cpu(ofs64[n])); +- u_int32_t flags; +- static char v4[11]; + unsigned long i = n; + + for (flags = 0; n-- ;) { +@@ -149,12 +146,7 @@ + offsets[i] = offsets[offsets[i].offset]; + } + } +- strcpy(v4, (char *) "64BE v4.0a"); +- v4[10] = 'a' + ((flags-1) & 0xF); // compressors used +- if (flags > 0x10) { // with links ? +- v4[10] += 'A' - 'a'; +- } +- return v4; ++ strcpy(v, (char *) "64BE v4.0a"); + } + } + else if (ofs32[1] == 0 && v3_64 == 0) { /* V1.0 */ +@@ -170,7 +162,6 @@ + else { /* V3.0 or V0.68 */ + unsigned long i; + loff_t j; +- static char v3[11]; + + for (i = 0; i < n && ntohl(ofs32[i]) < ntohl(ofs32[i+1]); i++); + if (i == n && ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ +@@ -185,28 +176,33 @@ + } + + v3_64 = (ofs32[1] == 0); +- for (i = n; i-- != 0; ) ++ for (i = n; i-- != 0; ) { + offsets[i].size = ntohl(ofs32[i << v3_64]); +- for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { +- offsets[i].offset = j; +- offsets[i].flags = global_flags; + if (offsets[i].size == 0xFFFFFFFF) { +- offsets[i].flags = CLOOP_COMPRESSOR_NONE; +- offsets[i].size = block_size; ++ offsets[i].size = 0x10000000 | block_size; + } +- if ((offsets[i].size & 0x80000000) == 0) { ++ offsets[i].flags = (offsets[i].size >> 28); ++ offsets[i].size &= 0x0FFFFFFF; ++ } ++ for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { ++ offsets[i].offset = j; ++ if (offsets[i].flags < 8) { + j += offsets[i].size; + } + } + for (i = 0; i < n; i++) { +- if (offsets[i].size & 0x80000000) { +- offsets[i] = offsets[offsets[i].size & 0x7FFFFFFF]; ++ flags |= 1 << offsets[i].flags; ++ if (offsets[i].flags >= 8) { ++ offsets[i] = offsets[offsets[i].size]; + } + } +- strcpy(v3, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a"); +- v3[10] += global_flags; +- return v3; ++ strcpy(v, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a"); ++ } ++ v[10] = 'a' + ((flags-1) & 0xF); // compressors used ++ if (flags > 0x10) { // with links ? ++ v[10] += 'A' - 'a'; + } ++ return v; + } + + /* Cloop suspend IOCTL */ +--- cloop.c ++++ cloop.c +@@ -542,7 +542,7 @@ + const unsigned int header_size = sizeof(struct cloop_head); + unsigned int i, total_offsets=0; + loff_t fs_read_position = 0, header_pos[2]; +- int flags, isblkdev, bytes_read, error = 0; ++ int isblkdev, bytes_read, error = 0; + if (clo->suspended) return error; + #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) + inode = file->f_dentry->d_inode; +@@ -698,18 +698,12 @@ + error=-EBADF; goto error_release; + } + len = CLOOP3_INDEX_SIZE(ntohl(tail.index_size)) * total_offsets; +- flags = CLOOP3_BLOCKS_FLAGS(ntohl(tail.index_size)); +-// May 3 19:45:20 (none) user.info kernel: cloop: uncompress(clo=e0a78000, block_ptrs=e0c9c000, &len(1440)=ddc05e6c, zbuf=e0c9f000, zlen=43, flag=0) +-printk(KERN_INFO "%s: uncompress(clo=%p, block_ptrs=%p, &len(%ld)=%p, zbuf=%p, zlen=%ld, flag=%d)\n", cloop_name, +- clo, clo->block_ptrs, len, &len, zbuf, zlen, flags); +- ret = uncompress(clo, (void *) clo->block_ptrs, &len, zbuf, zlen, flags); +-// May 3 19:45:20 (none) user.alert kernel: BUG: unable to handle kernel NULL pointer dereference at (null) +-printk(KERN_INFO "%s: uncompressed !\n", cloop_name); ++ ret = uncompress(clo, (void *) clo->block_ptrs, &len, zbuf, zlen, CLOOP_COMPRESSOR_ZLIB); + cloop_free(zbuf, zlen); + if (ret != 0) + { +- printk(KERN_ERR "%s: decompression error %i uncompressing index, flags %u\n", +- cloop_name, ret, flags); ++ printk(KERN_ERR "%s: decompression error %i uncompressing index\n", ++ cloop_name, ret); + error=-EBADF; goto error_release; + } + } +@@ -722,7 +716,6 @@ + else + { + unsigned int n, total_bytes; +- flags = 0; + clo->block_ptrs = cloop_malloc(sizeof(struct block_info) * total_offsets); + if (!clo->block_ptrs) + { +@@ -761,7 +754,7 @@ + } + { + int i; +- char *version = build_index(clo->block_ptrs, clo->head.num_blocks, clo->head.block_size, flags); ++ char *version = build_index(clo->block_ptrs, clo->head.num_blocks, clo->head.block_size); + clo->largest_block = 0; + for (i = 0; i < clo->head.num_blocks; i++) + if (clo->block_ptrs[i].size > clo->largest_block) +@@ -769,9 +762,6 @@ + printk(KERN_INFO "%s: %s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n", + cloop_name, clo->underlying_filename, version, clo->head.num_blocks, + clo->head.block_size, clo->largest_block); +- } +- { +- int i; + clo->num_buffered_blocks = (buffers > 0 && clo->head.block_size >= 512) ? + (buffers / clo->head.block_size) : 1; + clo->buffered_blocknum = cloop_malloc(clo->num_buffered_blocks * sizeof (u_int32_t)); +@@ -874,6 +864,10 @@ + cloop_free(clo->block_ptrs, sizeof(struct block_info) * total_offsets); + clo->block_ptrs=NULL; + error_release: ++#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE)) ++ zlib_inflateEnd(&clo->zstream); ++ if(clo->zstream.workspace) { cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); clo->zstream.workspace = NULL; } ++#endif + if(bbuf) cloop_free(bbuf, clo->underlying_blksize); + if(clo->underlying_filename) { kfree(clo->underlying_filename); clo->underlying_filename=NULL; } + clo->backing_file=NULL; diff -r 36e9a3dcd5de -r cea6e929d21e linux64-cloop/stuff/cloop.u --- a/linux64-cloop/stuff/cloop.u Mon May 04 09:05:12 2020 +0000 +++ b/linux64-cloop/stuff/cloop.u Tue May 05 11:06:44 2020 +0000 @@ -1373,3 +1373,178 @@ } return 0; init_out_dealloc: +--- cloop.h ++++ cloop.h +@@ -86,11 +86,8 @@ + struct cloop_tail + { + u_int32_t table_size; +- u_int32_t index_size; /* size:4 comp:3 ctrl-c:1 lastlen:24 */ ++ u_int32_t index_size; /* size:4 unused:3 ctrl-c:1 lastlen:24 */ + #define CLOOP3_INDEX_SIZE(x) ((unsigned int)((x) & 0xF)) +-#define CLOOP3_BLOCKS_FLAGS(x) ((unsigned int)((x) & 0x70) >> 4) +-#define CLOOP3_TRUNCATED(x) ((unsigned int)((x) & 0x80) >> 7) +-#define CLOOP3_LASTLEN(x) (unsigned int)((x) >> 8) + u_int32_t num_blocks; + }; + +@@ -104,8 +101,10 @@ + }; + + static inline char *build_index(struct block_info *offsets, unsigned long n, +- unsigned long block_size, unsigned global_flags) ++ unsigned long block_size) + { ++ static char v[11]; ++ u_int32_t flags = 0; + u_int32_t *ofs32 = (u_int32_t *) offsets; + loff_t *ofs64 = (loff_t *) offsets; + +@@ -130,8 +129,6 @@ + } + else { /* V2.0/V4.0 */ + loff_t last = CLOOP_BLOCK_OFFSET(__be64_to_cpu(ofs64[n])); +- u_int32_t flags; +- static char v4[11]; + unsigned long i = n; + + for (flags = 0; n-- ;) { +@@ -149,12 +146,7 @@ + offsets[i] = offsets[offsets[i].offset]; + } + } +- strcpy(v4, (char *) "64BE v4.0a"); +- v4[10] = 'a' + ((flags-1) & 0xF); // compressors used +- if (flags > 0x10) { // with links ? +- v4[10] += 'A' - 'a'; +- } +- return v4; ++ strcpy(v, (char *) "64BE v4.0a"); + } + } + else if (ofs32[1] == 0 && v3_64 == 0) { /* V1.0 */ +@@ -170,7 +162,6 @@ + else { /* V3.0 or V0.68 */ + unsigned long i; + loff_t j; +- static char v3[11]; + + for (i = 0; i < n && ntohl(ofs32[i]) < ntohl(ofs32[i+1]); i++); + if (i == n && ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ +@@ -185,28 +176,33 @@ + } + + v3_64 = (ofs32[1] == 0); +- for (i = n; i-- != 0; ) ++ for (i = n; i-- != 0; ) { + offsets[i].size = ntohl(ofs32[i << v3_64]); +- for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { +- offsets[i].offset = j; +- offsets[i].flags = global_flags; + if (offsets[i].size == 0xFFFFFFFF) { +- offsets[i].flags = CLOOP_COMPRESSOR_NONE; +- offsets[i].size = block_size; ++ offsets[i].size = 0x10000000 | block_size; + } +- if ((offsets[i].size & 0x80000000) == 0) { ++ offsets[i].flags = (offsets[i].size >> 28); ++ offsets[i].size &= 0x0FFFFFFF; ++ } ++ for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { ++ offsets[i].offset = j; ++ if (offsets[i].flags < 8) { + j += offsets[i].size; + } + } + for (i = 0; i < n; i++) { +- if (offsets[i].size & 0x80000000) { +- offsets[i] = offsets[offsets[i].size & 0x7FFFFFFF]; ++ flags |= 1 << offsets[i].flags; ++ if (offsets[i].flags >= 8) { ++ offsets[i] = offsets[offsets[i].size]; + } + } +- strcpy(v3, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a"); +- v3[10] += global_flags; +- return v3; ++ strcpy(v, (char *) (v3_64) ? "64BE v3.0a" : "32BE v3.0a"); ++ } ++ v[10] = 'a' + ((flags-1) & 0xF); // compressors used ++ if (flags > 0x10) { // with links ? ++ v[10] += 'A' - 'a'; + } ++ return v; + } + + /* Cloop suspend IOCTL */ +--- cloop.c ++++ cloop.c +@@ -542,7 +542,7 @@ + const unsigned int header_size = sizeof(struct cloop_head); + unsigned int i, total_offsets=0; + loff_t fs_read_position = 0, header_pos[2]; +- int flags, isblkdev, bytes_read, error = 0; ++ int isblkdev, bytes_read, error = 0; + if (clo->suspended) return error; + #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) + inode = file->f_dentry->d_inode; +@@ -698,18 +698,12 @@ + error=-EBADF; goto error_release; + } + len = CLOOP3_INDEX_SIZE(ntohl(tail.index_size)) * total_offsets; +- flags = CLOOP3_BLOCKS_FLAGS(ntohl(tail.index_size)); +-// May 3 19:45:20 (none) user.info kernel: cloop: uncompress(clo=e0a78000, block_ptrs=e0c9c000, &len(1440)=ddc05e6c, zbuf=e0c9f000, zlen=43, flag=0) +-printk(KERN_INFO "%s: uncompress(clo=%p, block_ptrs=%p, &len(%ld)=%p, zbuf=%p, zlen=%ld, flag=%d)\n", cloop_name, +- clo, clo->block_ptrs, len, &len, zbuf, zlen, flags); +- ret = uncompress(clo, (void *) clo->block_ptrs, &len, zbuf, zlen, flags); +-// May 3 19:45:20 (none) user.alert kernel: BUG: unable to handle kernel NULL pointer dereference at (null) +-printk(KERN_INFO "%s: uncompressed !\n", cloop_name); ++ ret = uncompress(clo, (void *) clo->block_ptrs, &len, zbuf, zlen, CLOOP_COMPRESSOR_ZLIB); + cloop_free(zbuf, zlen); + if (ret != 0) + { +- printk(KERN_ERR "%s: decompression error %i uncompressing index, flags %u\n", +- cloop_name, ret, flags); ++ printk(KERN_ERR "%s: decompression error %i uncompressing index\n", ++ cloop_name, ret); + error=-EBADF; goto error_release; + } + } +@@ -722,7 +716,6 @@ + else + { + unsigned int n, total_bytes; +- flags = 0; + clo->block_ptrs = cloop_malloc(sizeof(struct block_info) * total_offsets); + if (!clo->block_ptrs) + { +@@ -761,7 +754,7 @@ + } + { + int i; +- char *version = build_index(clo->block_ptrs, clo->head.num_blocks, clo->head.block_size, flags); ++ char *version = build_index(clo->block_ptrs, clo->head.num_blocks, clo->head.block_size); + clo->largest_block = 0; + for (i = 0; i < clo->head.num_blocks; i++) + if (clo->block_ptrs[i].size > clo->largest_block) +@@ -769,9 +762,6 @@ + printk(KERN_INFO "%s: %s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n", + cloop_name, clo->underlying_filename, version, clo->head.num_blocks, + clo->head.block_size, clo->largest_block); +- } +- { +- int i; + clo->num_buffered_blocks = (buffers > 0 && clo->head.block_size >= 512) ? + (buffers / clo->head.block_size) : 1; + clo->buffered_blocknum = cloop_malloc(clo->num_buffered_blocks * sizeof (u_int32_t)); +@@ -874,6 +864,10 @@ + cloop_free(clo->block_ptrs, sizeof(struct block_info) * total_offsets); + clo->block_ptrs=NULL; + error_release: ++#if (defined(CONFIG_ZLIB_INFLATE) || defined(CONFIG_ZLIB_INFLATE_MODULE)) ++ zlib_inflateEnd(&clo->zstream); ++ if(clo->zstream.workspace) { cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); clo->zstream.workspace = NULL; } ++#endif + if(bbuf) cloop_free(bbuf, clo->underlying_blksize); + if(clo->underlying_filename) { kfree(clo->underlying_filename); clo->underlying_filename=NULL; } + clo->backing_file=NULL; diff -r 36e9a3dcd5de -r cea6e929d21e ocsinventory-server/receipt --- a/ocsinventory-server/receipt Mon May 04 09:05:12 2020 +0000 +++ b/ocsinventory-server/receipt Tue May 05 11:06:44 2020 +0000 @@ -7,7 +7,7 @@ MAINTAINER="pascal.bellard@slitaz.org" LICENSE="GPL2" SOURCE="OCSNG_UNIX_SERVER" -WEB_SITE="http://www.ocsinventory-ng.org/index.php?page=English" +WEB_SITE="https://www.ocsinventory-ng.org/index.php?page=English" WANTED="ocsinventory" DEPENDS="apache php-apache mysql perl perl-xml-simple perl-compress-raw-zlib diff -r 36e9a3dcd5de -r cea6e929d21e ocsinventory/receipt --- a/ocsinventory/receipt Mon May 04 09:05:12 2020 +0000 +++ b/ocsinventory/receipt Tue May 05 11:06:44 2020 +0000 @@ -8,7 +8,7 @@ LICENSE="GPL2" SOURCE="OCSNG_UNIX_SERVER" TARBALL="$SOURCE-$VERSION.tar.gz" -WEB_SITE="http://www.ocsinventory-ng.org/" +WEB_SITE="https://www.ocsinventory-ng.org/" WGET_URL="https://launchpad.net/ocsinventory-server/stable-${VERSION%.*}/$VERSION/+download/$TARBALL" TAGS="system administration" diff -r 36e9a3dcd5de -r cea6e929d21e ocsreports/receipt --- a/ocsreports/receipt Mon May 04 09:05:12 2020 +0000 +++ b/ocsreports/receipt Tue May 05 11:06:44 2020 +0000 @@ -8,7 +8,7 @@ LICENSE="GPL2" WANTED="ocsinventory" SOURCE="OCSNG_UNIX_SERVER" -WEB_SITE="http://www.ocsinventory-ng.org/" +WEB_SITE="https://www.ocsinventory-ng.org/" TAGS="system administration" DEPENDS="php-apache php-mysql mysql" diff -r 36e9a3dcd5de -r cea6e929d21e qemu/stuff/cloop.u --- a/qemu/stuff/cloop.u Mon May 04 09:05:12 2020 +0000 +++ b/qemu/stuff/cloop.u Tue May 05 11:06:44 2020 +0000 @@ -402,3 +402,128 @@ -qcow.o-libs := -lz +qcow.o-libs := -lz -llzma linux-aio.o-libs := -laio +--- block/cloop.c ++++ block/cloop.c +@@ -48,7 +48,6 @@ + } cloop_tail; + + #define CLOOP3_INDEX_SIZE(x) ((unsigned int)((x) & 0xF)) +-#define CLOOP3_BLOCKS_FLAGS(x) ((unsigned int)((x) & 0x70) >> 4) + + typedef struct block_info { + uint64_t offset; /* 64-bit offsets of compressed block */ +@@ -57,7 +56,7 @@ + } block_info; + + static inline int build_index(struct block_info *offsets, unsigned long n, +- unsigned long block_size, unsigned global_flags) ++ unsigned long block_size) + { + uint32_t *ofs32 = (uint32_t *) offsets; + loff_t *ofs64 = (loff_t *) offsets; +@@ -118,42 +117,44 @@ + offsets[n].flags = 0; + } + } +- else if (be32_to_cpu(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ +- loff_t last = be32_to_cpu(ofs32[n]); +- while (n--) { +- offsets[n].size = last - +- (offsets[n].offset = be32_to_cpu(ofs32[n])); +- if (offsets[n].size > 2 * MAX_BLOCK_SIZE) +- return n+1; +- last = offsets[n].offset; +- offsets[n].flags = 0; +- } +- } +- else { /* V3.0 */ ++ else { /* V3.0 or V0.68 */ + unsigned long i; + loff_t j; + +- v3_64 = (ofs32[1] == 0) ? 2 : 1; ++ for (i = 0; i < n && be32_to_cpu(ofs32[i]) < be32_to_cpu(ofs32[i+1]); i++); ++ if (i == n && be32_to_cpu(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ ++ loff_t last = be32_to_cpu(ofs32[n]); ++ while (n--) { ++ offsets[n].size = last - ++ (offsets[n].offset = be32_to_cpu(ofs32[n])); ++ if (offsets[n].size > 2 * MAX_BLOCK_SIZE) ++ return n+1; ++ last = offsets[n].offset; ++ offsets[n].flags = 0; ++ } ++ return 0; ++ } ++ ++ v3_64 = (ofs32[1] == 0); + for (i = n; i-- > 0; ) { +- offsets[i].size = be32_to_cpu(ofs32[i*v3_64]); +- if ((offsets[i].size & 0x80000000) == 0 && +- offsets[i].size > 2 * MAX_BLOCK_SIZE) ++ offsets[i].size = be32_to_cpu(ofs32[i << v3_64]); ++ if (offsets[i].size == 0xFFFFFFFF) { ++ offsets[i].size = 0x10000000 | block_size; ++ } ++ offsets[i].flags = (offsets[i].size >> 28); ++ offsets[i].size &= 0x0FFFFFFF; ++ if (offsets[i].size > 2 * MAX_BLOCK_SIZE) + return i+1; + } + for (i = 0, j = 128 + 4 + 4; i < n; i++) { + offsets[i].offset = j; +- offsets[i].flags = global_flags; +- if (offsets[i].size == 0xFFFFFFFF) { +- offsets[i].flags = CLOOP_COMPRESSOR_NONE; +- offsets[i].size = block_size; +- } +- if ((offsets[i].size & 0x80000000) == 0) { ++ if (offsets[i].flags < 8) { + j += offsets[i].size; + } + } + for (i = 0; i < n; i++) { +- if (offsets[i].size & 0x80000000) { +- offsets[i] = offsets[offsets[i].size & 0x7FFFFFFF]; ++ if (offsets[i].flags >= 8) { ++ offsets[i] = offsets[offsets[i].size]; + } + } + } +@@ -170,7 +171,6 @@ + uint8_t *compressed_block; + uint8_t *uncompressed_block; + z_stream zstream; +- int global_flags; + } BDRVCloopState; + + static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename) +@@ -305,7 +305,6 @@ + } + len = be32_to_cpu(tail.table_size); + toclen = CLOOP3_INDEX_SIZE(be32_to_cpu(tail.index_size)) * s->n_blocks; +- s->global_flags = CLOOP3_BLOCKS_FLAGS(be32_to_cpu(tail.index_size)); + + s->offsets = g_malloc(offsets_size); + p = g_malloc(len); +@@ -316,9 +315,9 @@ + } + s->zstream.next_in = p; + s->zstream.avail_in = len; +- s->zstream.next_out = s->offsets; ++ s->zstream.next_out = (void *) s->offsets; + s->zstream.avail_out = toclen; +- if (cloop_unpack(s, s->global_flags) == 0) { ++ if (cloop_unpack(s, CLOOP_COMPRESSOR_ZLIB) == 0) { + ret = -EINVAL; + goto fail; + } +@@ -342,7 +341,7 @@ + goto fail; + } + } +- ret = build_index(s->offsets, s->n_blocks, s->block_size, s->global_flags); ++ ret = build_index(s->offsets, s->n_blocks, s->block_size); + if (ret) { + error_setg(errp, "invalid compressed block size at index %u, " + "image file is corrupt", ret-1);