diff options
Diffstat (limited to 'crypto/af_alg.c')
-rw-r--r-- | crypto/af_alg.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 7f8b7edcadca..26089d182cb7 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -358,8 +358,8 @@ int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len) npages = (off + n + PAGE_SIZE - 1) >> PAGE_SHIFT; if (WARN_ON(npages == 0)) return -EINVAL; - - sg_init_table(sgl->sg, npages); + /* Add one extra for linking */ + sg_init_table(sgl->sg, npages + 1); for (i = 0, len = n; i < npages; i++) { int plen = min_t(int, len, PAGE_SIZE - off); @@ -369,18 +369,26 @@ int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len) off = 0; len -= plen; } + sg_mark_end(sgl->sg + npages - 1); + sgl->npages = npages; + return n; } EXPORT_SYMBOL_GPL(af_alg_make_sg); +void af_alg_link_sg(struct af_alg_sgl *sgl_prev, struct af_alg_sgl *sgl_new) +{ + sg_unmark_end(sgl_prev->sg + sgl_prev->npages - 1); + sg_chain(sgl_prev->sg, sgl_prev->npages + 1, sgl_new->sg); +} +EXPORT_SYMBOL(af_alg_link_sg); + void af_alg_free_sg(struct af_alg_sgl *sgl) { int i; - i = 0; - do { + for (i = 0; i < sgl->npages; i++) put_page(sgl->pages[i]); - } while (!sg_is_last(sgl->sg + (i++))); } EXPORT_SYMBOL_GPL(af_alg_free_sg); |