# HG changeset patch # User Pascal Bellard # Date 1412954067 -7200 # Node ID 2a96a678fd4c6fdd9af0bd4917a9d3abc333f338 # Parent c7c5267e7001a338bd2903137e64a82719d1a78e Add linux64-cloop diff -r c7c5267e7001 -r 2a96a678fd4c linux-cloop/receipt --- a/linux-cloop/receipt Fri Oct 10 16:34:25 2014 +0200 +++ b/linux-cloop/receipt Fri Oct 10 17:14:27 2014 +0200 @@ -26,7 +26,7 @@ # Rules to gen a SliTaz package suitable for Tazpkg. genpkg_rules() { - EXTRAVERSION=_${kvers%.*} + EXTRAVERSION=_$kvers mkdir -p $fs/lib/modules/$kvers-slitaz/kernel/misc $fs/dev $fs/usr/bin cp $src/cloop_suspend $fs/usr/bin cp $src/cloop.ko.xz $fs/lib/modules/$kvers-slitaz/kernel/misc diff -r c7c5267e7001 -r 2a96a678fd4c linux64-cloop/receipt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux64-cloop/receipt Fri Oct 10 17:14:27 2014 +0200 @@ -0,0 +1,50 @@ +# SliTaz package receipt. + +PACKAGE="linux64-cloop" +SOURCE="cloop" +VERSION="2.639-2" +CATEGORY="base-system" +MAINTAINER="pascal.bellard@slitaz.org" +LICENSE="GPL2" +SHORT_DESC="The read-only compressed loop device kernel module." +WEB_SITE="http://knoppix.net/wiki/Cloop" +TARBALL="${SOURCE}_${VERSION}.tar.gz" +WGET_URL="http://debian-knoppix.alioth.debian.org/packages/$SOURCE/$TARBALL" +PROVIDE="linux-cloop:linux64" + +DEPENDS="linux64" +BUILD_DEPENDS="linux-module-headers xz uclibc-cross-compiler-x86_64" +SUGGESTED="cloop-utils" + +AUFS_NOT_RAMFS="uclibc-cross-compiler-x86_64 is not compatible with aufs+tmpfs 8(" + +# Rules to configure and make the package. + +compile_rules() +{ + patch -p0 < $stuff/cloop.u + make ARCH=x86_64 CROSS_COMPILE=uclibc-x86_64- KERNEL_DIR="/usr/src/linux" cloop.ko && xz cloop.ko +} + +# Rules to gen a SliTaz package suitable for Tazpkg. +genpkg_rules() +{ + EXTRAVERSION=_$kvers + mkdir -p $fs/lib/modules/$kvers-slitaz64/kernel/misc $fs/dev $fs/usr/bin + cp $src/cloop_suspend $fs/usr/bin + cp $src/cloop.ko.xz $fs/lib/modules/$kvers-slitaz64/kernel/misc + mknod $fs/dev/cloop b 240 0 + for i in $(seq 1 7); do + mknod $fs/dev/cloop$i b 240 $i + done +} + +post_install() +{ + chroot "$1/" depmod -a ${EXTRAVERSION#_}-slitaz64 +} + +post_remove() +{ + depmod -a +} diff -r c7c5267e7001 -r 2a96a678fd4c linux64-cloop/stuff/cloop.u --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux64-cloop/stuff/cloop.u Fri Oct 10 17:14:27 2014 +0200 @@ -0,0 +1,280 @@ +--- cloop.h ++++ cloop.h +@@ -20,6 +20,75 @@ + /* data_index (num_blocks 64bit pointers, network order)... */ + /* compressed data (gzip block compressed format)... */ + ++struct cloop_tail ++{ ++ u_int32_t table_size; ++ u_int32_t index_size; ++ u_int32_t num_blocks; ++}; ++ ++struct block_info ++{ ++ loff_t offset; /* 64-bit offsets of compressed block */ ++ u_int32_t size; /* 32-bit compressed block size */ ++ u_int32_t optidx; /* 32-bit index number */ ++}; ++ ++static inline char *build_index(struct block_info *offsets, unsigned long n) ++{ ++ u_int32_t *ofs32 = (u_int32_t *) offsets; ++ loff_t *ofs64 = (loff_t *) offsets; ++ ++ if (ofs32[0] == 0) { ++ if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */ ++ while (n--) { ++ offsets[n].offset = __be64_to_cpu(offsets[n].offset); ++ offsets[n].size = ntohl(offsets[n].size); ++ } ++ return (char *) "128BE accelerated knoppix 1.0"; ++ } ++ else { /* V2.0 */ ++ loff_t last = __be64_to_cpu(ofs64[n]); ++ while (n--) { ++ offsets[n].size = last - ++ (offsets[n].offset = __be64_to_cpu(ofs64[n])); ++ last = offsets[n].offset; ++ } ++ return (char *) "64BE v2.0"; ++ } ++ } ++ else if (ofs32[1] == 0) { /* V1.0 */ ++ loff_t last = __le64_to_cpu(ofs64[n]); ++ while (n--) { ++ offsets[n].size = last - ++ (offsets[n].offset = __le64_to_cpu(ofs64[n])); ++ last = offsets[n].offset; ++ } ++ return (char *) "64LE v1.0"; ++ } ++ else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */ ++ loff_t last = ntohl(ofs32[n]); ++ while (n--) { ++ offsets[n].size = last - ++ (offsets[n].offset = ntohl(ofs32[n])); ++ last = offsets[n].offset; ++ } ++ return (char *) "32BE v0.68"; ++ } ++ else { /* V3.0 */ ++ unsigned long i; ++ loff_t j; ++ ++ for (i = n; i-- != 0; ) ++ offsets[i].size = ntohl(ofs32[i]); ++ for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { ++ offsets[i].offset = j; ++ j += offsets[i].size; ++ } ++ return (char *) "32BE v3.0"; ++ } ++} ++ + /* Cloop suspend IOCTL */ + #define CLOOP_SUSPEND 0x4C07 + +--- cloop.c ++++ cloop.c +@@ -5,11 +5,18 @@ + * A cloop file looks like this: + * [32-bit uncompressed block size: network order] + * [32-bit number of blocks (n_blocks): network order] +- * [64-bit file offsets of start of blocks: network order] ++ * [for version < 3] ++ * [32-bit, 64-bit or 128-bit file offsets of start of blocks] + * ... + * (n_blocks + 1). + * n_blocks consisting of: + * [compressed block] ++ * ... ++ * [for version >= 3] ++ * [compressed list of 32-bit block sizes] ++ * [32-bit compressed index size: network order] ++ * [32-bit index size = 4: network order] ++ * [32-bit number of blocks (n_blocks): network order] + * + * Every version greatly inspired by code seen in loop.c + * by Theodore Ts'o, 3/29/93. +@@ -115,7 +122,7 @@ + struct cloop_head head; + + /* An array of offsets of compressed blocks within the file */ +- loff_t *offsets; ++ struct block_info *offsets; + + /* We buffer some uncompressed blocks for performance */ + int buffered_blocknum[BUFFERED_BLOCKS]; +@@ -256,11 +263,11 @@ + return i; + } + +- buf_length = be64_to_cpu(clo->offsets[blocknum+1]) - be64_to_cpu(clo->offsets[blocknum]); ++ buf_length = clo->offsets[blocknum].size; + + /* Load one compressed block from the file. */ + cloop_read_from_file(clo, clo->backing_file, (char *)clo->compressed_buffer, +- be64_to_cpu(clo->offsets[blocknum]), buf_length); ++ clo->offsets[blocknum].offset, buf_length); + + buflen = ntohl(clo->head.block_size); + +@@ -275,9 +282,9 @@ + if (ret != 0) + { + printk(KERN_ERR "%s: zlib decompression error %i uncompressing block %u %u/%lu/%u/%u " +- "%Lu-%Lu\n", cloop_name, ret, blocknum, ++ "%Lu:%u\n", cloop_name, ret, blocknum, + ntohl(clo->head.block_size), buflen, buf_length, buf_done, +- be64_to_cpu(clo->offsets[blocknum]), be64_to_cpu(clo->offsets[blocknum+1])); ++ clo->offsets[blocknum].offset, clo->offsets[blocknum].size); + clo->buffered_blocknum[clo->current_bufnum] = -1; + return -1; + } +@@ -489,30 +496,73 @@ + cloop_name, ntohl(clo->head.block_size)); + error=-EBADF; goto error_release; + } +- if (clo->head.preamble[0x0B]!='V'||clo->head.preamble[0x0C]<'1') +- { +- printk(KERN_ERR "%s: Cannot read old 32-bit (version 0.68) images, " +- "please use an older version of %s for this file.\n", +- cloop_name, cloop_name); +- error=-EBADF; goto error_release; +- } +- if (clo->head.preamble[0x0C]<'2') +- { +- printk(KERN_ERR "%s: Cannot read old architecture-dependent " +- "(format <= 1.0) images, please use an older " +- "version of %s for this file.\n", +- cloop_name, cloop_name); +- error=-EBADF; goto error_release; +- } +- total_offsets=ntohl(clo->head.num_blocks)+1; +- if (!isblkdev && (sizeof(struct cloop_head)+sizeof(loff_t)* ++ total_offsets=ntohl(clo->head.num_blocks); ++ if (!isblkdev && (sizeof(struct cloop_head)+sizeof(struct block_info)* + total_offsets > inode->i_size)) + { + printk(KERN_ERR "%s: file too small for %u blocks\n", + cloop_name, ntohl(clo->head.num_blocks)); + error=-EBADF; goto error_release; + } +- clo->offsets = cloop_malloc(sizeof(loff_t) * total_offsets); ++ if (total_offsets + 1 == 0) /* Version >= 3.0 */ ++ { ++ struct cloop_tail tail; ++ if(isblkdev) ++ { ++ /* No end of file: can't find index */ ++ printk(KERN_ERR "%s: no V3 support for block device\n", ++ cloop_name); ++ error=-EBADF; goto error_release; ++ } ++ bytes_read = cloop_read_from_file(clo, file, (void *) &tail, ++ inode->i_size - sizeof(struct cloop_tail), ++ sizeof(struct cloop_tail)); ++ if(bytes_read == sizeof(struct cloop_tail)) ++ { ++ unsigned long len, zlen; ++ void *zbuf; ++ clo->head.num_blocks = tail.num_blocks; ++ total_offsets = ntohl(clo->head.num_blocks); ++ clo->offsets = cloop_malloc(sizeof(struct block_info) * total_offsets); ++ if (!clo->offsets) ++ { ++ printk(KERN_ERR "%s: can't alloc index\n", ++ cloop_name); ++ error=-EBADF; goto error_release; ++ } ++ zbuf = &clo->offsets[total_offsets/2]; ++ zlen = ntohl(tail.table_size); ++ len = ntohl(tail.index_size) * total_offsets; ++ bytes_read = cloop_read_from_file(clo, file, zbuf, ++ inode->i_size - zlen - sizeof(struct cloop_tail), ++ zlen); ++ if (bytes_read != zlen) ++ { ++ printk(KERN_ERR "%s: can't read index\n", ++ cloop_name); ++ error=-EBADF; goto error_release; ++ } ++ clo->zstream.workspace = cloop_malloc(zlib_inflate_workspacesize()); ++ if(!clo->zstream.workspace) ++ { ++ printk(KERN_ERR "%s: can't alloc index workspace\n", ++ cloop_name); ++ error=-EBADF; goto error_release; ++ } ++ zlib_inflateInit(&clo->zstream); ++ uncompress(clo, (void *) clo->offsets, &len, zbuf, zlen); ++ cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); ++ clo->zstream.workspace = NULL; ++ break; ++ } ++ else ++ { ++ printk(KERN_ERR "%s: can't find index\n", ++ cloop_name); ++ error=-EBADF; goto error_release; ++ } ++ } ++ clo->offsets = cloop_malloc(sizeof(struct block_info) * total_offsets); + if (!clo->offsets) + { + printk(KERN_ERR "%s: out of kernel mem for offsets\n", cloop_name); +@@ -521,19 +571,19 @@ + } + num_readable = MIN(total_offsets - offsets_read, + (clo->underlying_blksize - offset) +- / sizeof(loff_t)); +- memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(loff_t)); ++ / sizeof(struct block_info)); ++ memcpy(&clo->offsets[offsets_read], bbuf+offset, num_readable * sizeof(struct block_info)); + offsets_read += num_readable; + } + { /* Search for largest block rather than estimate. KK. */ + int i; +- for(i=0;ioffsets, ntohl(clo->head.num_blocks)); ++ for(i=0;ioffsets[i+1]) - be64_to_cpu(clo->offsets[i]); +- clo->largest_block=MAX(clo->largest_block,d); ++ clo->largest_block=MAX(clo->largest_block,clo->offsets[i].size); + } +- printk(KERN_INFO "%s: %s: %u blocks, %u bytes/block, largest block is %lu bytes.\n", +- cloop_name, filename, ntohl(clo->head.num_blocks), ++ printk(KERN_INFO "%s: %s: %s, %u blocks, %u bytes/block, largest block is %lu bytes.\n", ++ cloop_name, filename, version, ntohl(clo->head.num_blocks), + ntohl(clo->head.block_size), clo->largest_block); + } + /* Combo kmalloc used too large chunks (>130000). */ +@@ -565,16 +615,6 @@ + error=-ENOMEM; goto error_release_free_all; + } + zlib_inflateInit(&clo->zstream); +- if(!isblkdev && +- be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]) != inode->i_size) +- { +- printk(KERN_ERR "%s: final offset wrong (%Lu not %Lu)\n", +- cloop_name, +- be64_to_cpu(clo->offsets[ntohl(clo->head.num_blocks)]), +- inode->i_size); +- cloop_free(clo->zstream.workspace, zlib_inflate_workspacesize()); clo->zstream.workspace=NULL; +- goto error_release_free_all; +- } + { + int i; + for(i=0; ibuffered_blocknum[i] = -1; +@@ -653,7 +693,7 @@ + } + } + error_release_free: +- cloop_free(clo->offsets, sizeof(loff_t) * total_offsets); ++ cloop_free(clo->offsets, sizeof(struct block_info) * total_offsets); + clo->offsets=NULL; + error_release: + if(bbuf) cloop_free(bbuf, clo->underlying_blksize);