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);