aboutsummaryrefslogtreecommitdiffstats
path: root/fs/squashfs/super.c
diff options
context:
space:
mode:
authorPhillip Lougher <phillip@lougher.demon.co.uk>2009-10-05 23:04:15 -0400
committerPhillip Lougher <phillip@lougher.demon.co.uk>2010-01-20 16:47:47 -0500
commit4c0f0bb2351bee3de8dd7715ee199454a59f1230 (patch)
treec552993587a8e87f7ebc0fe0955efdde94cc8884 /fs/squashfs/super.c
parentf1a40359f8d8ba073257ed31a513e492621bcbc5 (diff)
Squashfs: add a decompressor framework
This adds a decompressor framework which allows multiple compression algorithms to be cleanly supported. Also update zlib wrapper and other code to use the new framework. Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
Diffstat (limited to 'fs/squashfs/super.c')
-rw-r--r--fs/squashfs/super.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index b9f8c6a92d6a..3550aec2f655 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -41,27 +41,35 @@
41#include "squashfs_fs_sb.h" 41#include "squashfs_fs_sb.h"
42#include "squashfs_fs_i.h" 42#include "squashfs_fs_i.h"
43#include "squashfs.h" 43#include "squashfs.h"
44#include "decompressor.h"
44 45
45static struct file_system_type squashfs_fs_type; 46static struct file_system_type squashfs_fs_type;
46static const struct super_operations squashfs_super_ops; 47static const struct super_operations squashfs_super_ops;
47 48
48static int supported_squashfs_filesystem(short major, short minor, short comp) 49static const struct squashfs_decompressor *supported_squashfs_filesystem(short
50 major, short minor, short id)
49{ 51{
52 const struct squashfs_decompressor *decompressor;
53
50 if (major < SQUASHFS_MAJOR) { 54 if (major < SQUASHFS_MAJOR) {
51 ERROR("Major/Minor mismatch, older Squashfs %d.%d " 55 ERROR("Major/Minor mismatch, older Squashfs %d.%d "
52 "filesystems are unsupported\n", major, minor); 56 "filesystems are unsupported\n", major, minor);
53 return -EINVAL; 57 return NULL;
54 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { 58 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
55 ERROR("Major/Minor mismatch, trying to mount newer " 59 ERROR("Major/Minor mismatch, trying to mount newer "
56 "%d.%d filesystem\n", major, minor); 60 "%d.%d filesystem\n", major, minor);
57 ERROR("Please update your kernel\n"); 61 ERROR("Please update your kernel\n");
58 return -EINVAL; 62 return NULL;
59 } 63 }
60 64
61 if (comp != ZLIB_COMPRESSION) 65 decompressor = squashfs_lookup_decompressor(id);
62 return -EINVAL; 66 if (!decompressor->supported) {
67 ERROR("Filesystem uses \"%s\" compression. This is not "
68 "supported\n", decompressor->name);
69 return NULL;
70 }
63 71
64 return 0; 72 return decompressor;
65} 73}
66 74
67 75
@@ -86,10 +94,6 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
86 } 94 }
87 msblk = sb->s_fs_info; 95 msblk = sb->s_fs_info;
88 96
89 msblk->stream = squashfs_zlib_init();
90 if (msblk->stream == NULL)
91 goto failure;
92
93 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); 97 sblk = kzalloc(sizeof(*sblk), GFP_KERNEL);
94 if (sblk == NULL) { 98 if (sblk == NULL) {
95 ERROR("Failed to allocate squashfs_super_block\n"); 99 ERROR("Failed to allocate squashfs_super_block\n");
@@ -116,25 +120,25 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
116 goto failed_mount; 120 goto failed_mount;
117 } 121 }
118 122
123 err = -EINVAL;
124
119 /* Check it is a SQUASHFS superblock */ 125 /* Check it is a SQUASHFS superblock */
120 sb->s_magic = le32_to_cpu(sblk->s_magic); 126 sb->s_magic = le32_to_cpu(sblk->s_magic);
121 if (sb->s_magic != SQUASHFS_MAGIC) { 127 if (sb->s_magic != SQUASHFS_MAGIC) {
122 if (!silent) 128 if (!silent)
123 ERROR("Can't find a SQUASHFS superblock on %s\n", 129 ERROR("Can't find a SQUASHFS superblock on %s\n",
124 bdevname(sb->s_bdev, b)); 130 bdevname(sb->s_bdev, b));
125 err = -EINVAL;
126 goto failed_mount; 131 goto failed_mount;
127 } 132 }
128 133
129 /* Check the MAJOR & MINOR versions and compression type */ 134 /* Check the MAJOR & MINOR versions and lookup compression type */
130 err = supported_squashfs_filesystem(le16_to_cpu(sblk->s_major), 135 msblk->decompressor = supported_squashfs_filesystem(
136 le16_to_cpu(sblk->s_major),
131 le16_to_cpu(sblk->s_minor), 137 le16_to_cpu(sblk->s_minor),
132 le16_to_cpu(sblk->compression)); 138 le16_to_cpu(sblk->compression));
133 if (err < 0) 139 if (msblk->decompressor == NULL)
134 goto failed_mount; 140 goto failed_mount;
135 141
136 err = -EINVAL;
137
138 /* 142 /*
139 * Check if there's xattrs in the filesystem. These are not 143 * Check if there's xattrs in the filesystem. These are not
140 * supported in this version, so warn that they will be ignored. 144 * supported in this version, so warn that they will be ignored.
@@ -201,6 +205,10 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
201 205
202 err = -ENOMEM; 206 err = -ENOMEM;
203 207
208 msblk->stream = squashfs_decompressor_init(msblk);
209 if (msblk->stream == NULL)
210 goto failed_mount;
211
204 msblk->block_cache = squashfs_cache_init("metadata", 212 msblk->block_cache = squashfs_cache_init("metadata",
205 SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE); 213 SQUASHFS_CACHED_BLKS, SQUASHFS_METADATA_SIZE);
206 if (msblk->block_cache == NULL) 214 if (msblk->block_cache == NULL)
@@ -288,7 +296,7 @@ failed_mount:
288 squashfs_cache_delete(msblk->block_cache); 296 squashfs_cache_delete(msblk->block_cache);
289 squashfs_cache_delete(msblk->fragment_cache); 297 squashfs_cache_delete(msblk->fragment_cache);
290 squashfs_cache_delete(msblk->read_page); 298 squashfs_cache_delete(msblk->read_page);
291 squashfs_zlib_free(msblk->stream); 299 squashfs_decompressor_free(msblk, msblk->stream);
292 kfree(msblk->inode_lookup_table); 300 kfree(msblk->inode_lookup_table);
293 kfree(msblk->fragment_index); 301 kfree(msblk->fragment_index);
294 kfree(msblk->id_table); 302 kfree(msblk->id_table);
@@ -298,7 +306,6 @@ failed_mount:
298 return err; 306 return err;
299 307
300failure: 308failure:
301 squashfs_zlib_free(msblk->stream);
302 kfree(sb->s_fs_info); 309 kfree(sb->s_fs_info);
303 sb->s_fs_info = NULL; 310 sb->s_fs_info = NULL;
304 return -ENOMEM; 311 return -ENOMEM;
@@ -342,7 +349,7 @@ static void squashfs_put_super(struct super_block *sb)
342 squashfs_cache_delete(sbi->block_cache); 349 squashfs_cache_delete(sbi->block_cache);
343 squashfs_cache_delete(sbi->fragment_cache); 350 squashfs_cache_delete(sbi->fragment_cache);
344 squashfs_cache_delete(sbi->read_page); 351 squashfs_cache_delete(sbi->read_page);
345 squashfs_zlib_free(sbi->stream); 352 squashfs_decompressor_free(sbi, sbi->stream);
346 kfree(sbi->id_table); 353 kfree(sbi->id_table);
347 kfree(sbi->fragment_index); 354 kfree(sbi->fragment_index);
348 kfree(sbi->meta_index); 355 kfree(sbi->meta_index);