@@ -178,8 +178,9 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
178
178
unsigned int dlen = req -> dlen ;
179
179
struct page * spage , * dpage ;
180
180
unsigned int soff , doff ;
181
- void * src , * dst ;
182
181
unsigned int n ;
182
+ const u8 * src ;
183
+ u8 * dst ;
183
184
int ret ;
184
185
185
186
if (!req -> src || !slen )
@@ -188,37 +189,47 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
188
189
if (!req -> dst || !dlen )
189
190
return - EINVAL ;
190
191
191
- soff = req -> src -> offset ;
192
- spage = nth_page (sg_page (req -> src ), soff / PAGE_SIZE );
193
- soff = offset_in_page (soff );
194
-
195
- n = slen / PAGE_SIZE ;
196
- n += (offset_in_page (slen ) + soff - 1 ) / PAGE_SIZE ;
197
- if (slen <= req -> src -> length && (!PageHighMem (nth_page (spage , n )) ||
198
- size_add (soff , slen ) <= PAGE_SIZE ))
199
- src = kmap_local_page (spage ) + soff ;
200
- else
201
- src = scratch -> src ;
202
-
203
- doff = req -> dst -> offset ;
204
- dpage = nth_page (sg_page (req -> dst ), doff / PAGE_SIZE );
205
- doff = offset_in_page (doff );
192
+ if (acomp_request_src_isvirt (req ))
193
+ src = req -> svirt ;
194
+ else {
195
+ soff = req -> src -> offset ;
196
+ spage = nth_page (sg_page (req -> src ), soff / PAGE_SIZE );
197
+ soff = offset_in_page (soff );
198
+
199
+ n = slen / PAGE_SIZE ;
200
+ n += (offset_in_page (slen ) + soff - 1 ) / PAGE_SIZE ;
201
+ if (slen <= req -> src -> length &&
202
+ (!PageHighMem (nth_page (spage , n )) ||
203
+ size_add (soff , slen ) <= PAGE_SIZE ))
204
+ src = kmap_local_page (spage ) + soff ;
205
+ else
206
+ src = scratch -> src ;
207
+ }
206
208
207
- n = dlen / PAGE_SIZE ;
208
- n += (offset_in_page (dlen ) + doff - 1 ) / PAGE_SIZE ;
209
- if (dlen <= req -> dst -> length && (!PageHighMem (nth_page (dpage , n )) ||
210
- size_add (doff , dlen ) <= PAGE_SIZE ))
211
- dst = kmap_local_page (dpage ) + doff ;
209
+ if (acomp_request_dst_isvirt (req ))
210
+ dst = req -> dvirt ;
212
211
else {
213
- if (dlen > SCOMP_SCRATCH_SIZE )
214
- dlen = SCOMP_SCRATCH_SIZE ;
215
- dst = scratch -> dst ;
212
+ doff = req -> dst -> offset ;
213
+ dpage = nth_page (sg_page (req -> dst ), doff / PAGE_SIZE );
214
+ doff = offset_in_page (doff );
215
+
216
+ n = dlen / PAGE_SIZE ;
217
+ n += (offset_in_page (dlen ) + doff - 1 ) / PAGE_SIZE ;
218
+ if (dlen <= req -> dst -> length &&
219
+ (!PageHighMem (nth_page (dpage , n )) ||
220
+ size_add (doff , dlen ) <= PAGE_SIZE ))
221
+ dst = kmap_local_page (dpage ) + doff ;
222
+ else {
223
+ if (dlen > SCOMP_SCRATCH_SIZE )
224
+ dlen = SCOMP_SCRATCH_SIZE ;
225
+ dst = scratch -> dst ;
226
+ }
216
227
}
217
228
218
229
spin_lock_bh (& scratch -> lock );
219
230
220
231
if (src == scratch -> src )
221
- memcpy_from_sglist (src , req -> src , 0 , slen );
232
+ memcpy_from_sglist (scratch -> src , req -> src , 0 , slen );
222
233
223
234
stream = raw_cpu_ptr (crypto_scomp_alg (scomp )-> stream );
224
235
spin_lock (& stream -> lock );
@@ -237,7 +248,7 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
237
248
238
249
req -> dlen = dlen ;
239
250
240
- if (dst != scratch -> dst ) {
251
+ if (! acomp_request_dst_isvirt ( req ) && dst != scratch -> dst ) {
241
252
kunmap_local (dst );
242
253
dlen += doff ;
243
254
for (;;) {
@@ -248,20 +259,34 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
248
259
dpage = nth_page (dpage , 1 );
249
260
}
250
261
}
251
- if (src != scratch -> src )
262
+ if (! acomp_request_src_isvirt ( req ) && src != scratch -> src )
252
263
kunmap_local (src );
253
264
254
265
return ret ;
255
266
}
256
267
268
+ static int scomp_acomp_chain (struct acomp_req * req , int dir )
269
+ {
270
+ struct acomp_req * r2 ;
271
+ int err ;
272
+
273
+ err = scomp_acomp_comp_decomp (req , dir );
274
+ req -> base .err = err ;
275
+
276
+ list_for_each_entry (r2 , & req -> base .list , base .list )
277
+ r2 -> base .err = scomp_acomp_comp_decomp (r2 , dir );
278
+
279
+ return err ;
280
+ }
281
+
257
282
static int scomp_acomp_compress (struct acomp_req * req )
258
283
{
259
- return scomp_acomp_comp_decomp (req , 1 );
284
+ return scomp_acomp_chain (req , 1 );
260
285
}
261
286
262
287
static int scomp_acomp_decompress (struct acomp_req * req )
263
288
{
264
- return scomp_acomp_comp_decomp (req , 0 );
289
+ return scomp_acomp_chain (req , 0 );
265
290
}
266
291
267
292
static void crypto_exit_scomp_ops_async (struct crypto_tfm * tfm )
@@ -322,12 +347,21 @@ static const struct crypto_type crypto_scomp_type = {
322
347
.tfmsize = offsetof(struct crypto_scomp , base ),
323
348
};
324
349
325
- int crypto_register_scomp (struct scomp_alg * alg )
350
+ static void scomp_prepare_alg (struct scomp_alg * alg )
326
351
{
327
352
struct crypto_alg * base = & alg -> calg .base ;
328
353
329
354
comp_prepare_alg (& alg -> calg );
330
355
356
+ base -> cra_flags |= CRYPTO_ALG_REQ_CHAIN ;
357
+ }
358
+
359
+ int crypto_register_scomp (struct scomp_alg * alg )
360
+ {
361
+ struct crypto_alg * base = & alg -> calg .base ;
362
+
363
+ scomp_prepare_alg (alg );
364
+
331
365
base -> cra_type = & crypto_scomp_type ;
332
366
base -> cra_flags |= CRYPTO_ALG_TYPE_SCOMPRESS ;
333
367
0 commit comments