Blame view
fs/squashfs/decompressor.c
3.72 KB
4c0f0bb23
|
1 2 3 4 |
/* * Squashfs - a compressed read only filesystem for Linux * * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
d7f2ff671
|
5 |
* Phillip Lougher <phillip@squashfs.org.uk> |
4c0f0bb23
|
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * decompressor.c */ #include <linux/types.h> #include <linux/mutex.h> |
b7fc0ff09
|
26 |
#include <linux/slab.h> |
4c0f0bb23
|
27 28 29 30 |
#include <linux/buffer_head.h> #include "squashfs_fs.h" #include "squashfs_fs_sb.h" |
4c0f0bb23
|
31 32 |
#include "decompressor.h" #include "squashfs.h" |
846b730e9
|
33 |
#include "page_actor.h" |
4c0f0bb23
|
34 35 36 37 38 |
/* * This file (and decompressor.h) implements a decompressor framework for * Squashfs, allowing multiple decompressors to be easily supported */ |
dc3256782
|
39 |
static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = { |
9508c6b90
|
40 |
NULL, NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0 |
dc3256782
|
41 |
}; |
62421645b
|
42 43 44 45 46 |
#ifndef CONFIG_SQUASHFS_LZ4 static const struct squashfs_decompressor squashfs_lz4_comp_ops = { NULL, NULL, NULL, NULL, LZ4_COMPRESSION, "lz4", 0 }; #endif |
79cb8ced7
|
47 |
#ifndef CONFIG_SQUASHFS_LZO |
01a678c5a
|
48 |
static const struct squashfs_decompressor squashfs_lzo_comp_ops = { |
9508c6b90
|
49 |
NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0 |
dc3256782
|
50 |
}; |
79cb8ced7
|
51 |
#endif |
dc3256782
|
52 |
|
7a43ae523
|
53 54 |
#ifndef CONFIG_SQUASHFS_XZ static const struct squashfs_decompressor squashfs_xz_comp_ops = { |
9508c6b90
|
55 |
NULL, NULL, NULL, NULL, XZ_COMPRESSION, "xz", 0 |
7a43ae523
|
56 57 |
}; #endif |
cc6d34971
|
58 59 |
#ifndef CONFIG_SQUASHFS_ZLIB static const struct squashfs_decompressor squashfs_zlib_comp_ops = { |
9508c6b90
|
60 |
NULL, NULL, NULL, NULL, ZLIB_COMPRESSION, "zlib", 0 |
cc6d34971
|
61 62 |
}; #endif |
4c0f0bb23
|
63 |
static const struct squashfs_decompressor squashfs_unknown_comp_ops = { |
9508c6b90
|
64 |
NULL, NULL, NULL, NULL, 0, "unknown", 0 |
4c0f0bb23
|
65 66 67 68 |
}; static const struct squashfs_decompressor *decompressor[] = { &squashfs_zlib_comp_ops, |
62421645b
|
69 |
&squashfs_lz4_comp_ops, |
79cb8ced7
|
70 |
&squashfs_lzo_comp_ops, |
7a43ae523
|
71 |
&squashfs_xz_comp_ops, |
01a678c5a
|
72 |
&squashfs_lzma_unsupported_comp_ops, |
4c0f0bb23
|
73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
&squashfs_unknown_comp_ops }; const struct squashfs_decompressor *squashfs_lookup_decompressor(int id) { int i; for (i = 0; decompressor[i]->id; i++) if (id == decompressor[i]->id) break; return decompressor[i]; } |
b7fc0ff09
|
87 |
|
9508c6b90
|
88 |
static void *get_comp_opts(struct super_block *sb, unsigned short flags) |
b7fc0ff09
|
89 90 |
{ struct squashfs_sb_info *msblk = sb->s_fs_info; |
9508c6b90
|
91 |
void *buffer = NULL, *comp_opts; |
846b730e9
|
92 |
struct squashfs_page_actor *actor = NULL; |
b7fc0ff09
|
93 94 95 96 97 98 99 |
int length = 0; /* * Read decompressor specific options from file system if present */ if (SQUASHFS_COMP_OPTS(flags)) { buffer = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL); |
9508c6b90
|
100 101 102 103 |
if (buffer == NULL) { comp_opts = ERR_PTR(-ENOMEM); goto out; } |
b7fc0ff09
|
104 |
|
846b730e9
|
105 106 107 108 109 110 111 112 |
actor = squashfs_page_actor_init(&buffer, 1, 0); if (actor == NULL) { comp_opts = ERR_PTR(-ENOMEM); goto out; } length = squashfs_read_data(sb, sizeof(struct squashfs_super_block), 0, NULL, actor); |
b7fc0ff09
|
113 114 |
if (length < 0) { |
9508c6b90
|
115 116 |
comp_opts = ERR_PTR(length); goto out; |
b7fc0ff09
|
117 118 |
} } |
9508c6b90
|
119 |
comp_opts = squashfs_comp_opts(msblk, buffer, length); |
b7fc0ff09
|
120 |
|
9508c6b90
|
121 |
out: |
846b730e9
|
122 |
kfree(actor); |
b7fc0ff09
|
123 |
kfree(buffer); |
9508c6b90
|
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
return comp_opts; } void *squashfs_decompressor_setup(struct super_block *sb, unsigned short flags) { struct squashfs_sb_info *msblk = sb->s_fs_info; void *stream, *comp_opts = get_comp_opts(sb, flags); if (IS_ERR(comp_opts)) return comp_opts; stream = squashfs_decompressor_create(msblk, comp_opts); if (IS_ERR(stream)) kfree(comp_opts); |
b7fc0ff09
|
139 |
|
9508c6b90
|
140 |
return stream; |
b7fc0ff09
|
141 |
} |