wok-6.x annotate linux64-cloop/stuff/cloop.u @ rev 18899
Add more art from Leonardo Laporte.
SLiM themes Clean, Esperanza, Japan Art, Leaves, Montanhoso.
Openbox 3 themes Blinder, Chrommo.
Combo-theme Japanes (Openbox and GTK2).
SLiM themes Clean, Esperanza, Japan Art, Leaves, Montanhoso.
Openbox 3 themes Blinder, Chrommo.
Combo-theme Japanes (Openbox and GTK2).
author | Aleksej Bobylev <al.bobylev@gmail.com> |
---|---|
date | Thu Feb 18 16:54:27 2016 +0200 (2016-02-18) |
parents | 8fe10eb4f215 |
children | 36e9a3dcd5de |
rev | line source |
---|---|
pascal@17214 | 1 --- cloop.h |
pascal@17214 | 2 +++ cloop.h |
pascal@18828 | 3 @@ -20,6 +20,80 @@ |
pascal@17214 | 4 /* data_index (num_blocks 64bit pointers, network order)... */ |
pascal@17214 | 5 /* compressed data (gzip block compressed format)... */ |
pascal@17214 | 6 |
pascal@17214 | 7 +struct cloop_tail |
pascal@17214 | 8 +{ |
pascal@17214 | 9 + u_int32_t table_size; |
pascal@17214 | 10 + u_int32_t index_size; |
pascal@17214 | 11 + u_int32_t num_blocks; |
pascal@17214 | 12 +}; |
pascal@17214 | 13 + |
pascal@17214 | 14 +struct block_info |
pascal@17214 | 15 +{ |
pascal@17214 | 16 + loff_t offset; /* 64-bit offsets of compressed block */ |
pascal@17214 | 17 + u_int32_t size; /* 32-bit compressed block size */ |
pascal@17214 | 18 + u_int32_t optidx; /* 32-bit index number */ |
pascal@17214 | 19 +}; |
pascal@17214 | 20 + |
pascal@17214 | 21 +static inline char *build_index(struct block_info *offsets, unsigned long n) |
pascal@17214 | 22 +{ |
pascal@17214 | 23 + u_int32_t *ofs32 = (u_int32_t *) offsets; |
pascal@17214 | 24 + loff_t *ofs64 = (loff_t *) offsets; |
pascal@17214 | 25 + |
pascal@17214 | 26 + if (ofs32[0] == 0) { |
pascal@17214 | 27 + if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */ |
pascal@17214 | 28 + while (n--) { |
pascal@17214 | 29 + offsets[n].offset = __be64_to_cpu(offsets[n].offset); |
pascal@17214 | 30 + offsets[n].size = ntohl(offsets[n].size); |
pascal@17214 | 31 + } |
pascal@17214 | 32 + return (char *) "128BE accelerated knoppix 1.0"; |
pascal@17214 | 33 + } |
pascal@17214 | 34 + else { /* V2.0 */ |
pascal@17361 | 35 + loff_t last = __be64_to_cpu(ofs64[n - 1]); |
pascal@17214 | 36 + while (n--) { |
pascal@17214 | 37 + offsets[n].size = last - |
pascal@17214 | 38 + (offsets[n].offset = __be64_to_cpu(ofs64[n])); |
pascal@17214 | 39 + last = offsets[n].offset; |
pascal@17214 | 40 + } |
pascal@17214 | 41 + return (char *) "64BE v2.0"; |
pascal@17214 | 42 + } |
pascal@17214 | 43 + } |
pascal@17214 | 44 + else if (ofs32[1] == 0) { /* V1.0 */ |
pascal@17361 | 45 + loff_t last = __le64_to_cpu(ofs64[n - 1]); |
pascal@17214 | 46 + while (n--) { |
pascal@17214 | 47 + offsets[n].size = last - |
pascal@17214 | 48 + (offsets[n].offset = __le64_to_cpu(ofs64[n])); |
pascal@17214 | 49 + last = offsets[n].offset; |
pascal@17214 | 50 + } |
pascal@17214 | 51 + return (char *) "64LE v1.0"; |
pascal@17214 | 52 + } |
pascal@17214 | 53 + else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ |
pascal@17361 | 54 + loff_t last = ntohl(ofs32[n - 1]); |
pascal@17214 | 55 + while (n--) { |
pascal@17214 | 56 + offsets[n].size = last - |
pascal@17214 | 57 + (offsets[n].offset = ntohl(ofs32[n])); |
pascal@17214 | 58 + last = offsets[n].offset; |
pascal@17214 | 59 + } |
pascal@17214 | 60 + return (char *) "32BE v0.68"; |
pascal@17214 | 61 + } |
pascal@17214 | 62 + else { /* V3.0 */ |
pascal@17214 | 63 + unsigned long i; |
pascal@17214 | 64 + loff_t j; |
pascal@17214 | 65 + |
pascal@17214 | 66 + for (i = n; i-- != 0; ) |
pascal@17214 | 67 + offsets[i].size = ntohl(ofs32[i]); |
pascal@17214 | 68 + for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { |
pascal@17214 | 69 + offsets[i].offset = j; |
pascal@18828 | 70 + if (offsets[i].size & 0x80000000) { |
pascal@18829 | 71 + unsigned long k = offsets[i].size & 0x7FFFFFFF; |
pascal@18828 | 72 + offsets[i].offset = offsets[k].offset; |
pascal@18828 | 73 + offsets[i].size = offsets[k].size; |
pascal@18828 | 74 + } |
pascal@18828 | 75 + else j += offsets[i].size; |
pascal@17214 | 76 + } |
pascal@17214 | 77 + return (char *) "32BE v3.0"; |
pascal@17214 | 78 + } |
pascal@17214 | 79 +} |
pascal@17214 | 80 + |
pascal@17214 | 81 /* Cloop suspend IOCTL */ |
pascal@17214 | 82 #define CLOOP_SUSPEND 0x4C07 |
pascal@17214 | 83 |
pascal@17214 | 84 --- cloop.c |
pascal@17214 | 85 +++ cloop.c |
pascal@17214 | 86 @@ -5,11 +5,18 @@ |
pascal@17214 | 87 * A cloop file looks like this: |
pascal@17214 | 88 * [32-bit uncompressed block size: network order] |
pascal@17214 | 89 * [32-bit number of blocks (n_blocks): network order] |
pascal@17214 | 90 - * [64-bit file offsets of start of blocks: network order] |
pascal@17214 | 91 + * [for version < 3] |
pascal@17214 | 92 + * [32-bit, 64-bit or 128-bit file offsets of start of blocks] |
pascal@17214 | 93 * ... |
pascal@17214 | 94 * (n_blocks + 1). |
pascal@17214 | 95 * n_blocks consisting of: |
pascal@17214 | 96 * [compressed block] |
pascal@17214 | 97 + * ... |
pascal@17214 | 98 + * [for version >= 3] |
pascal@17214 | 99 + * [compressed list of 32-bit block sizes] |
pascal@17214 | 100 + * [32-bit compressed index size: network order] |
pascal@17214 | 101 + * [32-bit index size = 4: network order] |
pascal@17214 | 102 + * [32-bit number of blocks (n_blocks): network order] |
pascal@17214 | 103 * |
pascal@17214 | 104 * Every version greatly inspired by code seen in loop.c |
pascal@17214 | 105 * by Theodore Ts'o, 3/29/93. |
pascal@17214 | 106 @@ -115,7 +122,7 @@ |
pascal@17214 | 107 struct cloop_head head; |
pascal@17214 | 108 |
pascal@17214 | 109 /* An array of offsets of compressed blocks within the file */ |
pascal@17214 | 110 - loff_t *offsets; |
pascal@17214 | 111 + struct block_info *offsets; |
pascal@17214 | 112 |
pascal@17214 | 113 /* We buffer some uncompressed blocks for performance */ |
pascal@17214 | 114 int buffered_blocknum[BUFFERED_BLOCKS]; |
pascal@17214 | 115 @@ -256,11 +263,11 @@ |
pascal@17214 | 116 return i; |
pascal@17214 | 117 } |
pascal@17214 | 118 |
pascal@17214 | 119 - buf_length = be64_to_cpu(clo->offsets[blocknum+1]) - be64_to_cpu(clo->offsets[blocknum]); |
pascal@17214 | 120 + buf_length = clo->offsets[blocknum].size; |
pascal@17214 | 121 |
pascal@17214 | 122 /* Load one compressed block from the file. */ |
pascal@17214 | 123 cloop_read_from_file(clo, clo->backing_file, (char *)clo->compressed_buffer, |
pascal@17214 | 124 - be64_to_cpu(clo->offsets[blocknum]), buf_length); |
pascal@17214 | 125 + clo->offsets[blocknum].offset, buf_length); |
pascal@17214 | 126 |
pascal@17214 | 127 buflen = ntohl(clo->head.block_size); |
pascal@17214 | 128 |
pascal@17214 | 129 @@ -275,9 +282,9 @@ |
pascal@17214 | 130 if (ret != 0) |
pascal@17214 | 131 { |
pascal@17214 | 132 printk(KERN_ERR "%s: zlib decompression error %i uncompressing block %u %u/%lu/%u/%u " |
pascal@17214 | 133 - "%Lu-%Lu\n", cloop_name, ret, blocknum, |
pascal@17214 | 134 + "%Lu:%u\n", cloop_name, ret, blocknum, |
pascal@17214 | 135 ntohl(clo->head.block_size), buflen, buf_length, buf_done, |
pascal@17214 | 136 - be64_to_cpu(clo->offsets[blocknum]), be64_to_cpu(clo->offsets[blocknum+1])); |
pascal@17214 | 137 + clo->offsets[blocknum].offset, clo->offsets[blocknum].size); |
pascal@17214 | 138 clo->buffered_blocknum[clo->current_bufnum] = -1; |
pascal@17214 | 139 return -1; |
pascal@17214 | 140 } |
pascal@17214 | 141 @@ -489,30 +496,73 @@ |
pascal@17214 | 142 cloop_name, ntohl(clo->head.block_size)); |
pascal@17214 | 143 error=-EBADF; goto error_release; |
pascal@17214 | 144 } |
pascal@17214 | 145 - if (clo->head.preamble[0x0B]!='V'||clo->head.preamble[0x0C]<'1') |
pascal@17214 | 146 - { |
pascal@17214 | 147 - printk(KERN_ERR "%s: Cannot read old 32-bit (version 0.68) images, " |
pascal@17214 | 148 - "please use an older version of %s for this file.\n", |
pascal@17214 | 149 - cloop_name, cloop_name); |
pascal@17214 | 150 - error=-EBADF; goto error_release; |
pascal@17214 | 151 - } |
pascal@17214 | 152 - if (clo->head.preamble[0x0C]<'2') |
pascal@17214 | 153 - { |
pascal@17214 | 154 - printk(KERN_ERR "%s: Cannot read old architecture-dependent " |
pascal@17214 | 155 - "(format <= 1.0) images, please use an older " |
pascal@17214 | 156 - "version of %s for this file.\n", |
pascal@17214 | 157 - cloop_name, cloop_name); |
pascal@17214 | 158 - error=-EBADF; goto error_release; |
pascal@17214 | 159 - } |
pascal@17214 | 160 - total_offsets=ntohl(clo->head.num_blocks)+1; |
pascal@17214 | 161 - if (!isblkdev && (sizeof(struct cloop_head)+sizeof(loff_t)* |
pascal@17214 | 162 + total_offsets=ntohl(clo->head.num_blocks); |
pascal@17214 | 163 + if (!isblkdev && (sizeof(struct cloop_head)+sizeof(struct block_info)* |
pascal@17214 | 164 total_offsets > inode->i_size)) |
pascal@17214 | 165 { |
pascal@17214 | 166 printk(KERN_ERR "%s: file too small for %u blocks\n", |
pascal@17214 | 167 cloop_name, ntohl(clo->head.num_blocks)); |
pascal@17214 | 168 error=-EBADF; goto error_release; |
pascal@17214 | 169 } |
pascal@17214 | 170 - clo->offsets = cloop_malloc(sizeof(loff_t) * total_offsets); |
pascal@17214 | 171 + if (total_offsets + 1 == 0) /* Version >= 3.0 */ |
pascal@17214 | 172 + { |
pascal@17214 | 173 + struct cloop_tail tail; |
pascal@17214 | 174 + if(isblkdev) |
pascal@17214 | 175 + { |
pascal@17214 | 176 + /* No end of file: can't find index */ |
pascal@17214 | 177 + printk(KERN_ERR "%s: no V3 support for block device\n", |
pascal@17214 | 178 + cloop_name); |
pascal@17214 | 179 + error=-EBADF; goto error_release; |
pascal@17214 | 180 + } |
pascal@17214 | 181 + bytes_read = cloop_read_from_file(clo, file, (void *) &tail, |
pascal@17214 | 182 + inode->i_size - sizeof(struct cloop_tail), |
pascal@17214 | 183 + sizeof(struct cloop_tail)); |
pascal@17214 | 184 + if(bytes_read == sizeof(struct cloop_tail)) |
pascal@17214 | 185 + { |
pascal@17214 | 186 + unsigned long len, zlen; |
pascal@17214 | 187 + void *zbuf; |
pascal@17214 | 188 + clo->head.num_blocks = tail.num_blocks; |
pascal@17214 | 189 + total_offsets = ntohl(clo->head.num_blocks); |
pascal@17214 | 190 + clo->offsets = cloop_malloc(sizeof(struct block_info) * total_offsets); |
pascal@17214 | 191 + if (!clo->offsets) |
pascal@17214 | 192 + { |
pascal@17214 | 193 + printk(KERN_ERR "%s: can't alloc index\n", |
pascal@17214 | 194 + cloop_name); |
pascal@17214 | 195 + error=-EBADF; goto error_release; |
pascal@17214 | 196 + } |
pascal@17214 | 197 + zbuf = &clo->offsets[total_offsets/2]; |
pascal@17214 | 198 + zlen = ntohl(tail.table_size); |
pascal@17214 | 199 + len = ntohl(tail.index_size) * total_offsets; |
pascal@17214 | 200 + bytes_read = cloop_read_from_file(clo, file, zbuf, |
pascal@17214 | 201 + inode->i_size - zlen - sizeof(struct cloop_tail), |
pascal@17214 | 202 + zlen); |
pascal@17214 | 203 + if (bytes_read != zlen) |
pascal@17214 | 204 + { |
pascal@17214 | 205 + printk(KERN_ERR "%s: can't read index\n", |
pascal@17214 | 206 + cloop_name); |
pascal@17214 | 207 + error=-EBADF; goto error_release; |
pascal@17214 | 208 + } |
pascal@17214 | 209 + clo->zstream.workspace = cloop_malloc(zlib_inflate_workspacesize()); |
pascal@17214 | 210 + if(!clo->zstream.workspace) |
pascal@17214 | 211 + { |
pascal@17214 | 212 + printk(KERN_ERR "%s: can't alloc index workspace\n", |
pascal@17214 | 213 + cloop_name); |
pascal@17214 | 214 + error=-EBADF; goto error_release; |
pascal@17214 | 215 + } |
pascal@17214 | 216 + zlib_inflateInit(&clo->zstream); |
pascal@17214 | 217 + uncompress(clo, (void *) clo->offsets, &len, zbuf, zlen); |
pascal@17214 | 218 + cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); |
pascal@17214 | 219 + clo->zstream.workspace = NULL; |
pascal@17214 | 220 + break; |
pascal@17214 | 221 + } |
pascal@17214 | 222 + else |
pascal@17214 | 223 + { |
pascal@17214 | 224 + printk(KERN_ERR "%s: can't find index\n", |
pascal@17214 | 225 + cloop_name); |
pascal@17214 | 226 + error=-EBADF; goto error_release; |
pascal@17214 | 227 + } |
pascal@17214 | 228 + } |
pascal@17214 | 229 + clo->offsets = cloop_malloc(sizeof(struct block_info) * total_offsets); |
pascal@17214 | 230 if (!clo->offsets) |
pascal@17214 | 231 { |
pascal@17214 | 232 printk(KERN_ERR "%s: out of kernel mem for offsets\n", cloop_name); |
pascal@17365 | 233 @@ -521,19 +571,22 @@ |
pascal@17214 | 234 } |
pascal@17214 | 235 num_readable = MIN(total_offsets - offsets_read, |
pascal@17214 | 236 (clo->underlying_blksize - offset) |
pascal@17214 | 237 - / sizeof(loff_t)); |
pascal@17214 | 238 - memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(loff_t)); |
pascal@17214 | 239 + / sizeof(struct block_info)); |
pascal@17214 | 240 + memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(struct block_info)); |
pascal@17214 | 241 offsets_read += num_readable; |
pascal@17214 | 242 } |
pascal@17214 | 243 { /* Search for largest block rather than estimate. KK. */ |
pascal@17214 | 244 int i; |
pascal@17214 | 245 - for(i=0;i<total_offsets-1;i++) |
pascal@17214 | 246 + char *version = build_index(clo->offsets, ntohl(clo->head.num_blocks)); |
pascal@17361 | 247 + for(i=0,clo->largest_block=0;i<total_offsets;i++) |
pascal@17214 | 248 { |
pascal@17214 | 249 - loff_t d=be64_to_cpu(clo->offsets[i+1]) - be64_to_cpu(clo->offsets[i]); |
pascal@17214 | 250 - clo->largest_block=MAX(clo->largest_block,d); |
pascal@17214 | 251 + clo->largest_block=MAX(clo->largest_block,clo->offsets[i].size); |
pascal@17214 | 252 } |
pascal@17214 | 253 - printk(KERN_INFO "%s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n", |
pascal@17214 | 254 - cloop_name, filename, ntohl(clo->head.num_blocks), |
pascal@17365 | 255 + i = ntohl(clo->head.block_size); |
pascal@17365 | 256 + i += i/1000 + 12 + 4; /* max gzip block size */ |
pascal@17365 | 257 + if (clo->largest_block > i) clo->largest_block = i; /* broken index ? */ |
pascal@17214 | 258 + printk(KERN_INFO "%s: %s: %s, %u blocks, %u bytes/block, largest block is %lu bytes.\n", |
pascal@17214 | 259 + cloop_name, filename, version, ntohl(clo->head.num_blocks), |
pascal@17214 | 260 ntohl(clo->head.block_size), clo->largest_block); |
pascal@17214 | 261 } |
pascal@17214 | 262 /* Combo kmalloc used too large chunks (>130000). */ |
pascal@17365 | 263 @@ -565,16 +618,6 @@ |
pascal@17214 | 264 error=-ENOMEM; goto error_release_free_all; |
pascal@17214 | 265 } |
pascal@17214 | 266 zlib_inflateInit(&clo->zstream); |
pascal@17214 | 267 - if(!isblkdev && |
pascal@17214 | 268 - be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]) != inode->i_size) |
pascal@17214 | 269 - { |
pascal@17214 | 270 - printk(KERN_ERR "%s: final offset wrong (%Lu not %Lu)\n", |
pascal@17214 | 271 - cloop_name, |
pascal@17214 | 272 - be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]), |
pascal@17214 | 273 - inode->i_size); |
pascal@17214 | 274 - cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); clo->zstream.workspace=NULL; |
pascal@17214 | 275 - goto error_release_free_all; |
pascal@17214 | 276 - } |
pascal@17214 | 277 { |
pascal@17214 | 278 int i; |
pascal@17214 | 279 for(i=0; i<BUFFERED_BLOCKS; i++) clo->buffered_blocknum[i] = -1; |
pascal@17365 | 280 @@ -653,7 +696,7 @@ |
pascal@17214 | 281 } |
pascal@17214 | 282 } |
pascal@17214 | 283 error_release_free: |
pascal@17214 | 284 - cloop_free(clo->offsets, sizeof(loff_t) * total_offsets); |
pascal@17214 | 285 + cloop_free(clo->offsets, sizeof(struct block_info) * total_offsets); |
pascal@17214 | 286 clo->offsets=NULL; |
pascal@17214 | 287 error_release: |
pascal@17214 | 288 if(bbuf) cloop_free(bbuf, clo->underlying_blksize); |