wok-4.x annotate fusecloop/stuff/fusecloop.u @ rev 10933

fusecloop: add v3.0 support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Fri Aug 26 20:39:15 2011 +0200 (2011-08-26)
parents ff0097ff50cd
children 65b7fa14f14f
rev   line source
pascal@10932 1 --- compressed_loop.h
pascal@10932 2 +++ compressed_loop.h
pascal@10933 3 @@ -41,6 +41,85 @@
pascal@10932 4 /* data_index (num_blocks 64bit pointers, network order)... */
pascal@10932 5 /* compressed data (gzip block compressed format)... */
pascal@10932 6
pascal@10933 7 +struct cloop_tail
pascal@10933 8 +{
pascal@10933 9 + u_int32_t index_size;
pascal@10933 10 + u_int32_t num_blocks;
pascal@10933 11 +};
pascal@10933 12 +
pascal@10932 13 +struct block_info
pascal@10932 14 +{
pascal@10932 15 + loff_t offset; /* 64-bit offsets of compressed block */
pascal@10932 16 + u_int32_t size; /* 32-bit compressed block size */
pascal@10932 17 + u_int32_t optidx; /* 32-bit index number */
pascal@10932 18 +};
pascal@10932 19 +
pascal@10933 20 +static inline char *build_index(struct block_info *offsets, unsigned long n,
pascal@10933 21 + unsigned long block_size)
pascal@10932 22 +{
pascal@10933 23 + u_int16_t *ofs16 = (u_int16_t *) offsets;
pascal@10932 24 + u_int32_t *ofs32 = (u_int32_t *) offsets;
pascal@10932 25 + loff_t *ofs64 = (loff_t *) offsets;
pascal@10933 26 +
pascal@10932 27 + if (ofs32[0] == 0) {
pascal@10932 28 + if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */
pascal@10933 29 + while (n--) {
pascal@10932 30 + offsets[n].offset = __be64_to_cpu(offsets[n].offset);
pascal@10932 31 + offsets[n].size = ntohl(offsets[n].size);
pascal@10933 32 + }
pascal@10932 33 + return "128BE accelerated knoppix 1.0";
pascal@10932 34 + }
pascal@10932 35 + else { /* V2.0 */
pascal@10933 36 + loff_t last = __be64_to_cpu(ofs64[n]);
pascal@10933 37 + while (n--) {
pascal@10932 38 + offsets[n].size = last -
pascal@10932 39 + (offsets[n].offset = __be64_to_cpu(ofs64[n]));
pascal@10932 40 + last = offsets[n].offset;
pascal@10933 41 + }
pascal@10932 42 + return "64BE v2.0";
pascal@10932 43 + }
pascal@10932 44 + }
pascal@10932 45 + else if (ofs32[1] == 0) { /* V1.0 */
pascal@10933 46 + loff_t last = __be64_to_cpu(ofs64[n]);
pascal@10933 47 + while (n--) {
pascal@10932 48 + offsets[n].size = last -
pascal@10932 49 + (offsets[n].offset = __le64_to_cpu(ofs64[n]));
pascal@10932 50 + last = offsets[n].offset;
pascal@10933 51 + }
pascal@10932 52 + return "64LE v1.0";
pascal@10932 53 + }
pascal@10933 54 + else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
pascal@10933 55 + loff_t last = ntohl(ofs32[n]);
pascal@10933 56 + while (n--) {
pascal@10932 57 + offsets[n].size = last -
pascal@10932 58 + (offsets[n].offset = ntohl(ofs32[n]));
pascal@10932 59 + last = offsets[n].offset;
pascal@10933 60 + }
pascal@10932 61 + return "32BE v0.68";
pascal@10932 62 + }
pascal@10933 63 + else { /* V3.0 */
pascal@10933 64 + char *type;
pascal@10933 65 + int i, j, smallest;
pascal@10933 66 +
pascal@10933 67 + smallest = (block_size < 32768) ? 0 : block_size>>10;
pascal@10933 68 + if (block_size > 0x10000) {
pascal@10933 69 + for (i = 0; i < n; i++)
pascal@10933 70 + offsets[n].size = smallest + ntohl(ofs32[n]);
pascal@10933 71 + type = "32BE size v3.0";
pascal@10933 72 + }
pascal@10933 73 + else {
pascal@10933 74 + for (i = 0; i < n; i++)
pascal@10933 75 + offsets[n].size = smallest + ntohs(ofs16[n]);
pascal@10933 76 + type = "16BE size v3.0";
pascal@10933 77 + }
pascal@10933 78 + for (i = j = 0; i < n; i++) {
pascal@10933 79 + offsets[i].offset = j;
pascal@10933 80 + j += offsets[i].size;
pascal@10933 81 + }
pascal@10933 82 + return type;
pascal@10933 83 + }
pascal@10932 84 +}
pascal@10932 85 +
pascal@10932 86 /* Cloop suspend IOCTL */
pascal@10932 87 #define CLOOP_SUSPEND 0x4C07
pascal@10932 88
pascal@10932 89
pascal@10932 90 --- cloopreader.h
pascal@10932 91 +++ cloopreader.h
pascal@10932 92 @@ -33,7 +33,7 @@
pascal@10932 93 int numblocks;
pascal@10932 94 ulong blocksize;
pascal@10932 95
pascal@10932 96 - loff_t* toc; /* Data index */
pascal@10932 97 + struct block_info *toc; /* Data index */
pascal@10932 98 size_t tocsize;
pascal@10932 99
pascal@10932 100 unsigned char* cblock; /* Compressed block */
pascal@10932 101
pascal@10932 102 --- cloopreader.c
pascal@10932 103 +++ cloopreader.c
pascal@10933 104 @@ -59,10 +59,20 @@
pascal@10932 105
pascal@10932 106 ALLOC(c->pblock,c->blocksize);
pascal@10932 107
pascal@10932 108 - c->tocsize=sizeof *c->toc * (c->numblocks+1); /* One extra address is position of EOF */
pascal@10932 109 + c->tocsize=sizeof(*c->toc) * c->numblocks;
pascal@10933 110 + if (c->numblocks == -1) {
pascal@10933 111 + struct cloop_tail tail;
pascal@10933 112 +
pascal@10933 113 + OP(lseek(c->fh, - sizeof(tail), SEEK_END));
pascal@10933 114 + OP(read_all(c->fh, &tail, sizeof(tail)));
pascal@10933 115 + c->numblocks = ntohl(tail.num_blocks);
pascal@10933 116 + c->tocsize = ntohl(tail.index_size) * c->numblocks;
pascal@10933 117 + OP(lseek(c->fh, - sizeof(tail) - c->tocsize, SEEK_END));
pascal@10933 118 + }
pascal@10932 119 ALLOC(c->toc,c->tocsize);
pascal@10932 120
pascal@10932 121 OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
pascal@10933 122 + build_index(c->toc, c->numblocks, c->blocksize);
pascal@10932 123 c->cblocksizecur=0;
pascal@10932 124 c->curblock=-1;
pascal@10932 125 return 0;
pascal@10933 126 @@ -79,10 +89,10 @@
pascal@10932 127 if(page>=c->numblocks){errno=EFAULT;return -1;}
pascal@10932 128 c->curblock=page;
pascal@10932 129
pascal@10932 130 - bprintf("Seeking to 0x%Lx\n",btc(c->toc[page]));
pascal@10932 131 - OP(lseek(c->fh,btc(c->toc[page]), SEEK_SET));
pascal@10932 132 + bprintf("Seeking to 0x%Lx\n",c->toc[page].offset);
pascal@10932 133 + OP(lseek(c->fh,c->toc[page].offset, SEEK_SET));
pascal@10932 134
pascal@10932 135 - c->cblocksize=btc(c->toc[page+1]) - btc(c->toc[page]);
pascal@10932 136 + c->cblocksize=c->toc[page].size;
pascal@10932 137 bprintf("Compressed size=%lu\n",c->cblocksize);
pascal@10932 138 if(c->cblocksize > c->cblocksizecur){
pascal@10932 139 if(c->cblocksizecur)free(c->cblock);
pascal@10933 140
pascal@10932 141 --- extract_compressed_fs.c
pascal@10932 142 +++ extract_compressed_fs.c
pascal@10932 143 @@ -7,6 +7,7 @@
pascal@10932 144 struct cloop_head head;
pascal@10932 145 unsigned int i;
pascal@10932 146 unsigned char *buffer, *clear_buffer;
pascal@10932 147 + struct block_info *offsets;
pascal@10932 148
pascal@10932 149 if (argc != 2) {
pascal@10932 150 fprintf(stderr, "Need filename\n");
pascal@10933 151 @@ -30,35 +31,48 @@
pascal@10932 152 fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n",
pascal@10932 153 ntohl(head.num_blocks), ntohl(head.block_size), head.preamble);
pascal@10932 154
pascal@10933 155 + i = ntohl(head.num_blocks);
pascal@10933 156 + if (i == -1) {
pascal@10933 157 + struct cloop_tail tail;
pascal@10933 158 + if (lseek(handle, - sizeof(tail), SEEK_END) < 0 ||
pascal@10933 159 + read(handle, &tail, sizeof(tail)) != sizeof(tail) ||
pascal@10933 160 + lseek(handle, - sizeof(tail) -
pascal@10933 161 + (ntohl(tail.num_blocks) * ntohl(tail.index_size)),
pascal@10933 162 + SEEK_END) < 0) {
pascal@10933 163 + perror("Reading tail\n");
pascal@10933 164 + exit(1);
pascal@10933 165 + }
pascal@10933 166 + head.num_blocks = tail.num_blocks;
pascal@10933 167 + i = ntohl(tail.num_blocks) * ntohl(tail.index_size);
pascal@10933 168 + }
pascal@10933 169 + else i *= sizeof(*offsets);
pascal@10932 170 + offsets = malloc(i);
pascal@10932 171 + if (!offsets || read(handle, offsets, i) != i) {
pascal@10932 172 + perror("Reading index\n");
pascal@10932 173 + exit(1);
pascal@10932 174 + }
pascal@10932 175 +
pascal@10933 176 + fprintf(stderr, "Index %s.\n", build_index(offsets,
pascal@10933 177 + ntohl(head.num_blocks), ntohl(head.block_size)));
pascal@10932 178 +
pascal@10932 179 for (i = 0; i < ntohl(head.num_blocks); i++) {
pascal@10932 180 - int currpos;
pascal@10932 181 unsigned long destlen = ntohl(head.block_size);
pascal@10932 182 - loff_t offset[2];
pascal@10932 183 - unsigned int size;
pascal@10932 184 + unsigned int size = offsets[i].size;
pascal@10932 185
pascal@10932 186 - read(handle, &offset, 2*sizeof(loff_t));
pascal@10932 187 - lseek(handle, -sizeof(loff_t), SEEK_CUR);
pascal@10932 188 -
pascal@10932 189 - currpos = lseek(handle, 0, SEEK_CUR);
pascal@10932 190 - if (lseek(handle, __be64_to_cpu(offset[0]), SEEK_SET) < 0) {
pascal@10932 191 + if (lseek(handle, offsets[i].offset, SEEK_SET) < 0) {
pascal@10932 192 fprintf(stderr, "lseek to %Lu: %s\n",
pascal@10932 193 - __be64_to_cpu(offset[0]), strerror(errno));
pascal@10932 194 + offsets[i].offset, strerror(errno));
pascal@10932 195 exit(1);
pascal@10932 196 }
pascal@10932 197
pascal@10932 198 - size=__be64_to_cpu(offset[1])-__be64_to_cpu(offset[0]);
pascal@10932 199 if (size > ntohl(head.block_size) + ntohl(head.block_size)/1000
pascal@10932 200 + 12 + 4) {
pascal@10932 201 fprintf(stderr,
pascal@10932 202 "Size %u for block %u (offset %Lu) too big\n",
pascal@10932 203 - size, i, __be64_to_cpu(offset[0]));
pascal@10932 204 + size, i, offsets[i].offset);
pascal@10932 205 exit(1);
pascal@10932 206 }
pascal@10932 207 read(handle, buffer, size);
pascal@10932 208 - if (lseek(handle, currpos, SEEK_SET) < 0) {
pascal@10932 209 - perror("seeking");
pascal@10932 210 - exit(1);
pascal@10932 211 - }
pascal@10932 212
pascal@10932 213 fprintf(stderr, "Block %u length %u => %lu\n",
pascal@10932 214 i, size, destlen);