Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ubifs: Use ACOMP_REQUEST_CLONE

Switch to the new acomp API where stacks requests are used by
default and a dynamic request is only allocted when necessary.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Herbert Xu e87e95d8 097c432c

+116 -135
+116 -135
fs/ubifs/compress.c
··· 19 19 #include <linux/highmem.h> 20 20 #include "ubifs.h" 21 21 22 + union ubifs_in_ptr { 23 + const void *buf; 24 + struct folio *folio; 25 + }; 26 + 22 27 /* Fake description object for the "none" compressor */ 23 28 static struct ubifs_compressor none_compr = { 24 29 .compr_type = UBIFS_COMPR_NONE, ··· 73 68 /* All UBIFS compressors */ 74 69 struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT]; 75 70 76 - static int ubifs_compress_req(const struct ubifs_info *c, 77 - struct acomp_req *req, 78 - void *out_buf, int *out_len, 79 - const char *compr_name) 71 + static void ubifs_compress_common(int *compr_type, union ubifs_in_ptr in_ptr, 72 + size_t in_offset, int in_len, bool in_folio, 73 + void *out_buf, int *out_len) 80 74 { 81 - struct crypto_wait wait; 82 - int in_len = req->slen; 75 + struct ubifs_compressor *compr = ubifs_compressors[*compr_type]; 83 76 int dlen = *out_len; 84 77 int err; 85 78 79 + if (*compr_type == UBIFS_COMPR_NONE) 80 + goto no_compr; 81 + 82 + /* If the input data is small, do not even try to compress it */ 83 + if (in_len < UBIFS_MIN_COMPR_LEN) 84 + goto no_compr; 85 + 86 86 dlen = min(dlen, in_len - UBIFS_MIN_COMPRESS_DIFF); 87 87 88 - crypto_init_wait(&wait); 89 - acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 90 - crypto_req_done, &wait); 91 - acomp_request_set_dst_dma(req, out_buf, dlen); 92 - err = crypto_acomp_compress(req); 93 - err = crypto_wait_req(err, &wait); 94 - *out_len = req->dlen; 95 - acomp_request_free(req); 88 + do { 89 + ACOMP_REQUEST_ON_STACK(req, compr->cc); 90 + DECLARE_CRYPTO_WAIT(wait); 96 91 97 - return err; 92 + acomp_request_set_callback(req, 0, NULL, NULL); 93 + if (in_folio) 94 + acomp_request_set_src_folio(req, in_ptr.folio, 95 + in_offset, in_len); 96 + else 97 + acomp_request_set_src_dma(req, in_ptr.buf, in_len); 98 + acomp_request_set_dst_dma(req, out_buf, dlen); 99 + err = crypto_acomp_compress(req); 100 + dlen = req->dlen; 101 + if (err != -EAGAIN) 102 + break; 103 + 104 + req = ACOMP_REQUEST_CLONE(req, GFP_NOFS | __GFP_NOWARN); 105 + acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 106 + crypto_req_done, &wait); 107 + err = crypto_acomp_compress(req); 108 + err = crypto_wait_req(err, &wait); 109 + dlen = req->dlen; 110 + acomp_request_free(req); 111 + } while (0); 112 + 113 + *out_len = dlen; 114 + if (err) 115 + goto no_compr; 116 + 117 + return; 118 + 119 + no_compr: 120 + if (in_folio) 121 + memcpy_from_folio(out_buf, in_ptr.folio, in_offset, in_len); 122 + else 123 + memcpy(out_buf, in_ptr.buf, in_len); 124 + *out_len = in_len; 125 + *compr_type = UBIFS_COMPR_NONE; 98 126 } 99 127 100 128 /** ··· 152 114 void ubifs_compress(const struct ubifs_info *c, const void *in_buf, 153 115 int in_len, void *out_buf, int *out_len, int *compr_type) 154 116 { 155 - int err; 156 - struct ubifs_compressor *compr = ubifs_compressors[*compr_type]; 117 + union ubifs_in_ptr in_ptr = { .buf = in_buf }; 157 118 158 - if (*compr_type == UBIFS_COMPR_NONE) 159 - goto no_compr; 160 - 161 - /* If the input data is small, do not even try to compress it */ 162 - if (in_len < UBIFS_MIN_COMPR_LEN) 163 - goto no_compr; 164 - 165 - { 166 - ACOMP_REQUEST_ALLOC(req, compr->cc, GFP_NOFS | __GFP_NOWARN); 167 - 168 - acomp_request_set_src_dma(req, in_buf, in_len); 169 - err = ubifs_compress_req(c, req, out_buf, out_len, compr->name); 170 - } 171 - 172 - if (err) 173 - goto no_compr; 174 - 175 - return; 176 - 177 - no_compr: 178 - memcpy(out_buf, in_buf, in_len); 179 - *out_len = in_len; 180 - *compr_type = UBIFS_COMPR_NONE; 119 + ubifs_compress_common(compr_type, in_ptr, 0, in_len, false, 120 + out_buf, out_len); 181 121 } 182 122 183 123 /** ··· 182 166 size_t in_offset, int in_len, void *out_buf, 183 167 int *out_len, int *compr_type) 184 168 { 185 - int err; 186 - struct ubifs_compressor *compr = ubifs_compressors[*compr_type]; 169 + union ubifs_in_ptr in_ptr = { .folio = in_folio }; 187 170 188 - if (*compr_type == UBIFS_COMPR_NONE) 189 - goto no_compr; 190 - 191 - /* If the input data is small, do not even try to compress it */ 192 - if (in_len < UBIFS_MIN_COMPR_LEN) 193 - goto no_compr; 194 - 195 - { 196 - ACOMP_REQUEST_ALLOC(req, compr->cc, GFP_NOFS | __GFP_NOWARN); 197 - 198 - acomp_request_set_src_folio(req, in_folio, in_offset, in_len); 199 - err = ubifs_compress_req(c, req, out_buf, out_len, compr->name); 200 - } 201 - 202 - if (err) 203 - goto no_compr; 204 - 205 - return; 206 - 207 - no_compr: 208 - memcpy_from_folio(out_buf, in_folio, in_offset, in_len); 209 - *out_len = in_len; 210 - *compr_type = UBIFS_COMPR_NONE; 171 + ubifs_compress_common(compr_type, in_ptr, in_offset, in_len, true, 172 + out_buf, out_len); 211 173 } 212 174 213 - static int ubifs_decompress_req(const struct ubifs_info *c, 214 - struct acomp_req *req, 215 - const void *in_buf, int in_len, int *out_len, 216 - const char *compr_name) 175 + static int ubifs_decompress_common(const struct ubifs_info *c, 176 + const void *in_buf, int in_len, 177 + void *out_ptr, size_t out_offset, 178 + int *out_len, bool out_folio, 179 + int compr_type) 217 180 { 218 - struct crypto_wait wait; 181 + struct ubifs_compressor *compr; 182 + int dlen = *out_len; 219 183 int err; 220 184 221 - crypto_init_wait(&wait); 222 - acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 223 - crypto_req_done, &wait); 224 - acomp_request_set_src_dma(req, in_buf, in_len); 225 - err = crypto_acomp_decompress(req); 226 - err = crypto_wait_req(err, &wait); 227 - *out_len = req->dlen; 185 + if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) { 186 + ubifs_err(c, "invalid compression type %d", compr_type); 187 + return -EINVAL; 188 + } 228 189 190 + compr = ubifs_compressors[compr_type]; 191 + 192 + if (unlikely(!compr->capi_name)) { 193 + ubifs_err(c, "%s compression is not compiled in", compr->name); 194 + return -EINVAL; 195 + } 196 + 197 + if (compr_type == UBIFS_COMPR_NONE) { 198 + if (out_folio) 199 + memcpy_to_folio(out_ptr, out_offset, in_buf, in_len); 200 + else 201 + memcpy(out_ptr, in_buf, in_len); 202 + *out_len = in_len; 203 + return 0; 204 + } 205 + 206 + do { 207 + ACOMP_REQUEST_ON_STACK(req, compr->cc); 208 + DECLARE_CRYPTO_WAIT(wait); 209 + 210 + acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, 211 + crypto_req_done, &wait); 212 + acomp_request_set_src_dma(req, in_buf, in_len); 213 + if (out_folio) 214 + acomp_request_set_dst_folio(req, out_ptr, out_offset, 215 + dlen); 216 + else 217 + acomp_request_set_dst_dma(req, out_ptr, dlen); 218 + err = crypto_acomp_decompress(req); 219 + dlen = req->dlen; 220 + if (err != -EAGAIN) 221 + break; 222 + 223 + req = ACOMP_REQUEST_CLONE(req, GFP_NOFS | __GFP_NOWARN); 224 + err = crypto_acomp_decompress(req); 225 + err = crypto_wait_req(err, &wait); 226 + dlen = req->dlen; 227 + acomp_request_free(req); 228 + } while (0); 229 + 230 + *out_len = dlen; 229 231 if (err) 230 232 ubifs_err(c, "cannot decompress %d bytes, compressor %s, error %d", 231 - in_len, compr_name, err); 232 - 233 - acomp_request_free(req); 233 + in_len, compr->name, err); 234 234 235 235 return err; 236 236 } ··· 267 235 int ubifs_decompress(const struct ubifs_info *c, const void *in_buf, 268 236 int in_len, void *out_buf, int *out_len, int compr_type) 269 237 { 270 - struct ubifs_compressor *compr; 271 - 272 - if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) { 273 - ubifs_err(c, "invalid compression type %d", compr_type); 274 - return -EINVAL; 275 - } 276 - 277 - compr = ubifs_compressors[compr_type]; 278 - 279 - if (unlikely(!compr->capi_name)) { 280 - ubifs_err(c, "%s compression is not compiled in", compr->name); 281 - return -EINVAL; 282 - } 283 - 284 - if (compr_type == UBIFS_COMPR_NONE) { 285 - memcpy(out_buf, in_buf, in_len); 286 - *out_len = in_len; 287 - return 0; 288 - } 289 - 290 - { 291 - ACOMP_REQUEST_ALLOC(req, compr->cc, GFP_NOFS | __GFP_NOWARN); 292 - 293 - acomp_request_set_dst_dma(req, out_buf, *out_len); 294 - return ubifs_decompress_req(c, req, in_buf, in_len, out_len, 295 - compr->name); 296 - } 238 + return ubifs_decompress_common(c, in_buf, in_len, out_buf, 0, out_len, 239 + false, compr_type); 297 240 } 298 241 299 242 /** ··· 290 283 int in_len, struct folio *out_folio, 291 284 size_t out_offset, int *out_len, int compr_type) 292 285 { 293 - struct ubifs_compressor *compr; 294 - 295 - if (unlikely(compr_type < 0 || compr_type >= UBIFS_COMPR_TYPES_CNT)) { 296 - ubifs_err(c, "invalid compression type %d", compr_type); 297 - return -EINVAL; 298 - } 299 - 300 - compr = ubifs_compressors[compr_type]; 301 - 302 - if (unlikely(!compr->capi_name)) { 303 - ubifs_err(c, "%s compression is not compiled in", compr->name); 304 - return -EINVAL; 305 - } 306 - 307 - if (compr_type == UBIFS_COMPR_NONE) { 308 - memcpy_to_folio(out_folio, out_offset, in_buf, in_len); 309 - *out_len = in_len; 310 - return 0; 311 - } 312 - 313 - { 314 - ACOMP_REQUEST_ALLOC(req, compr->cc, GFP_NOFS | __GFP_NOWARN); 315 - 316 - acomp_request_set_dst_folio(req, out_folio, out_offset, 317 - *out_len); 318 - return ubifs_decompress_req(c, req, in_buf, in_len, out_len, 319 - compr->name); 320 - } 286 + return ubifs_decompress_common(c, in_buf, in_len, out_folio, 287 + out_offset, out_len, true, compr_type); 321 288 } 322 289 323 290 /**