Blame view

fs/squashfs/decompressor.c 3.25 KB
68252eb5f   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
2
3
4
5
  /*
   * Squashfs - a compressed read only filesystem for Linux
   *
   * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
d7f2ff671   Phillip Lougher   Squashfs: update ...
6
   * Phillip Lougher <phillip@squashfs.org.uk>
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
7
   *
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
8
9
10
11
12
   * decompressor.c
   */
  
  #include <linux/types.h>
  #include <linux/mutex.h>
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
13
  #include <linux/slab.h>
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
14
15
16
17
  #include <linux/buffer_head.h>
  
  #include "squashfs_fs.h"
  #include "squashfs_fs_sb.h"
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
18
19
  #include "decompressor.h"
  #include "squashfs.h"
846b730e9   Phillip Lougher   Squashfs: General...
20
  #include "page_actor.h"
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
21
22
23
24
25
  
  /*
   * This file (and decompressor.h) implements a decompressor framework for
   * Squashfs, allowing multiple decompressors to be easily supported
   */
dc3256782   Phillip Lougher   Squashfs: add dec...
26
  static const struct squashfs_decompressor squashfs_lzma_unsupported_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
27
  	NULL, NULL, NULL, NULL, LZMA_COMPRESSION, "lzma", 0
dc3256782   Phillip Lougher   Squashfs: add dec...
28
  };
62421645b   Phillip Lougher   Squashfs: Add LZ4...
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   Chan Jeong   Squashfs: Add LZO...
34
  #ifndef CONFIG_SQUASHFS_LZO
01a678c5a   Phillip Lougher   Squashfs: simplif...
35
  static const struct squashfs_decompressor squashfs_lzo_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
36
  	NULL, NULL, NULL, NULL, LZO_COMPRESSION, "lzo", 0
dc3256782   Phillip Lougher   Squashfs: add dec...
37
  };
79cb8ced7   Chan Jeong   Squashfs: Add LZO...
38
  #endif
dc3256782   Phillip Lougher   Squashfs: add dec...
39

7a43ae523   Phillip Lougher   Squashfs: Add XZ ...
40
41
  #ifndef CONFIG_SQUASHFS_XZ
  static const struct squashfs_decompressor squashfs_xz_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
42
  	NULL, NULL, NULL, NULL, XZ_COMPRESSION, "xz", 0
7a43ae523   Phillip Lougher   Squashfs: Add XZ ...
43
44
  };
  #endif
cc6d34971   Phillip Lougher   Squashfs: Make ZL...
45
46
  #ifndef CONFIG_SQUASHFS_ZLIB
  static const struct squashfs_decompressor squashfs_zlib_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
47
  	NULL, NULL, NULL, NULL, ZLIB_COMPRESSION, "zlib", 0
cc6d34971   Phillip Lougher   Squashfs: Make ZL...
48
49
  };
  #endif
87bf54bb4   Sean Purcell   squashfs: Add zst...
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   Phillip Lougher   Squashfs: add a d...
55
  static const struct squashfs_decompressor squashfs_unknown_comp_ops = {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
56
  	NULL, NULL, NULL, NULL, 0, "unknown", 0
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
57
58
59
60
  };
  
  static const struct squashfs_decompressor *decompressor[] = {
  	&squashfs_zlib_comp_ops,
62421645b   Phillip Lougher   Squashfs: Add LZ4...
61
  	&squashfs_lz4_comp_ops,
79cb8ced7   Chan Jeong   Squashfs: Add LZO...
62
  	&squashfs_lzo_comp_ops,
7a43ae523   Phillip Lougher   Squashfs: Add XZ ...
63
  	&squashfs_xz_comp_ops,
01a678c5a   Phillip Lougher   Squashfs: simplif...
64
  	&squashfs_lzma_unsupported_comp_ops,
87bf54bb4   Sean Purcell   squashfs: Add zst...
65
  	&squashfs_zstd_comp_ops,
4c0f0bb23   Phillip Lougher   Squashfs: add a d...
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   Phillip Lougher   Squashfs: extend ...
80

9508c6b90   Phillip Lougher   Squashfs: Refacto...
81
  static void *get_comp_opts(struct super_block *sb, unsigned short flags)
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
82
83
  {
  	struct squashfs_sb_info *msblk = sb->s_fs_info;
9508c6b90   Phillip Lougher   Squashfs: Refacto...
84
  	void *buffer = NULL, *comp_opts;
846b730e9   Phillip Lougher   Squashfs: General...
85
  	struct squashfs_page_actor *actor = NULL;
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
86
87
88
89
90
91
  	int length = 0;
  
  	/*
  	 * Read decompressor specific options from file system if present
  	 */
  	if (SQUASHFS_COMP_OPTS(flags)) {
09cbfeaf1   Kirill A. Shutemov   mm, fs: get rid o...
92
  		buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
93
94
95
96
  		if (buffer == NULL) {
  			comp_opts = ERR_PTR(-ENOMEM);
  			goto out;
  		}
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
97

846b730e9   Phillip Lougher   Squashfs: General...
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   Phillip Lougher   Squashfs: extend ...
106
107
  
  		if (length < 0) {
9508c6b90   Phillip Lougher   Squashfs: Refacto...
108
109
  			comp_opts = ERR_PTR(length);
  			goto out;
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
110
111
  		}
  	}
9508c6b90   Phillip Lougher   Squashfs: Refacto...
112
  	comp_opts = squashfs_comp_opts(msblk, buffer, length);
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
113

9508c6b90   Phillip Lougher   Squashfs: Refacto...
114
  out:
846b730e9   Phillip Lougher   Squashfs: General...
115
  	kfree(actor);
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
116
  	kfree(buffer);
9508c6b90   Phillip Lougher   Squashfs: Refacto...
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   Phillip Lougher   Squashfs: extend ...
132

9508c6b90   Phillip Lougher   Squashfs: Refacto...
133
  	return stream;
b7fc0ff09   Phillip Lougher   Squashfs: extend ...
134
  }