Blame view
fs/squashfs/decompressor.c
3.25 KB
68252eb5f
|
1 |
// SPDX-License-Identifier: GPL-2.0-or-later |
4c0f0bb23
|
2 3 4 5 |
/* * Squashfs - a compressed read only filesystem for Linux * * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
d7f2ff671
|
6 |
* Phillip Lougher <phillip@squashfs.org.uk> |
4c0f0bb23
|
7 |
* |
4c0f0bb23
|
8 9 10 11 12 |
* decompressor.c */ #include <linux/types.h> #include <linux/mutex.h> |
b7fc0ff09
|
13 |
#include <linux/slab.h> |
4c0f0bb23
|
14 15 16 17 |
#include <linux/buffer_head.h> #include "squashfs_fs.h" #include "squashfs_fs_sb.h" |
4c0f0bb23
|
18 19 |
#include "decompressor.h" #include "squashfs.h" |
846b730e9
|
20 |
#include "page_actor.h" |
4c0f0bb23
|
21 22 23 24 25 |
/* * This file (and decompressor.h) implements a decompressor framework for * Squashfs, allowing multiple decompressors to be easily supported */ |
dc3256782
|
26 |
static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = { |
9508c6b90
|
27 |
NULL, NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0 |
dc3256782
|
28 |
}; |
62421645b
|
29 30 31 32 33 |
#ifndef CONFIG_SQUASHFS_LZ4 static const struct squashfs_decompressor squashfs_lz4_comp_ops = { NULL, NULL, NULL, NULL, LZ4_COMPRESSION, "lz4", 0 }; #endif |
79cb8ced7
|
34 |
#ifndef CONFIG_SQUASHFS_LZO |
01a678c5a
|
35 |
static const struct squashfs_decompressor squashfs_lzo_comp_ops = { |
9508c6b90
|
36 |
NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0 |
dc3256782
|
37 |
}; |
79cb8ced7
|
38 |
#endif |
dc3256782
|
39 |
|
7a43ae523
|
40 41 |
#ifndef CONFIG_SQUASHFS_XZ static const struct squashfs_decompressor squashfs_xz_comp_ops = { |
9508c6b90
|
42 |
NULL, NULL, NULL, NULL, XZ_COMPRESSION, "xz", 0 |
7a43ae523
|
43 44 |
}; #endif |
cc6d34971
|
45 46 |
#ifndef CONFIG_SQUASHFS_ZLIB static const struct squashfs_decompressor squashfs_zlib_comp_ops = { |
9508c6b90
|
47 |
NULL, NULL, NULL, NULL, ZLIB_COMPRESSION, "zlib", 0 |
cc6d34971
|
48 49 |
}; #endif |
87bf54bb4
|
50 51 52 53 54 |
#ifndef CONFIG_SQUASHFS_ZSTD static const struct squashfs_decompressor squashfs_zstd_comp_ops = { NULL, NULL, NULL, NULL, ZSTD_COMPRESSION, "zstd", 0 }; #endif |
4c0f0bb23
|
55 |
static const struct squashfs_decompressor squashfs_unknown_comp_ops = { |
9508c6b90
|
56 |
NULL, NULL, NULL, NULL, 0, "unknown", 0 |
4c0f0bb23
|
57 58 59 60 |
}; static const struct squashfs_decompressor *decompressor[] = { &squashfs_zlib_comp_ops, |
62421645b
|
61 |
&squashfs_lz4_comp_ops, |
79cb8ced7
|
62 |
&squashfs_lzo_comp_ops, |
7a43ae523
|
63 |
&squashfs_xz_comp_ops, |
01a678c5a
|
64 |
&squashfs_lzma_unsupported_comp_ops, |
87bf54bb4
|
65 |
&squashfs_zstd_comp_ops, |
4c0f0bb23
|
66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
&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
|
80 |
|
9508c6b90
|
81 |
static void *get_comp_opts(struct super_block *sb, unsigned short flags) |
b7fc0ff09
|
82 83 |
{ struct squashfs_sb_info *msblk = sb->s_fs_info; |
9508c6b90
|
84 |
void *buffer = NULL, *comp_opts; |
846b730e9
|
85 |
struct squashfs_page_actor *actor = NULL; |
b7fc0ff09
|
86 87 88 89 90 91 |
int length = 0; /* * Read decompressor specific options from file system if present */ if (SQUASHFS_COMP_OPTS(flags)) { |
09cbfeaf1
|
92 |
buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); |
9508c6b90
|
93 94 95 96 |
if (buffer == NULL) { comp_opts = ERR_PTR(-ENOMEM); goto out; } |
b7fc0ff09
|
97 |
|
846b730e9
|
98 99 100 101 102 103 104 105 |
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
|
106 107 |
if (length < 0) { |
9508c6b90
|
108 109 |
comp_opts = ERR_PTR(length); goto out; |
b7fc0ff09
|
110 111 |
} } |
9508c6b90
|
112 |
comp_opts = squashfs_comp_opts(msblk, buffer, length); |
b7fc0ff09
|
113 |
|
9508c6b90
|
114 |
out: |
846b730e9
|
115 |
kfree(actor); |
b7fc0ff09
|
116 |
kfree(buffer); |
9508c6b90
|
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
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
|
132 |
|
9508c6b90
|
133 |
return stream; |
b7fc0ff09
|
134 |
} |