summaryrefslogtreecommitdiff
path: root/crypto/scompress.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2025-03-15 18:30:40 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2025-03-21 17:35:26 +0800
commit8a6771cda3f48a4d954647d69ff0094346db6191 (patch)
treeda7a3debcf41d3f1cef1e8e25368935b299d197f /crypto/scompress.c
parentdfd3bc6977e8b99458169c19cd703d34ffa86acc (diff)
crypto: acomp - Add support for folios
For many users, it's easier to supply a folio rather than an SG list since they already have them. Add support for folios to the acomp interface. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/scompress.c')
-rw-r--r--crypto/scompress.c72
1 files changed, 46 insertions, 26 deletions
diff --git a/crypto/scompress.c b/crypto/scompress.c
index ba9b22ba53fe..f85cc0d83164 100644
--- a/crypto/scompress.c
+++ b/crypto/scompress.c
@@ -177,9 +177,10 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
unsigned int slen = req->slen;
unsigned int dlen = req->dlen;
struct page *spage, *dpage;
- unsigned int soff, doff;
unsigned int n;
const u8 *src;
+ size_t soff;
+ size_t doff;
u8 *dst;
int ret;
@@ -192,38 +193,57 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
if (acomp_request_src_isvirt(req))
src = req->svirt;
else {
- soff = req->src->offset;
- spage = nth_page(sg_page(req->src), soff / PAGE_SIZE);
- soff = offset_in_page(soff);
-
- n = slen / PAGE_SIZE;
- n += (offset_in_page(slen) + soff - 1) / PAGE_SIZE;
- if (slen <= req->src->length &&
- (!PageHighMem(nth_page(spage, n)) ||
- size_add(soff, slen) <= PAGE_SIZE))
+ src = scratch->src;
+ do {
+ if (acomp_request_src_isfolio(req)) {
+ spage = folio_page(req->sfolio, 0);
+ soff = req->soff;
+ } else if (slen <= req->src->length) {
+ spage = sg_page(req->src);
+ soff = req->src->offset;
+ } else
+ break;
+
+ spage = nth_page(spage, soff / PAGE_SIZE);
+ soff = offset_in_page(soff);
+
+ n = slen / PAGE_SIZE;
+ n += (offset_in_page(slen) + soff - 1) / PAGE_SIZE;
+ if (PageHighMem(nth_page(spage, n)) &&
+ size_add(soff, slen) > PAGE_SIZE)
+ break;
src = kmap_local_page(spage) + soff;
- else
- src = scratch->src;
+ } while (0);
}
if (acomp_request_dst_isvirt(req))
dst = req->dvirt;
else {
- doff = req->dst->offset;
- dpage = nth_page(sg_page(req->dst), doff / PAGE_SIZE);
- doff = offset_in_page(doff);
-
- n = dlen / PAGE_SIZE;
- n += (offset_in_page(dlen) + doff - 1) / PAGE_SIZE;
- if (dlen <= req->dst->length &&
- (!PageHighMem(nth_page(dpage, n)) ||
- size_add(doff, dlen) <= PAGE_SIZE))
+ unsigned int max = SCOMP_SCRATCH_SIZE;
+
+ dst = scratch->dst;
+ do {
+ if (acomp_request_dst_isfolio(req)) {
+ dpage = folio_page(req->dfolio, 0);
+ doff = req->doff;
+ } else if (dlen <= req->dst->length) {
+ dpage = sg_page(req->dst);
+ doff = req->dst->offset;
+ } else
+ break;
+
+ dpage = nth_page(dpage, doff / PAGE_SIZE);
+ doff = offset_in_page(doff);
+
+ n = dlen / PAGE_SIZE;
+ n += (offset_in_page(dlen) + doff - 1) / PAGE_SIZE;
+ if (PageHighMem(dpage + n) &&
+ size_add(doff, dlen) > PAGE_SIZE)
+ break;
dst = kmap_local_page(dpage) + doff;
- else {
- if (dlen > SCOMP_SCRATCH_SIZE)
- dlen = SCOMP_SCRATCH_SIZE;
- dst = scratch->dst;
- }
+ max = dlen;
+ } while (0);
+ dlen = min(dlen, max);
}
spin_lock_bh(&scratch->lock);