hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/squashfs/xz_wrapper.c
....@@ -1,29 +1,16 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Squashfs - a compressed read only filesystem for Linux
34 *
45 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
56 * Phillip Lougher <phillip@squashfs.org.uk>
67 *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version 2,
10
- * or (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program; if not, write to the Free Software
19
- * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
- *
218 * xz_wrapper.c
229 */
2310
2411
2512 #include <linux/mutex.h>
26
-#include <linux/buffer_head.h>
13
+#include <linux/bio.h>
2714 #include <linux/slab.h>
2815 #include <linux/xz.h>
2916 #include <linux/bitops.h>
....@@ -130,11 +117,12 @@
130117
131118
132119 static int squashfs_xz_uncompress(struct squashfs_sb_info *msblk, void *strm,
133
- struct buffer_head **bh, int b, int offset, int length,
120
+ struct bio *bio, int offset, int length,
134121 struct squashfs_page_actor *output)
135122 {
136
- enum xz_ret xz_err;
137
- int avail, total = 0, k = 0;
123
+ struct bvec_iter_all iter_all = {};
124
+ struct bio_vec *bvec = bvec_init_iter_all(&iter_all);
125
+ int total = 0, error = 0;
138126 struct squashfs_xz *stream = strm;
139127
140128 xz_dec_reset(stream->state);
....@@ -144,11 +132,23 @@
144132 stream->buf.out_size = PAGE_SIZE;
145133 stream->buf.out = squashfs_first_page(output);
146134
147
- do {
148
- if (stream->buf.in_pos == stream->buf.in_size && k < b) {
149
- avail = min(length, msblk->devblksize - offset);
135
+ for (;;) {
136
+ enum xz_ret xz_err;
137
+
138
+ if (stream->buf.in_pos == stream->buf.in_size) {
139
+ const void *data;
140
+ int avail;
141
+
142
+ if (!bio_next_segment(bio, &iter_all)) {
143
+ /* XZ_STREAM_END must be reached. */
144
+ error = -EIO;
145
+ break;
146
+ }
147
+
148
+ avail = min(length, ((int)bvec->bv_len) - offset);
149
+ data = page_address(bvec->bv_page) + bvec->bv_offset;
150150 length -= avail;
151
- stream->buf.in = bh[k]->b_data + offset;
151
+ stream->buf.in = data + offset;
152152 stream->buf.in_size = avail;
153153 stream->buf.in_pos = 0;
154154 offset = 0;
....@@ -163,23 +163,17 @@
163163 }
164164
165165 xz_err = xz_dec_run(stream->state, &stream->buf);
166
-
167
- if (stream->buf.in_pos == stream->buf.in_size && k < b)
168
- put_bh(bh[k++]);
169
- } while (xz_err == XZ_OK);
166
+ if (xz_err == XZ_STREAM_END)
167
+ break;
168
+ if (xz_err != XZ_OK) {
169
+ error = -EIO;
170
+ break;
171
+ }
172
+ }
170173
171174 squashfs_finish_page(output);
172175
173
- if (xz_err != XZ_STREAM_END || k < b)
174
- goto out;
175
-
176
- return total + stream->buf.out_pos;
177
-
178
-out:
179
- for (; k < b; k++)
180
- put_bh(bh[k]);
181
-
182
- return -EIO;
176
+ return error ? error : total + stream->buf.out_pos;
183177 }
184178
185179 const struct squashfs_decompressor squashfs_xz_comp_ops = {