SOURCES (LINUX_2_6): sqlzma2k-3.2-r2.patch (NEW) - lzma for squash...

mguevara mguevara at pld-linux.org
Tue May 8 15:48:29 CEST 2007


Author: mguevara                     Date: Tue May  8 13:48:29 2007 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- lzma for squashfs from http://www.squashfs-lzma.org/dl/sqlzma3.2-r2b.tar.bz2

---- Files affected:
SOURCES:
   sqlzma2k-3.2-r2.patch (NONE -> 1.1.2.1)  (NEW)

---- Diffs:

================================================================
Index: SOURCES/sqlzma2k-3.2-r2.patch
diff -u /dev/null SOURCES/sqlzma2k-3.2-r2.patch:1.1.2.1
--- /dev/null	Tue May  8 15:48:29 2007
+++ SOURCES/sqlzma2k-3.2-r2.patch	Tue May  8 15:48:24 2007
@@ -0,0 +1,536 @@
+Index: linux-2.6.21.1/fs/squashfs/inode.c
+===================================================================
+RCS file: linux-2.6.21.1/fs/squashfs/inode.c,v
+retrieving revision 1.1
+retrieving revision 1.4
+diff -u -p -r1.1 -r1.4
+--- linux-2.6.21.1/fs/squashfs/inode.c	16 Jan 2007 03:30:24 -0000	1.1
++++ linux-2.6.21.1/fs/squashfs/inode.c	5 Mar 2007 12:01:30 -0000	1.4
+@@ -33,6 +33,28 @@
+ #include <linux/smp_lock.h>
+ 
+ #include "squashfs.h"
++#include "sqlzma.h"
++#include "sqmagic.h"
++
++#undef KeepPreemptive
++#if defined(CONFIG_PREEMPT) && !defined(UnsquashNoPreempt)
++#define KeepPreemptive
++#endif
++
++struct sqlzma {
++#ifdef KeepPreemptive
++	struct mutex mtx;
++#endif
++	unsigned char read_data[SQUASHFS_FILE_MAX_SIZE];
++	struct sqlzma_un un;
++};
++static DEFINE_PER_CPU(struct sqlzma *, sqlzma);
++
++#define dpri(fmt, args...) /* printk("%s:%d: " fmt, __func__, __LINE__, ##args) */
++#define dpri_un(un)	dpri("un{%d, {%d %p}, {%d %p}, {%d %p}}\n", \
++			     (un)->un_lzma, (un)->un_a[0].sz, (un)->un_a[0].buf, \
++			     (un)->un_a[1].sz, (un)->un_a[1].buf, \
++			     (un)->un_a[2].sz, (un)->un_a[2].buf)
+ 
+ static void vfs_read_inode(struct inode *i);
+ static struct dentry *squashfs_get_parent(struct dentry *child);
+@@ -238,66 +260,74 @@ SQSH_EXTERN unsigned int squashfs_read_d
+ 	}
+ 
+ 	if (compressed) {
+-		int zlib_err = 0;
++		int zlib_err = Z_STREAM_END;
++		int rest, start;
++		enum {Src, Dst};
++		struct sized_buf sbuf[2];
++		struct sqlzma *percpu;
+ 
+ 		/*
+ 	 	* uncompress block
+ 	 	*/
+-
+-		mutex_lock(&msblk->read_data_mutex);
+-
+-		msblk->stream.next_out = buffer;
+-		msblk->stream.avail_out = srclength;
+-
+-		for (bytes = 0; k < b; k++) {
+-			avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
+-					msblk->devblksize - offset :
+-					c_byte - bytes;
++		for (k = 0; k < b; k++) {
+ 			wait_on_buffer(bh[k]);
+ 			if (!buffer_uptodate(bh[k]))
+-				goto release_mutex;
+-
+-			msblk->stream.next_in = bh[k]->b_data + offset;
+-			msblk->stream.avail_in = avail_bytes;
+-
+-			if (k == 0) {
+-				zlib_err = zlib_inflateInit(&msblk->stream);
+-				if (zlib_err != Z_OK) {
+-					ERROR("zlib_inflateInit returned unexpected result 0x%x, srclength %d\n",
+-						zlib_err, srclength);
+-					goto release_mutex;
+-				}
+-
+-				if (avail_bytes == 0) {
+-					offset = 0;
+-					brelse(bh[k]);
+-					continue;
+-				}
+-			}
+-
+-			zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
+-			if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
+-				ERROR("zlib_inflate returned unexpected result 0x%x, srclength %d, avail_in %d, avail_out %d\n",
+-					zlib_err, srclength, msblk->stream.avail_in, msblk->stream.avail_out);
+-				goto release_mutex;
+-			}
++				goto block_release;
++		}
+ 
+-			bytes += avail_bytes;
++		avail_bytes = 0;
++		for (k = 0; !avail_bytes && k < b; k++) {
++			avail_bytes = msblk->devblksize - offset;
++			if (c_byte < avail_bytes)
++				avail_bytes = c_byte;
++			if (avail_bytes)
++				break;
+ 			offset = 0;
+ 			brelse(bh[k]);
+ 		}
++		bytes = 0;
++		if (!avail_bytes)
++			goto block_release; // nothing to be process
+ 
+-		if (zlib_err != Z_STREAM_END)
+-			goto release_mutex;
+-
+-		zlib_err = zlib_inflateEnd(&msblk->stream);
+-		if (zlib_err != Z_OK) {
+-			ERROR("zlib_inflateEnd returned unexpected result 0x%x, srclength %d\n",
+-				zlib_err, srclength);
++		start = k;
++		/* it disables preemption */
++		percpu = get_cpu_var(sqlzma);
++#ifdef KeepPreemptive
++		put_cpu_var(sqlzma);
++		mutex_lock(&percpu->mtx);
++#endif
++
++		for (; k < b; k++) {
++			memcpy(percpu->read_data + bytes, bh[k]->b_data + offset,
++			       avail_bytes);
++			bytes += avail_bytes;
++			offset = 0;
++			brelse(bh[k]);
++			avail_bytes = msblk->devblksize - offset;
++			rest = c_byte - bytes;
++			if (rest < avail_bytes)
++				avail_bytes = rest;
++		}
++
++		sbuf[Src].buf = percpu->read_data;
++		sbuf[Src].sz = bytes;
++		sbuf[Dst].buf = buffer;
++		sbuf[Dst].sz = srclength;
++		dpri_un(&percpu->un);
++		dpri("src %d %p, dst %d %p\n", sbuf[Src].sz, sbuf[Src].buf,
++		     sbuf[Dst].sz, sbuf[Dst].buf);
++		zlib_err = sqlzma_un(&percpu->un, sbuf + Src, sbuf + Dst);
++		bytes = percpu->un.un_reslen;
++
++#ifdef KeepPreemptive
++		mutex_unlock(&percpu->mtx);
++#else
++		put_cpu_var(sqlzma);
++#endif
++		if (unlikely(zlib_err)) {
++			dpri("zlib_err %d\n", zlib_err);
+ 			goto release_mutex;
+ 		}
+-		bytes = msblk->stream.total_out;
+-		mutex_unlock(&msblk->read_data_mutex);
+ 	} else {
+ 		int i;
+ 
+@@ -325,7 +355,7 @@ SQSH_EXTERN unsigned int squashfs_read_d
+ 	return bytes;
+ 
+ release_mutex:
+-	mutex_unlock(&msblk->read_data_mutex);
++	//mutex_unlock(&msblk->read_data_mutex);
+ 
+ block_release:
+ 	for (; k < b; k++)
+@@ -1106,29 +1136,28 @@ static int squashfs_fill_super(struct su
+ {
+ 	struct squashfs_sb_info *msblk;
+ 	struct squashfs_super_block *sblk;
+-	int i;
++	int i, err;
+ 	char b[BDEVNAME_SIZE];
+ 	struct inode *root;
++	void *label;
+ 
+ 	TRACE("Entered squashfs_read_superblock\n");
+ 
++	err = -ENOMEM;
+ 	if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info),
+ 						GFP_KERNEL))) {
+ 		ERROR("Failed to allocate superblock\n");
+ 		goto failure;
+ 	}
++	label = &&out_fsinfo;
+ 	memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info));
+ 	msblk = s->s_fs_info;
+-	if (!(msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()))) {
+-		ERROR("Failed to allocate zlib workspace\n");
+-		goto failure;
+-	}
+ 	sblk = &msblk->sblk;
+ 	
+ 	msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
+ 	msblk->devblksize_log2 = ffz(~msblk->devblksize);
+ 
+-	mutex_init(&msblk->read_data_mutex);
++	//mutex_init(&msblk->read_data_mutex);
+ 	mutex_init(&msblk->read_page_mutex);
+ 	mutex_init(&msblk->block_cache_mutex);
+ 	mutex_init(&msblk->fragment_mutex);
+@@ -1137,45 +1166,60 @@ static int squashfs_fill_super(struct su
+ 	init_waitqueue_head(&msblk->waitq);
+ 	init_waitqueue_head(&msblk->fragment_wait_queue);
+ 
++	err = -EINVAL;
+ 	sblk->bytes_used = sizeof(struct squashfs_super_block);
+ 	if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
+ 					sizeof(struct squashfs_super_block) |
+ 					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) {
+ 		SERROR("unable to read superblock\n");
+-		goto failed_mount;
++		goto *label;
+ 	}
+ 
+ 	/* Check it is a SQUASHFS superblock */
++	s->s_magic = sblk->s_magic;
+ 	msblk->swap = 0;
+-	if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
+-		if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
+-			struct squashfs_super_block ssblk;
+-
+-			WARNING("Mounting a different endian SQUASHFS "
+-				"filesystem on %s\n", bdevname(s->s_bdev, b));
+-
+-			SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
+-			memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
+-			msblk->swap = 1;
+-		} else  {
+-			SERROR("Can't find a SQUASHFS superblock on %s\n",
+-							bdevname(s->s_bdev, b));
+-			goto failed_mount;
+-		}
++	dpri("magic 0x%x\n", sblk->s_magic);
++	switch (sblk->s_magic) {
++		struct squashfs_super_block ssblk;
++
++	case SQUASHFS_MAGIC_SWAP:
++		/*FALLTHROUGH*/
++	case SQUASHFS_MAGIC_LZMA_SWAP:
++		WARNING("Mounting a different endian SQUASHFS "
++			"filesystem on %s\n", bdevname(s->s_bdev, b));
++
++		SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
++		memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
++		msblk->swap = 1;
++		/*FALLTHROUGH*/
++	case SQUASHFS_MAGIC:
++	case SQUASHFS_MAGIC_LZMA:
++		break;
++	default:
++		SERROR("Can't find a SQUASHFS superblock on %s\n",
++		       bdevname(s->s_bdev, b));
++		goto *label;
++	}
++
++	{
++		struct sqlzma *p;
++		dpri("block_size %d\n", sblk->block_size);
++		BUG_ON(sblk->block_size > sizeof(p->read_data));
+ 	}
+ 
+ 	/* Check the MAJOR & MINOR versions */
++	err = -EINVAL;
+ 	if(!supported_squashfs_filesystem(msblk, silent))
+-		goto failed_mount;
++		goto *label;
+ 
+ 	/* Check the filesystem does not extend beyond the end of the
+ 	   block device */
+ 	if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode))
+-		goto failed_mount;
++		goto *label;
+ 
+ 	/* Check the root inode for sanity */
+ 	if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE)
+-		goto failed_mount;
++		goto *label;
+ 
+ 	TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
+ 	TRACE("Inodes are %scompressed\n",
+@@ -1205,11 +1249,13 @@ static int squashfs_fill_super(struct su
+ 	s->s_op = &squashfs_super_ops;
+ 
+ 	/* Init inode_table block pointer array */
++	err = -ENOMEM;
+ 	if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) *
+ 					SQUASHFS_CACHED_BLKS, GFP_KERNEL))) {
+ 		ERROR("Failed to allocate block cache\n");
+-		goto failed_mount;
++		goto *label;
+ 	}
++	label = &&out_block_cache;
+ 
+ 	for (i = 0; i < SQUASHFS_CACHED_BLKS; i++)
+ 		msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
+@@ -1219,17 +1265,21 @@ static int squashfs_fill_super(struct su
+ 	/* Allocate read_page block */
+ 	if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {
+ 		ERROR("Failed to allocate read_page block\n");
+-		goto failed_mount;
++		goto *label;
+ 	}
++	label = &&out_read_page;
+ 
+ 	/* Allocate uid and gid tables */
+ 	if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) *
+ 					sizeof(unsigned int), GFP_KERNEL))) {
+ 		ERROR("Failed to allocate uid/gid table\n");
+-		goto failed_mount;
++		goto *label;
+ 	}
++	label = &&out_uid;
+ 	msblk->guid = msblk->uid + sblk->no_uids;
+    
++	dpri("swap %d\n", msblk->swap);
++	err = -EINVAL;
+ 	if (msblk->swap) {
+ 		unsigned int suid[sblk->no_uids + sblk->no_guids];
+ 
+@@ -1238,7 +1288,7 @@ static int squashfs_fill_super(struct su
+ 					 sizeof(unsigned int)) |
+ 					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) {
+ 			ERROR("unable to read uid/gid table\n");
+-			goto failed_mount;
++			goto *label;
+ 		}
+ 
+ 		SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids +
+@@ -1249,18 +1299,20 @@ static int squashfs_fill_super(struct su
+ 					 sizeof(unsigned int)) |
+ 					SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) {
+ 			ERROR("unable to read uid/gid table\n");
+-			goto failed_mount;
++			goto *label;
+ 		}
+ 
+ 
+ 	if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
+ 		goto allocate_root;
+ 
++	err = -ENOMEM;
+ 	if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) *
+ 				SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) {
+ 		ERROR("Failed to allocate fragment block cache\n");
+-		goto failed_mount;
++		goto *label;
+ 	}
++	label = &&out_fragment;
+ 
+ 	for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) {
+ 		msblk->fragment[i].locked = 0;
+@@ -1272,7 +1324,7 @@ static int squashfs_fill_super(struct su
+ 
+ 	/* Allocate and read fragment index table */
+ 	if (msblk->read_fragment_index_table(s) == 0)
+-		goto failed_mount;
++		goto *label;
+ 
+ 	if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK)
+ 		goto allocate_root;
+@@ -1285,9 +1337,12 @@ static int squashfs_fill_super(struct su
+ 	s->s_export_op = &squashfs_export_ops;
+ 
+ allocate_root:
++	dpri("alloate_root\n");
+ 	root = new_inode(s);
+-	if ((msblk->read_inode)(root, sblk->root_inode) == 0)
++	if ((msblk->read_inode)(root, sblk->root_inode) == 0) {
++		iput(root);
+ 		goto failed_mount;
++	}
+ 	insert_inode_hash(root);
+ 
+ 	if ((s->s_root = d_alloc_root(root)) == NULL) {
+@@ -1302,18 +1357,20 @@ allocate_root:
+ failed_mount:
+ 	kfree(msblk->inode_lookup_table);
+ 	kfree(msblk->fragment_index);
++	kfree(msblk->fragment_index_2);
++ out_fragment:
+ 	kfree(msblk->fragment);
++ out_uid:
+ 	kfree(msblk->uid);
++ out_read_page:
+ 	kfree(msblk->read_page);
++ out_block_cache:
+ 	kfree(msblk->block_cache);
+-	kfree(msblk->fragment_index_2);
+-	vfree(msblk->stream.workspace);
++ out_fsinfo:
+ 	kfree(s->s_fs_info);
+ 	s->s_fs_info = NULL;
+-	return -EINVAL;
+-
+-failure:
+-	return -ENOMEM;
++ failure:
++	return err;
+ }
+ 
+ 
+@@ -1324,7 +1381,7 @@ static int squashfs_statfs(struct dentry
+ 
+ 	TRACE("Entered squashfs_statfs\n");
+ 
+-	buf->f_type = SQUASHFS_MAGIC;
++	buf->f_type = sblk->s_magic;
+ 	buf->f_bsize = sblk->block_size;
+ 	buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
+ 	buf->f_bfree = buf->f_bavail = 0;
+@@ -2235,7 +2292,6 @@ static void squashfs_put_super(struct su
+ 		kfree(sbi->fragment_index);
+ 		kfree(sbi->fragment_index_2);
+ 		kfree(sbi->meta_index);
+-		vfree(sbi->stream.workspace);
+ 		kfree(s->s_fs_info);
+ 		s->s_fs_info = NULL;
+ 	}
+@@ -2251,17 +2307,62 @@ static int squashfs_get_sb(struct file_s
+ }
+ 
+ 
++static void free_sqlzma(void)
++{
++	int cpu;
++	struct sqlzma *p;
++
++	for_each_online_cpu(cpu) {
++		p = per_cpu(sqlzma, cpu);
++		if (p) {
++#ifdef KeepPreemptive
++			mutex_destroy(&p->mtx);
++#endif
++			sqlzma_fin(&p->un);
++			kfree(p);
++		}
++	}
++}
++
+ static int __init init_squashfs_fs(void)
+ {
++	struct sqlzma *p;
++	int cpu;
+ 	int err = init_inodecache();
+ 	if (err)
+ 		goto out;
+ 
++	for_each_online_cpu(cpu) {
++		dpri("%d: %p\n", cpu, per_cpu(sqlzma, cpu));
++		err = -ENOMEM;
++		p = kmalloc(sizeof(struct sqlzma), GFP_KERNEL);
++		if (p) {
++#ifdef KeepPreemptive
++			mutex_init(&p->mtx);
++#endif
++			err = sqlzma_init(&p->un, 1, 0);
++			if (unlikely(err)) {
++				ERROR("Failed to intialize uncompress workspace\n");
++				break;
++			}
++			per_cpu(sqlzma, cpu) = p;
++			err = 0;
++		} else
++			break;
++	}
++	if (unlikely(err)) {
++		free_sqlzma();
++		goto out;
++	}
++
+ 	printk(KERN_INFO "squashfs: version 3.2-r2 (2007/01/15) "
+-		"Phillip Lougher\n");
++		"Phillip Lougher\n"
++		"squashfs: LZMA suppport for slax.org by jro\n");
+ 
+-	if ((err = register_filesystem(&squashfs_fs_type)))
++	if ((err = register_filesystem(&squashfs_fs_type))) {
++		free_sqlzma();
+ 		destroy_inodecache();
++	}
+ 
+ out:
+ 	return err;
+@@ -2271,6 +2372,7 @@ out:
+ static void __exit exit_squashfs_fs(void)
+ {
+ 	unregister_filesystem(&squashfs_fs_type);
++	free_sqlzma();
+ 	destroy_inodecache();
+ }
+ 
+@@ -2324,6 +2426,6 @@ static void destroy_inodecache(void)
+ 
+ module_init(init_squashfs_fs);
+ module_exit(exit_squashfs_fs);
+-MODULE_DESCRIPTION("squashfs 3.2-r2, a compressed read-only filesystem");
+-MODULE_AUTHOR("Phillip Lougher <phillip at lougher.org.uk>");
++MODULE_DESCRIPTION("squashfs 3.2-r2, a compressed read-only filesystem, and LZMA suppport for slax.org");
++MODULE_AUTHOR("Phillip Lougher <phillip at lougher.org.uk>, and LZMA suppport for slax.org by jro");
+ MODULE_LICENSE("GPL");
+Index: linux-2.6.21.1/include/linux/squashfs_fs_sb.h
+===================================================================
+RCS file: linux-2.6.21.1/include/linux/squashfs_fs_sb.h,v
+retrieving revision 1.1
+retrieving revision 1.2
+diff -u -p -r1.1 -r1.2
+--- linux-2.6.21.1/include/linux/squashfs_fs_sb.h	16 Jan 2007 03:30:24 -0000	1.1
++++ linux-2.6.21.1/include/linux/squashfs_fs_sb.h	16 Jan 2007 05:08:17 -0000	1.2
+@@ -24,6 +24,7 @@
+  */
+ 
+ #include <linux/squashfs_fs.h>
++#include "sqlzma.h"
+ 
+ struct squashfs_cache {
+ 	long long	block;
+@@ -54,7 +55,7 @@ struct squashfs_sb_info {
+ 	long long		*fragment_index;
+ 	unsigned int		*fragment_index_2;
+ 	char			*read_page;
+-	struct mutex		read_data_mutex;
++	//struct mutex		read_data_mutex;
+ 	struct mutex		read_page_mutex;
+ 	struct mutex		block_cache_mutex;
+ 	struct mutex		fragment_mutex;
+@@ -62,7 +63,6 @@ struct squashfs_sb_info {
+ 	wait_queue_head_t	waitq;
+ 	wait_queue_head_t	fragment_wait_queue;
+ 	struct meta_index	*meta_index;
+-	z_stream		stream;
+ 	long long		*inode_lookup_table;
+ 	int			(*read_inode)(struct inode *i,  squashfs_inode_t \
+ 				inode);
================================================================


More information about the pld-cvs-commit mailing list