Blame view

fs/squashfs/decompressor.c 3.72 KB
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
1
2
3
4
  /*
   * Squashfs - a compressed read only filesystem for Linux
   *
   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
d7f2ff671   Phillip Lougher   Squashfs: update ...
5
   * Phillip Lougher <phillip@squashfs.org.uk>
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
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   Phillip Lougher   Squashfs: extend ...
26
  #include <linux/slab.h>
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
27
28
29
30
  #include <linux/buffer_head.h>
  
  #include "squashfs_fs.h"
  #include "squashfs_fs_sb.h"
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
31
32
  #include "decompressor.h"
  #include "squashfs.h"
846b730e9   Phillip Lougher   Squashfs: General...
33
  #include "page_actor.h"
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
34
35
36
37
38
  
  /*
   * This file (and decompressor.h) implements a decompressor framework for
   * Squashfs, allowing multiple decompressors to be easily supported
   */
dc3256782   Phillip Lougher   Squashfs: add dec...
39
  static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
40
  	NULL, NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0
dc3256782   Phillip Lougher   Squashfs: add dec...
41
  };
62421645b   Phillip Lougher   Squashfs: Add LZ4...
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   Chan Jeong   Squashfs: Add LZO...
47
  #ifndef CONFIG_SQUASHFS_LZO
01a678c5a   Phillip Lougher   Squashfs: simplif...
48
  static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
49
  	NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
dc3256782   Phillip Lougher   Squashfs: add dec...
50
  };
79cb8ced7   Chan Jeong   Squashfs: Add LZO...
51
  #endif
dc3256782   Phillip Lougher   Squashfs: add dec...
52

7a43ae523   Phillip Lougher   Squashfs: Add XZ ...
53
54
  #ifndef CONFIG_SQUASHFS_XZ
  static const struct squashfs_decompressor squashfs_xz_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
55
  	NULL, NULL, NULL, NULL, XZ_COMPRESSION, "xz", 0
7a43ae523   Phillip Lougher   Squashfs: Add XZ ...
56
57
  };
  #endif
cc6d34971   Phillip Lougher   Squashfs: Make ZL...
58
59
  #ifndef CONFIG_SQUASHFS_ZLIB
  static const struct squashfs_decompressor squashfs_zlib_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
60
  	NULL, NULL, NULL, NULL, ZLIB_COMPRESSION, "zlib", 0
cc6d34971   Phillip Lougher   Squashfs: Make ZL...
61
62
  };
  #endif
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
63
  static const struct squashfs_decompressor squashfs_unknown_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
64
  	NULL, NULL, NULL, NULL, 0, "unknown", 0
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
65
66
67
68
  };
  
  static const struct squashfs_decompressor *decompressor[] = {
  	&squashfs_zlib_comp_ops,
62421645b   Phillip Lougher   Squashfs: Add LZ4...
69
  	&squashfs_lz4_comp_ops,
79cb8ced7   Chan Jeong   Squashfs: Add LZO...
70
  	&squashfs_lzo_comp_ops,
7a43ae523   Phillip Lougher   Squashfs: Add XZ ...
71
  	&squashfs_xz_comp_ops,
01a678c5a   Phillip Lougher   Squashfs: simplif...
72
  	&squashfs_lzma_unsupported_comp_ops,
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
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   Phillip Lougher   Squashfs: extend ...
87

9508c6b90   Phillip Lougher   Squashfs: Refacto...
88
  static void *get_comp_opts(struct super_block *sb, unsigned short flags)
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
89
90
  {
  	struct squashfs_sb_info *msblk = sb->s_fs_info;
9508c6b90   Phillip Lougher   Squashfs: Refacto...
91
  	void *buffer = NULL, *comp_opts;
846b730e9   Phillip Lougher   Squashfs: General...
92
  	struct squashfs_page_actor *actor = NULL;
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
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   Phillip Lougher   Squashfs: Refacto...
100
101
102
103
  		if (buffer == NULL) {
  			comp_opts = ERR_PTR(-ENOMEM);
  			goto out;
  		}
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
104

846b730e9   Phillip Lougher   Squashfs: General...
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   Phillip Lougher   Squashfs: extend ...
113
114
  
  		if (length < 0) {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
115
116
  			comp_opts = ERR_PTR(length);
  			goto out;
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
117
118
  		}
  	}
9508c6b90   Phillip Lougher   Squashfs: Refacto...
119
  	comp_opts = squashfs_comp_opts(msblk, buffer, length);
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
120

9508c6b90   Phillip Lougher   Squashfs: Refacto...
121
  out:
846b730e9   Phillip Lougher   Squashfs: General...
122
  	kfree(actor);
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
123
  	kfree(buffer);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
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   Phillip Lougher   Squashfs: extend ...
139

9508c6b90   Phillip Lougher   Squashfs: Refacto...
140
  	return stream;
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
141
  }