wok-current rev 17000
Add linux-cloop
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Mon Aug 11 16:24:13 2014 +0200 (2014-08-11) |
parents | fe86f04738d9 |
children | daa886d5366f |
files | linux-cloop/receipt linux-cloop/stuff/cloop.u |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/linux-cloop/receipt Mon Aug 11 16:24:13 2014 +0200 1.3 @@ -0,0 +1,46 @@ 1.4 +# SliTaz package receipt. 1.5 + 1.6 +PACKAGE="linux-cloop" 1.7 +SOURCE="cloop" 1.8 +VERSION="2.639-2" 1.9 +CATEGORY="base-system" 1.10 +MAINTAINER="pascal.bellard@slitaz.org" 1.11 +LICENSE="GPL2" 1.12 +SHORT_DESC="The read-only compressed loop device kernel module." 1.13 +WEB_SITE="http://knoppix.net/wiki/Cloop" 1.14 +TARBALL="${SOURCE}_${VERSION}.tar.gz" 1.15 +WGET_URL="http://debian-knoppix.alioth.debian.org/packages/$SOURCE/$TARBALL" 1.16 + 1.17 +DEPENDS="linux" 1.18 +BUILD_DEPENDS="linux-module-headers xz" 1.19 +SUGGESTED="cloop-utils" 1.20 + 1.21 +# Rules to configure and make the package. 1.22 + 1.23 +compile_rules() 1.24 +{ 1.25 + patch -p0 < cloop.u 1.26 + make KERNEL_DIR="/usr/src/linux" cloop.ko && xz cloop.ko 1.27 +} 1.28 + 1.29 +# Rules to gen a SliTaz package suitable for Tazpkg. 1.30 +genpkg_rules() 1.31 +{ 1.32 + EXTRAVERSION=_${kvers%.*} 1.33 + mkdir -p $fs/lib/modules/$kvers-slitaz/kernel/misc $fs/dev 1.34 + cp $src/cloop.ko.xz $fs/lib/modules/$kvers-slitaz/kernel/misc 1.35 + mknod $fs/dev/cloop b 240 0 1.36 + for i in $(seq 1 7); do 1.37 + mknod $fs/dev/cloop$i b 240 $i 1.38 + done 1.39 +} 1.40 + 1.41 +post_install() 1.42 +{ 1.43 + chroot "$1/" depmod -a ${EXTRAVERSION#_}-slitaz 1.44 +} 1.45 + 1.46 +post_remove() 1.47 +{ 1.48 + depmod -a 1.49 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/linux-cloop/stuff/cloop.u Mon Aug 11 16:24:13 2014 +0200 2.3 @@ -0,0 +1,279 @@ 2.4 +--- cloop.h 2.5 ++++ cloop.h 2.6 +@@ -20,6 +20,74 @@ 2.7 + /* data_index (num_blocks 64bit pointers, network order)... */ 2.8 + /* compressed data (gzip block compressed format)... */ 2.9 + 2.10 ++struct cloop_tail 2.11 ++{ 2.12 ++ u_int32_t table_size; 2.13 ++ u_int32_t index_size; 2.14 ++ u_int32_t num_blocks; 2.15 ++}; 2.16 ++ 2.17 ++struct block_info 2.18 ++{ 2.19 ++ loff_t offset; /* 64-bit offsets of compressed block */ 2.20 ++ u_int32_t size; /* 32-bit compressed block size */ 2.21 ++ u_int32_t optidx; /* 32-bit index number */ 2.22 ++}; 2.23 ++ 2.24 ++static inline char *build_index(struct block_info *offsets, unsigned long n) 2.25 ++{ 2.26 ++ u_int32_t *ofs32 = (u_int32_t *) offsets; 2.27 ++ loff_t *ofs64 = (loff_t *) offsets; 2.28 ++ 2.29 ++ if (ofs32[0] == 0) { 2.30 ++ if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */ 2.31 ++ while (n--) { 2.32 ++ offsets[n].offset = __be64_to_cpu(offsets[n].offset); 2.33 ++ offsets[n].size = ntohl(offsets[n].size); 2.34 ++ } 2.35 ++ return (char *) "128BE accelerated knoppix 1.0"; 2.36 ++ } 2.37 ++ else { /* V2.0 */ 2.38 ++ loff_t last = __be64_to_cpu(ofs64[n]); 2.39 ++ while (n--) { 2.40 ++ offsets[n].size = last - 2.41 ++ (offsets[n].offset = __be64_to_cpu(ofs64[n])); 2.42 ++ last = offsets[n].offset; 2.43 ++ } 2.44 ++ return (char *) "64BE v2.0"; 2.45 ++ } 2.46 ++ } 2.47 ++ else if (ofs32[1] == 0) { /* V1.0 */ 2.48 ++ loff_t last = __le64_to_cpu(ofs64[n]); 2.49 ++ while (n--) { 2.50 ++ offsets[n].size = last - 2.51 ++ (offsets[n].offset = __le64_to_cpu(ofs64[n])); 2.52 ++ last = offsets[n].offset; 2.53 ++ } 2.54 ++ return (char *) "64LE v1.0"; 2.55 ++ } 2.56 ++ else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ 2.57 ++ loff_t last = ntohl(ofs32[n]); 2.58 ++ while (n--) { 2.59 ++ offsets[n].size = last - 2.60 ++ (offsets[n].offset = ntohl(ofs32[n])); 2.61 ++ last = offsets[n].offset; 2.62 ++ } 2.63 ++ return (char *) "32BE v0.68"; 2.64 ++ } 2.65 ++ else { /* V3.0 */ 2.66 ++ int i, j; 2.67 ++ 2.68 ++ for (i = n; i-- > 0; ) 2.69 ++ offsets[i].size = ntohl(ofs32[i]); 2.70 ++ for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { 2.71 ++ offsets[i].offset = j; 2.72 ++ j += offsets[i].size; 2.73 ++ } 2.74 ++ return (char *) "32BE v3.0"; 2.75 ++ } 2.76 ++} 2.77 ++ 2.78 + /* Cloop suspend IOCTL */ 2.79 + #define CLOOP_SUSPEND 0x4C07 2.80 + 2.81 +--- cloop.c 2.82 ++++ cloop.c 2.83 +@@ -5,11 +5,18 @@ 2.84 + * A cloop file looks like this: 2.85 + * [32-bit uncompressed block size: network order] 2.86 + * [32-bit number of blocks (n_blocks): network order] 2.87 +- * [64-bit file offsets of start of blocks: network order] 2.88 ++ * [for version < 3] 2.89 ++ * [32-bit, 64-bit or 128-bit file offsets of start of blocks] 2.90 + * ... 2.91 + * (n_blocks + 1). 2.92 + * n_blocks consisting of: 2.93 + * [compressed block] 2.94 ++ * ... 2.95 ++ * [for version >= 3] 2.96 ++ * [compressed list of 32-bit block sizes] 2.97 ++ * [32-bit compressed index size: network order] 2.98 ++ * [32-bit index size = 4: network order] 2.99 ++ * [32-bit number of blocks (n_blocks): network order] 2.100 + * 2.101 + * Every version greatly inspired by code seen in loop.c 2.102 + * by Theodore Ts'o, 3/29/93. 2.103 +@@ -115,7 +122,7 @@ 2.104 + struct cloop_head head; 2.105 + 2.106 + /* An array of offsets of compressed blocks within the file */ 2.107 +- loff_t *offsets; 2.108 ++ struct block_info *offsets; 2.109 + 2.110 + /* We buffer some uncompressed blocks for performance */ 2.111 + int buffered_blocknum[BUFFERED_BLOCKS]; 2.112 +@@ -256,11 +263,11 @@ 2.113 + return i; 2.114 + } 2.115 + 2.116 +- buf_length = be64_to_cpu(clo->offsets[blocknum+1]) - be64_to_cpu(clo->offsets[blocknum]); 2.117 ++ buf_length = clo->offsets[blocknum].size; 2.118 + 2.119 + /* Load one compressed block from the file. */ 2.120 + cloop_read_from_file(clo, clo->backing_file, (char *)clo->compressed_buffer, 2.121 +- be64_to_cpu(clo->offsets[blocknum]), buf_length); 2.122 ++ clo->offsets[blocknum].offset, buf_length); 2.123 + 2.124 + buflen = ntohl(clo->head.block_size); 2.125 + 2.126 +@@ -275,9 +282,9 @@ 2.127 + if (ret != 0) 2.128 + { 2.129 + printk(KERN_ERR "%s: zlib decompression error %i uncompressing block %u %u/%lu/%u/%u " 2.130 +- "%Lu-%Lu\n", cloop_name, ret, blocknum, 2.131 ++ "%Lu:%u\n", cloop_name, ret, blocknum, 2.132 + ntohl(clo->head.block_size), buflen, buf_length, buf_done, 2.133 +- be64_to_cpu(clo->offsets[blocknum]), be64_to_cpu(clo->offsets[blocknum+1])); 2.134 ++ clo->offsets[blocknum].offset, clo->offsets[blocknum].size); 2.135 + clo->buffered_blocknum[clo->current_bufnum] = -1; 2.136 + return -1; 2.137 + } 2.138 +@@ -489,30 +496,73 @@ 2.139 + cloop_name, ntohl(clo->head.block_size)); 2.140 + error=-EBADF; goto error_release; 2.141 + } 2.142 +- if (clo->head.preamble[0x0B]!='V'||clo->head.preamble[0x0C]<'1') 2.143 +- { 2.144 +- printk(KERN_ERR "%s: Cannot read old 32-bit (version 0.68) images, " 2.145 +- "please use an older version of %s for this file.\n", 2.146 +- cloop_name, cloop_name); 2.147 +- error=-EBADF; goto error_release; 2.148 +- } 2.149 +- if (clo->head.preamble[0x0C]<'2') 2.150 +- { 2.151 +- printk(KERN_ERR "%s: Cannot read old architecture-dependent " 2.152 +- "(format <= 1.0) images, please use an older " 2.153 +- "version of %s for this file.\n", 2.154 +- cloop_name, cloop_name); 2.155 +- error=-EBADF; goto error_release; 2.156 +- } 2.157 +- total_offsets=ntohl(clo->head.num_blocks)+1; 2.158 +- if (!isblkdev && (sizeof(struct cloop_head)+sizeof(loff_t)* 2.159 ++ total_offsets=ntohl(clo->head.num_blocks); 2.160 ++ if (!isblkdev && (sizeof(struct cloop_head)+sizeof(struct block_info)* 2.161 + total_offsets > inode->i_size)) 2.162 + { 2.163 + printk(KERN_ERR "%s: file too small for %u blocks\n", 2.164 + cloop_name, ntohl(clo->head.num_blocks)); 2.165 + error=-EBADF; goto error_release; 2.166 + } 2.167 +- clo->offsets = cloop_malloc(sizeof(loff_t) * total_offsets); 2.168 ++ if (total_offsets + 1 == 0) /* Version >= 3.0 */ 2.169 ++ { 2.170 ++ struct cloop_tail tail; 2.171 ++ if(isblkdev) 2.172 ++ { 2.173 ++ /* No end of file: can't find index */ 2.174 ++ printk(KERN_ERR "%s: no V3 support for block device\n", 2.175 ++ cloop_name); 2.176 ++ error=-EBADF; goto error_release; 2.177 ++ } 2.178 ++ bytes_read = cloop_read_from_file(clo, file, (void *) &tail, 2.179 ++ inode->i_size - sizeof(struct cloop_tail), 2.180 ++ sizeof(struct cloop_tail)); 2.181 ++ if(bytes_read == sizeof(struct cloop_tail)) 2.182 ++ { 2.183 ++ unsigned long len, zlen; 2.184 ++ void *zbuf; 2.185 ++ clo->head.num_blocks = tail.num_blocks; 2.186 ++ total_offsets = ntohl(clo->head.num_blocks); 2.187 ++ clo->offsets = cloop_malloc(sizeof(struct block_info) * total_offsets); 2.188 ++ if (!clo->offsets) 2.189 ++ { 2.190 ++ printk(KERN_ERR "%s: can't alloc index\n", 2.191 ++ cloop_name); 2.192 ++ error=-EBADF; goto error_release; 2.193 ++ } 2.194 ++ zbuf = &clo->offsets[total_offsets/2]; 2.195 ++ zlen = ntohl(tail.table_size); 2.196 ++ len = ntohl(tail.index_size) * total_offsets; 2.197 ++ bytes_read = cloop_read_from_file(clo, file, zbuf, 2.198 ++ inode->i_size - zlen - sizeof(struct cloop_tail), 2.199 ++ zlen); 2.200 ++ if (bytes_read != zlen) 2.201 ++ { 2.202 ++ printk(KERN_ERR "%s: can't read index\n", 2.203 ++ cloop_name); 2.204 ++ error=-EBADF; goto error_release; 2.205 ++ } 2.206 ++ clo->zstream.workspace = cloop_malloc(zlib_inflate_workspacesize()); 2.207 ++ if(!clo->zstream.workspace) 2.208 ++ { 2.209 ++ printk(KERN_ERR "%s: can't alloc index workspace\n", 2.210 ++ cloop_name); 2.211 ++ error=-EBADF; goto error_release; 2.212 ++ } 2.213 ++ zlib_inflateInit(&clo->zstream); 2.214 ++ uncompress(clo, (void *) clo->offsets, &len, zbuf, zlen); 2.215 ++ cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); 2.216 ++ clo->zstream.workspace = NULL; 2.217 ++ break; 2.218 ++ } 2.219 ++ else 2.220 ++ { 2.221 ++ printk(KERN_ERR "%s: can't find index\n", 2.222 ++ cloop_name); 2.223 ++ error=-EBADF; goto error_release; 2.224 ++ } 2.225 ++ } 2.226 ++ clo->offsets = cloop_malloc(sizeof(struct block_info) * total_offsets); 2.227 + if (!clo->offsets) 2.228 + { 2.229 + printk(KERN_ERR "%s: out of kernel mem for offsets\n", cloop_name); 2.230 +@@ -521,19 +571,19 @@ 2.231 + } 2.232 + num_readable = MIN(total_offsets - offsets_read, 2.233 + (clo->underlying_blksize - offset) 2.234 +- / sizeof(loff_t)); 2.235 +- memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(loff_t)); 2.236 ++ / sizeof(struct block_info)); 2.237 ++ memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(struct block_info)); 2.238 + offsets_read += num_readable; 2.239 + } 2.240 + { /* Search for largest block rather than estimate. KK. */ 2.241 + int i; 2.242 +- for(i=0;i<total_offsets-1;i++) 2.243 ++ char *version = build_index(clo->offsets, ntohl(clo->head.num_blocks)); 2.244 ++ for(i=0;i<total_offsets;i++) 2.245 + { 2.246 +- loff_t d=be64_to_cpu(clo->offsets[i+1]) - be64_to_cpu(clo->offsets[i]); 2.247 +- clo->largest_block=MAX(clo->largest_block,d); 2.248 ++ clo->largest_block=MAX(clo->largest_block,clo->offsets[i].size); 2.249 + } 2.250 +- printk(KERN_INFO "%s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n", 2.251 +- cloop_name, filename, ntohl(clo->head.num_blocks), 2.252 ++ printk(KERN_INFO "%s: %s: %s, %u blocks, %u bytes/block, largest block is %lu bytes.\n", 2.253 ++ cloop_name, filename, version, ntohl(clo->head.num_blocks), 2.254 + ntohl(clo->head.block_size), clo->largest_block); 2.255 + } 2.256 + /* Combo kmalloc used too large chunks (>130000). */ 2.257 +@@ -565,16 +615,6 @@ 2.258 + error=-ENOMEM; goto error_release_free_all; 2.259 + } 2.260 + zlib_inflateInit(&clo->zstream); 2.261 +- if(!isblkdev && 2.262 +- be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]) != inode->i_size) 2.263 +- { 2.264 +- printk(KERN_ERR "%s: final offset wrong (%Lu not %Lu)\n", 2.265 +- cloop_name, 2.266 +- be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]), 2.267 +- inode->i_size); 2.268 +- cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); clo->zstream.workspace=NULL; 2.269 +- goto error_release_free_all; 2.270 +- } 2.271 + { 2.272 + int i; 2.273 + for(i=0; i<BUFFERED_BLOCKS; i++) clo->buffered_blocknum[i] = -1; 2.274 +@@ -653,7 +693,7 @@ 2.275 + } 2.276 + } 2.277 + error_release_free: 2.278 +- cloop_free(clo->offsets, sizeof(loff_t) * total_offsets); 2.279 ++ cloop_free(clo->offsets, sizeof(struct block_info) * total_offsets); 2.280 + clo->offsets=NULL; 2.281 + error_release: 2.282 + if(bbuf) cloop_free(bbuf, clo->underlying_blksize);