hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/fs/squashfs/zlib_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
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 * zlib_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/zlib.h>
2916 #include <linux/vmalloc.h>
....@@ -63,21 +50,35 @@
6350
6451
6552 static int zlib_uncompress(struct squashfs_sb_info *msblk, void *strm,
66
- struct buffer_head **bh, int b, int offset, int length,
53
+ struct bio *bio, int offset, int length,
6754 struct squashfs_page_actor *output)
6855 {
69
- int zlib_err, zlib_init = 0, k = 0;
56
+ struct bvec_iter_all iter_all = {};
57
+ struct bio_vec *bvec = bvec_init_iter_all(&iter_all);
58
+ int zlib_init = 0, error = 0;
7059 z_stream *stream = strm;
7160
7261 stream->avail_out = PAGE_SIZE;
7362 stream->next_out = squashfs_first_page(output);
7463 stream->avail_in = 0;
7564
76
- do {
77
- if (stream->avail_in == 0 && k < b) {
78
- int avail = min(length, msblk->devblksize - offset);
65
+ for (;;) {
66
+ int zlib_err;
67
+
68
+ if (stream->avail_in == 0) {
69
+ const void *data;
70
+ int avail;
71
+
72
+ if (!bio_next_segment(bio, &iter_all)) {
73
+ /* Z_STREAM_END must be reached. */
74
+ error = -EIO;
75
+ break;
76
+ }
77
+
78
+ avail = min(length, ((int)bvec->bv_len) - offset);
79
+ data = page_address(bvec->bv_page) + bvec->bv_offset;
7980 length -= avail;
80
- stream->next_in = bh[k]->b_data + offset;
81
+ stream->next_in = data + offset;
8182 stream->avail_in = avail;
8283 offset = 0;
8384 }
....@@ -91,37 +92,28 @@
9192 if (!zlib_init) {
9293 zlib_err = zlib_inflateInit(stream);
9394 if (zlib_err != Z_OK) {
94
- squashfs_finish_page(output);
95
- goto out;
95
+ error = -EIO;
96
+ break;
9697 }
9798 zlib_init = 1;
9899 }
99100
100101 zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
101
-
102
- if (stream->avail_in == 0 && k < b)
103
- put_bh(bh[k++]);
104
- } while (zlib_err == Z_OK);
102
+ if (zlib_err == Z_STREAM_END)
103
+ break;
104
+ if (zlib_err != Z_OK) {
105
+ error = -EIO;
106
+ break;
107
+ }
108
+ }
105109
106110 squashfs_finish_page(output);
107111
108
- if (zlib_err != Z_STREAM_END)
109
- goto out;
112
+ if (!error)
113
+ if (zlib_inflateEnd(stream) != Z_OK)
114
+ error = -EIO;
110115
111
- zlib_err = zlib_inflateEnd(stream);
112
- if (zlib_err != Z_OK)
113
- goto out;
114
-
115
- if (k < b)
116
- goto out;
117
-
118
- return stream->total_out;
119
-
120
-out:
121
- for (; k < b; k++)
122
- put_bh(bh[k]);
123
-
124
- return -EIO;
116
+ return error ? error : stream->total_out;
125117 }
126118
127119 const struct squashfs_decompressor squashfs_zlib_comp_ops = {