hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/squashfs/zstd_wrapper.c
....@@ -1,24 +1,15 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Squashfs - a compressed read only filesystem for Linux
34 *
45 * Copyright (c) 2016-present, Facebook, Inc.
56 * All rights reserved.
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
- *
178 * zstd_wrapper.c
189 */
1910
2011 #include <linux/mutex.h>
21
-#include <linux/buffer_head.h>
12
+#include <linux/bio.h>
2213 #include <linux/slab.h>
2314 #include <linux/zstd.h>
2415 #include <linux/vmalloc.h>
....@@ -68,33 +59,44 @@
6859
6960
7061 static int zstd_uncompress(struct squashfs_sb_info *msblk, void *strm,
71
- struct buffer_head **bh, int b, int offset, int length,
62
+ struct bio *bio, int offset, int length,
7263 struct squashfs_page_actor *output)
7364 {
7465 struct workspace *wksp = strm;
7566 ZSTD_DStream *stream;
7667 size_t total_out = 0;
77
- size_t zstd_err;
78
- int k = 0;
68
+ int error = 0;
7969 ZSTD_inBuffer in_buf = { NULL, 0, 0 };
8070 ZSTD_outBuffer out_buf = { NULL, 0, 0 };
71
+ struct bvec_iter_all iter_all = {};
72
+ struct bio_vec *bvec = bvec_init_iter_all(&iter_all);
8173
8274 stream = ZSTD_initDStream(wksp->window_size, wksp->mem, wksp->mem_size);
8375
8476 if (!stream) {
8577 ERROR("Failed to initialize zstd decompressor\n");
86
- goto out;
78
+ return -EIO;
8779 }
8880
8981 out_buf.size = PAGE_SIZE;
9082 out_buf.dst = squashfs_first_page(output);
9183
92
- do {
93
- if (in_buf.pos == in_buf.size && k < b) {
94
- int avail = min(length, msblk->devblksize - offset);
84
+ for (;;) {
85
+ size_t zstd_err;
9586
87
+ if (in_buf.pos == in_buf.size) {
88
+ const void *data;
89
+ int avail;
90
+
91
+ if (!bio_next_segment(bio, &iter_all)) {
92
+ error = -EIO;
93
+ break;
94
+ }
95
+
96
+ avail = min(length, ((int)bvec->bv_len) - offset);
97
+ data = page_address(bvec->bv_page) + bvec->bv_offset;
9698 length -= avail;
97
- in_buf.src = bh[k]->b_data + offset;
99
+ in_buf.src = data + offset;
98100 in_buf.size = avail;
99101 in_buf.pos = 0;
100102 offset = 0;
....@@ -106,8 +108,8 @@
106108 /* Shouldn't run out of pages
107109 * before stream is done.
108110 */
109
- squashfs_finish_page(output);
110
- goto out;
111
+ error = -EIO;
112
+ break;
111113 }
112114 out_buf.pos = 0;
113115 out_buf.size = PAGE_SIZE;
....@@ -116,29 +118,20 @@
116118 total_out -= out_buf.pos;
117119 zstd_err = ZSTD_decompressStream(stream, &out_buf, &in_buf);
118120 total_out += out_buf.pos; /* add the additional data produced */
121
+ if (zstd_err == 0)
122
+ break;
119123
120
- if (in_buf.pos == in_buf.size && k < b)
121
- put_bh(bh[k++]);
122
- } while (zstd_err != 0 && !ZSTD_isError(zstd_err));
124
+ if (ZSTD_isError(zstd_err)) {
125
+ ERROR("zstd decompression error: %d\n",
126
+ (int)ZSTD_getErrorCode(zstd_err));
127
+ error = -EIO;
128
+ break;
129
+ }
130
+ }
123131
124132 squashfs_finish_page(output);
125133
126
- if (ZSTD_isError(zstd_err)) {
127
- ERROR("zstd decompression error: %d\n",
128
- (int)ZSTD_getErrorCode(zstd_err));
129
- goto out;
130
- }
131
-
132
- if (k < b)
133
- goto out;
134
-
135
- return (int)total_out;
136
-
137
-out:
138
- for (; k < b; k++)
139
- put_bh(bh[k]);
140
-
141
- return -EIO;
134
+ return error ? error : total_out;
142135 }
143136
144137 const struct squashfs_decompressor squashfs_zstd_comp_ops = {