wok diff qemu/stuff/cloop.u @ rev 23762
fusecloop, linux-cloop, qemu: multicompressor support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Tue May 05 11:06:44 2020 +0000 (2020-05-05) |
parents | 09045e83f959 |
children | 2ac876d0d151 |
line diff
1.1 --- a/qemu/stuff/cloop.u Mon Apr 27 09:29:39 2020 +0000 1.2 +++ b/qemu/stuff/cloop.u Tue May 05 11:06:44 2020 +0000 1.3 @@ -402,3 +402,128 @@ 1.4 -qcow.o-libs := -lz 1.5 +qcow.o-libs := -lz -llzma 1.6 linux-aio.o-libs := -laio 1.7 +--- block/cloop.c 1.8 ++++ block/cloop.c 1.9 +@@ -48,7 +48,6 @@ 1.10 + } cloop_tail; 1.11 + 1.12 + #define CLOOP3_INDEX_SIZE(x) ((unsigned int)((x) & 0xF)) 1.13 +-#define CLOOP3_BLOCKS_FLAGS(x) ((unsigned int)((x) & 0x70) >> 4) 1.14 + 1.15 + typedef struct block_info { 1.16 + uint64_t offset; /* 64-bit offsets of compressed block */ 1.17 +@@ -57,7 +56,7 @@ 1.18 + } block_info; 1.19 + 1.20 + static inline int build_index(struct block_info *offsets, unsigned long n, 1.21 +- unsigned long block_size, unsigned global_flags) 1.22 ++ unsigned long block_size) 1.23 + { 1.24 + uint32_t *ofs32 = (uint32_t *) offsets; 1.25 + loff_t *ofs64 = (loff_t *) offsets; 1.26 +@@ -118,42 +117,44 @@ 1.27 + offsets[n].flags = 0; 1.28 + } 1.29 + } 1.30 +- else if (be32_to_cpu(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ 1.31 +- loff_t last = be32_to_cpu(ofs32[n]); 1.32 +- while (n--) { 1.33 +- offsets[n].size = last - 1.34 +- (offsets[n].offset = be32_to_cpu(ofs32[n])); 1.35 +- if (offsets[n].size > 2 * MAX_BLOCK_SIZE) 1.36 +- return n+1; 1.37 +- last = offsets[n].offset; 1.38 +- offsets[n].flags = 0; 1.39 +- } 1.40 +- } 1.41 +- else { /* V3.0 */ 1.42 ++ else { /* V3.0 or V0.68 */ 1.43 + unsigned long i; 1.44 + loff_t j; 1.45 + 1.46 +- v3_64 = (ofs32[1] == 0) ? 2 : 1; 1.47 ++ for (i = 0; i < n && be32_to_cpu(ofs32[i]) < be32_to_cpu(ofs32[i+1]); i++); 1.48 ++ if (i == n && be32_to_cpu(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ 1.49 ++ loff_t last = be32_to_cpu(ofs32[n]); 1.50 ++ while (n--) { 1.51 ++ offsets[n].size = last - 1.52 ++ (offsets[n].offset = be32_to_cpu(ofs32[n])); 1.53 ++ if (offsets[n].size > 2 * MAX_BLOCK_SIZE) 1.54 ++ return n+1; 1.55 ++ last = offsets[n].offset; 1.56 ++ offsets[n].flags = 0; 1.57 ++ } 1.58 ++ return 0; 1.59 ++ } 1.60 ++ 1.61 ++ v3_64 = (ofs32[1] == 0); 1.62 + for (i = n; i-- > 0; ) { 1.63 +- offsets[i].size = be32_to_cpu(ofs32[i*v3_64]); 1.64 +- if ((offsets[i].size & 0x80000000) == 0 && 1.65 +- offsets[i].size > 2 * MAX_BLOCK_SIZE) 1.66 ++ offsets[i].size = be32_to_cpu(ofs32[i << v3_64]); 1.67 ++ if (offsets[i].size == 0xFFFFFFFF) { 1.68 ++ offsets[i].size = 0x10000000 | block_size; 1.69 ++ } 1.70 ++ offsets[i].flags = (offsets[i].size >> 28); 1.71 ++ offsets[i].size &= 0x0FFFFFFF; 1.72 ++ if (offsets[i].size > 2 * MAX_BLOCK_SIZE) 1.73 + return i+1; 1.74 + } 1.75 + for (i = 0, j = 128 + 4 + 4; i < n; i++) { 1.76 + offsets[i].offset = j; 1.77 +- offsets[i].flags = global_flags; 1.78 +- if (offsets[i].size == 0xFFFFFFFF) { 1.79 +- offsets[i].flags = CLOOP_COMPRESSOR_NONE; 1.80 +- offsets[i].size = block_size; 1.81 +- } 1.82 +- if ((offsets[i].size & 0x80000000) == 0) { 1.83 ++ if (offsets[i].flags < 8) { 1.84 + j += offsets[i].size; 1.85 + } 1.86 + } 1.87 + for (i = 0; i < n; i++) { 1.88 +- if (offsets[i].size & 0x80000000) { 1.89 +- offsets[i] = offsets[offsets[i].size & 0x7FFFFFFF]; 1.90 ++ if (offsets[i].flags >= 8) { 1.91 ++ offsets[i] = offsets[offsets[i].size]; 1.92 + } 1.93 + } 1.94 + } 1.95 +@@ -170,7 +171,6 @@ 1.96 + uint8_t *compressed_block; 1.97 + uint8_t *uncompressed_block; 1.98 + z_stream zstream; 1.99 +- int global_flags; 1.100 + } BDRVCloopState; 1.101 + 1.102 + static int cloop_probe(const uint8_t *buf, int buf_size, const char *filename) 1.103 +@@ -305,7 +305,6 @@ 1.104 + } 1.105 + len = be32_to_cpu(tail.table_size); 1.106 + toclen = CLOOP3_INDEX_SIZE(be32_to_cpu(tail.index_size)) * s->n_blocks; 1.107 +- s->global_flags = CLOOP3_BLOCKS_FLAGS(be32_to_cpu(tail.index_size)); 1.108 + 1.109 + s->offsets = g_malloc(offsets_size); 1.110 + p = g_malloc(len); 1.111 +@@ -316,9 +315,9 @@ 1.112 + } 1.113 + s->zstream.next_in = p; 1.114 + s->zstream.avail_in = len; 1.115 +- s->zstream.next_out = s->offsets; 1.116 ++ s->zstream.next_out = (void *) s->offsets; 1.117 + s->zstream.avail_out = toclen; 1.118 +- if (cloop_unpack(s, s->global_flags) == 0) { 1.119 ++ if (cloop_unpack(s, CLOOP_COMPRESSOR_ZLIB) == 0) { 1.120 + ret = -EINVAL; 1.121 + goto fail; 1.122 + } 1.123 +@@ -342,7 +341,7 @@ 1.124 + goto fail; 1.125 + } 1.126 + } 1.127 +- ret = build_index(s->offsets, s->n_blocks, s->block_size, s->global_flags); 1.128 ++ ret = build_index(s->offsets, s->n_blocks, s->block_size); 1.129 + if (ret) { 1.130 + error_setg(errp, "invalid compressed block size at index %u, " 1.131 + "image file is corrupt", ret-1);