diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-11-28 16:39:25 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2015-02-04 01:34:15 -0500 |
commit | 1d10eb2f156f5fc83cf6c7ce60441592e66eadb3 (patch) | |
tree | b330398099f3da04395326250a747399495dc906 /crypto/af_alg.c | |
parent | 31a25fae85956e3a9c778141d29e5e803fb0b124 (diff) |
crypto: switch af_alg_make_sg() to iov_iter
With that, all ->sendmsg() instances are converted to iov_iter primitives
and are agnostic wrt the kind of iov_iter they are working with.
So's the last remaining ->recvmsg() instance that wasn't kind-agnostic yet.
All ->sendmsg() and ->recvmsg() advance ->msg_iter by the amount actually
copied and none of them modifies the underlying iovec, etc.
Cc: linux-crypto@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'crypto/af_alg.c')
-rw-r--r-- | crypto/af_alg.c | 40 |
1 files changed, 11 insertions, 29 deletions
diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 4665b79c729a..eb78fe8a60c8 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -338,49 +338,31 @@ static const struct net_proto_family alg_family = { .owner = THIS_MODULE, }; -int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, - int write) +int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len) { - unsigned long from = (unsigned long)addr; - unsigned long npages; - unsigned off; - int err; - int i; - - err = -EFAULT; - if (!access_ok(write ? VERIFY_READ : VERIFY_WRITE, addr, len)) - goto out; - - off = from & ~PAGE_MASK; - npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; - if (npages > ALG_MAX_PAGES) - npages = ALG_MAX_PAGES; + size_t off; + ssize_t n; + int npages, i; - err = get_user_pages_fast(from, npages, write, sgl->pages); - if (err < 0) - goto out; + n = iov_iter_get_pages(iter, sgl->pages, len, ALG_MAX_PAGES, &off); + if (n < 0) + return n; - npages = err; - err = -EINVAL; + npages = PAGE_ALIGN(off + n); if (WARN_ON(npages == 0)) - goto out; - - err = 0; + return -EINVAL; sg_init_table(sgl->sg, npages); - for (i = 0; i < npages; i++) { + for (i = 0, len = n; i < npages; i++) { int plen = min_t(int, len, PAGE_SIZE - off); sg_set_page(sgl->sg + i, sgl->pages[i], plen, off); off = 0; len -= plen; - err += plen; } - -out: - return err; + return n; } EXPORT_SYMBOL_GPL(af_alg_make_sg); |