wok-current diff linux64-cloop/stuff/cloop.u @ rev 17332
Up fxload (2008_10_13)
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Wed Nov 05 14:56:51 2014 +0100 (2014-11-05) |
parents | |
children | b30e264381c7 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/linux64-cloop/stuff/cloop.u Wed Nov 05 14:56:51 2014 +0100 1.3 @@ -0,0 +1,280 @@ 1.4 +--- cloop.h 1.5 ++++ cloop.h 1.6 +@@ -20,6 +20,75 @@ 1.7 + /* data_index (num_blocks 64bit pointers, network order)... */ 1.8 + /* compressed data (gzip block compressed format)... */ 1.9 + 1.10 ++struct cloop_tail 1.11 ++{ 1.12 ++ u_int32_t table_size; 1.13 ++ u_int32_t index_size; 1.14 ++ u_int32_t num_blocks; 1.15 ++}; 1.16 ++ 1.17 ++struct block_info 1.18 ++{ 1.19 ++ loff_t offset; /* 64-bit offsets of compressed block */ 1.20 ++ u_int32_t size; /* 32-bit compressed block size */ 1.21 ++ u_int32_t optidx; /* 32-bit index number */ 1.22 ++}; 1.23 ++ 1.24 ++static inline char *build_index(struct block_info *offsets, unsigned long n) 1.25 ++{ 1.26 ++ u_int32_t *ofs32 = (u_int32_t *) offsets; 1.27 ++ loff_t *ofs64 = (loff_t *) offsets; 1.28 ++ 1.29 ++ if (ofs32[0] == 0) { 1.30 ++ if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */ 1.31 ++ while (n--) { 1.32 ++ offsets[n].offset = __be64_to_cpu(offsets[n].offset); 1.33 ++ offsets[n].size = ntohl(offsets[n].size); 1.34 ++ } 1.35 ++ return (char *) "128BE accelerated knoppix 1.0"; 1.36 ++ } 1.37 ++ else { /* V2.0 */ 1.38 ++ loff_t last = __be64_to_cpu(ofs64[n]); 1.39 ++ while (n--) { 1.40 ++ offsets[n].size = last - 1.41 ++ (offsets[n].offset = __be64_to_cpu(ofs64[n])); 1.42 ++ last = offsets[n].offset; 1.43 ++ } 1.44 ++ return (char *) "64BE v2.0"; 1.45 ++ } 1.46 ++ } 1.47 ++ else if (ofs32[1] == 0) { /* V1.0 */ 1.48 ++ loff_t last = __le64_to_cpu(ofs64[n]); 1.49 ++ while (n--) { 1.50 ++ offsets[n].size = last - 1.51 ++ (offsets[n].offset = __le64_to_cpu(ofs64[n])); 1.52 ++ last = offsets[n].offset; 1.53 ++ } 1.54 ++ return (char *) "64LE v1.0"; 1.55 ++ } 1.56 ++ else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ 1.57 ++ loff_t last = ntohl(ofs32[n]); 1.58 ++ while (n--) { 1.59 ++ offsets[n].size = last - 1.60 ++ (offsets[n].offset = ntohl(ofs32[n])); 1.61 ++ last = offsets[n].offset; 1.62 ++ } 1.63 ++ return (char *) "32BE v0.68"; 1.64 ++ } 1.65 ++ else { /* V3.0 */ 1.66 ++ unsigned long i; 1.67 ++ loff_t j; 1.68 ++ 1.69 ++ for (i = n; i-- != 0; ) 1.70 ++ offsets[i].size = ntohl(ofs32[i]); 1.71 ++ for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { 1.72 ++ offsets[i].offset = j; 1.73 ++ j += offsets[i].size; 1.74 ++ } 1.75 ++ return (char *) "32BE v3.0"; 1.76 ++ } 1.77 ++} 1.78 ++ 1.79 + /* Cloop suspend IOCTL */ 1.80 + #define CLOOP_SUSPEND 0x4C07 1.81 + 1.82 +--- cloop.c 1.83 ++++ cloop.c 1.84 +@@ -5,11 +5,18 @@ 1.85 + * A cloop file looks like this: 1.86 + * [32-bit uncompressed block size: network order] 1.87 + * [32-bit number of blocks (n_blocks): network order] 1.88 +- * [64-bit file offsets of start of blocks: network order] 1.89 ++ * [for version < 3] 1.90 ++ * [32-bit, 64-bit or 128-bit file offsets of start of blocks] 1.91 + * ... 1.92 + * (n_blocks + 1). 1.93 + * n_blocks consisting of: 1.94 + * [compressed block] 1.95 ++ * ... 1.96 ++ * [for version >= 3] 1.97 ++ * [compressed list of 32-bit block sizes] 1.98 ++ * [32-bit compressed index size: network order] 1.99 ++ * [32-bit index size = 4: network order] 1.100 ++ * [32-bit number of blocks (n_blocks): network order] 1.101 + * 1.102 + * Every version greatly inspired by code seen in loop.c 1.103 + * by Theodore Ts'o, 3/29/93. 1.104 +@@ -115,7 +122,7 @@ 1.105 + struct cloop_head head; 1.106 + 1.107 + /* An array of offsets of compressed blocks within the file */ 1.108 +- loff_t *offsets; 1.109 ++ struct block_info *offsets; 1.110 + 1.111 + /* We buffer some uncompressed blocks for performance */ 1.112 + int buffered_blocknum[BUFFERED_BLOCKS]; 1.113 +@@ -256,11 +263,11 @@ 1.114 + return i; 1.115 + } 1.116 + 1.117 +- buf_length = be64_to_cpu(clo->offsets[blocknum+1]) - be64_to_cpu(clo->offsets[blocknum]); 1.118 ++ buf_length = clo->offsets[blocknum].size; 1.119 + 1.120 + /* Load one compressed block from the file. */ 1.121 + cloop_read_from_file(clo, clo->backing_file, (char *)clo->compressed_buffer, 1.122 +- be64_to_cpu(clo->offsets[blocknum]), buf_length); 1.123 ++ clo->offsets[blocknum].offset, buf_length); 1.124 + 1.125 + buflen = ntohl(clo->head.block_size); 1.126 + 1.127 +@@ -275,9 +282,9 @@ 1.128 + if (ret != 0) 1.129 + { 1.130 + printk(KERN_ERR "%s: zlib decompression error %i uncompressing block %u %u/%lu/%u/%u " 1.131 +- "%Lu-%Lu\n", cloop_name, ret, blocknum, 1.132 ++ "%Lu:%u\n", cloop_name, ret, blocknum, 1.133 + ntohl(clo->head.block_size), buflen, buf_length, buf_done, 1.134 +- be64_to_cpu(clo->offsets[blocknum]), be64_to_cpu(clo->offsets[blocknum+1])); 1.135 ++ clo->offsets[blocknum].offset, clo->offsets[blocknum].size); 1.136 + clo->buffered_blocknum[clo->current_bufnum] = -1; 1.137 + return -1; 1.138 + } 1.139 +@@ -489,30 +496,73 @@ 1.140 + cloop_name, ntohl(clo->head.block_size)); 1.141 + error=-EBADF; goto error_release; 1.142 + } 1.143 +- if (clo->head.preamble[0x0B]!='V'||clo->head.preamble[0x0C]<'1') 1.144 +- { 1.145 +- printk(KERN_ERR "%s: Cannot read old 32-bit (version 0.68) images, " 1.146 +- "please use an older version of %s for this file.\n", 1.147 +- cloop_name, cloop_name); 1.148 +- error=-EBADF; goto error_release; 1.149 +- } 1.150 +- if (clo->head.preamble[0x0C]<'2') 1.151 +- { 1.152 +- printk(KERN_ERR "%s: Cannot read old architecture-dependent " 1.153 +- "(format <= 1.0) images, please use an older " 1.154 +- "version of %s for this file.\n", 1.155 +- cloop_name, cloop_name); 1.156 +- error=-EBADF; goto error_release; 1.157 +- } 1.158 +- total_offsets=ntohl(clo->head.num_blocks)+1; 1.159 +- if (!isblkdev && (sizeof(struct cloop_head)+sizeof(loff_t)* 1.160 ++ total_offsets=ntohl(clo->head.num_blocks); 1.161 ++ if (!isblkdev && (sizeof(struct cloop_head)+sizeof(struct block_info)* 1.162 + total_offsets > inode->i_size)) 1.163 + { 1.164 + printk(KERN_ERR "%s: file too small for %u blocks\n", 1.165 + cloop_name, ntohl(clo->head.num_blocks)); 1.166 + error=-EBADF; goto error_release; 1.167 + } 1.168 +- clo->offsets = cloop_malloc(sizeof(loff_t) * total_offsets); 1.169 ++ if (total_offsets + 1 == 0) /* Version >= 3.0 */ 1.170 ++ { 1.171 ++ struct cloop_tail tail; 1.172 ++ if(isblkdev) 1.173 ++ { 1.174 ++ /* No end of file: can't find index */ 1.175 ++ printk(KERN_ERR "%s: no V3 support for block device\n", 1.176 ++ cloop_name); 1.177 ++ error=-EBADF; goto error_release; 1.178 ++ } 1.179 ++ bytes_read = cloop_read_from_file(clo, file, (void *) &tail, 1.180 ++ inode->i_size - sizeof(struct cloop_tail), 1.181 ++ sizeof(struct cloop_tail)); 1.182 ++ if(bytes_read == sizeof(struct cloop_tail)) 1.183 ++ { 1.184 ++ unsigned long len, zlen; 1.185 ++ void *zbuf; 1.186 ++ clo->head.num_blocks = tail.num_blocks; 1.187 ++ total_offsets = ntohl(clo->head.num_blocks); 1.188 ++ clo->offsets = cloop_malloc(sizeof(struct block_info) * total_offsets); 1.189 ++ if (!clo->offsets) 1.190 ++ { 1.191 ++ printk(KERN_ERR "%s: can't alloc index\n", 1.192 ++ cloop_name); 1.193 ++ error=-EBADF; goto error_release; 1.194 ++ } 1.195 ++ zbuf = &clo->offsets[total_offsets/2]; 1.196 ++ zlen = ntohl(tail.table_size); 1.197 ++ len = ntohl(tail.index_size) * total_offsets; 1.198 ++ bytes_read = cloop_read_from_file(clo, file, zbuf, 1.199 ++ inode->i_size - zlen - sizeof(struct cloop_tail), 1.200 ++ zlen); 1.201 ++ if (bytes_read != zlen) 1.202 ++ { 1.203 ++ printk(KERN_ERR "%s: can't read index\n", 1.204 ++ cloop_name); 1.205 ++ error=-EBADF; goto error_release; 1.206 ++ } 1.207 ++ clo->zstream.workspace = cloop_malloc(zlib_inflate_workspacesize()); 1.208 ++ if(!clo->zstream.workspace) 1.209 ++ { 1.210 ++ printk(KERN_ERR "%s: can't alloc index workspace\n", 1.211 ++ cloop_name); 1.212 ++ error=-EBADF; goto error_release; 1.213 ++ } 1.214 ++ zlib_inflateInit(&clo->zstream); 1.215 ++ uncompress(clo, (void *) clo->offsets, &len, zbuf, zlen); 1.216 ++ cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); 1.217 ++ clo->zstream.workspace = NULL; 1.218 ++ break; 1.219 ++ } 1.220 ++ else 1.221 ++ { 1.222 ++ printk(KERN_ERR "%s: can't find index\n", 1.223 ++ cloop_name); 1.224 ++ error=-EBADF; goto error_release; 1.225 ++ } 1.226 ++ } 1.227 ++ clo->offsets = cloop_malloc(sizeof(struct block_info) * total_offsets); 1.228 + if (!clo->offsets) 1.229 + { 1.230 + printk(KERN_ERR "%s: out of kernel mem for offsets\n", cloop_name); 1.231 +@@ -521,19 +571,19 @@ 1.232 + } 1.233 + num_readable = MIN(total_offsets - offsets_read, 1.234 + (clo->underlying_blksize - offset) 1.235 +- / sizeof(loff_t)); 1.236 +- memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(loff_t)); 1.237 ++ / sizeof(struct block_info)); 1.238 ++ memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(struct block_info)); 1.239 + offsets_read += num_readable; 1.240 + } 1.241 + { /* Search for largest block rather than estimate. KK. */ 1.242 + int i; 1.243 +- for(i=0;i<total_offsets-1;i++) 1.244 ++ char *version = build_index(clo->offsets, ntohl(clo->head.num_blocks)); 1.245 ++ for(i=0;i<total_offsets;i++) 1.246 + { 1.247 +- loff_t d=be64_to_cpu(clo->offsets[i+1]) - be64_to_cpu(clo->offsets[i]); 1.248 +- clo->largest_block=MAX(clo->largest_block,d); 1.249 ++ clo->largest_block=MAX(clo->largest_block,clo->offsets[i].size); 1.250 + } 1.251 +- printk(KERN_INFO "%s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n", 1.252 +- cloop_name, filename, ntohl(clo->head.num_blocks), 1.253 ++ printk(KERN_INFO "%s: %s: %s, %u blocks, %u bytes/block, largest block is %lu bytes.\n", 1.254 ++ cloop_name, filename, version, ntohl(clo->head.num_blocks), 1.255 + ntohl(clo->head.block_size), clo->largest_block); 1.256 + } 1.257 + /* Combo kmalloc used too large chunks (>130000). */ 1.258 +@@ -565,16 +615,6 @@ 1.259 + error=-ENOMEM; goto error_release_free_all; 1.260 + } 1.261 + zlib_inflateInit(&clo->zstream); 1.262 +- if(!isblkdev && 1.263 +- be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]) != inode->i_size) 1.264 +- { 1.265 +- printk(KERN_ERR "%s: final offset wrong (%Lu not %Lu)\n", 1.266 +- cloop_name, 1.267 +- be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]), 1.268 +- inode->i_size); 1.269 +- cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); clo->zstream.workspace=NULL; 1.270 +- goto error_release_free_all; 1.271 +- } 1.272 + { 1.273 + int i; 1.274 + for(i=0; i<BUFFERED_BLOCKS; i++) clo->buffered_blocknum[i] = -1; 1.275 +@@ -653,7 +693,7 @@ 1.276 + } 1.277 + } 1.278 + error_release_free: 1.279 +- cloop_free(clo->offsets, sizeof(loff_t) * total_offsets); 1.280 ++ cloop_free(clo->offsets, sizeof(struct block_info) * total_offsets); 1.281 + clo->offsets=NULL; 1.282 + error_release: 1.283 + if(bbuf) cloop_free(bbuf, clo->underlying_blksize);