crypto: af_alg: Pin pages rather than ref'ing if appropriate
[linux-block.git] / crypto / af_alg.c
index 5f7252a5b7b44af2915913ef9ac35fddb369b3d5..7caff10df64353fe7bee94c46e283d4edeb04be4 100644 (file)
@@ -533,14 +533,17 @@ static const struct net_proto_family alg_family = {
 
 int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len)
 {
+       struct page **pages = sgl->pages;
        size_t off;
        ssize_t n;
        int npages, i;
 
-       n = iov_iter_get_pages2(iter, sgl->pages, len, ALG_MAX_PAGES, &off);
+       n = iov_iter_extract_pages(iter, &pages, len, ALG_MAX_PAGES, 0, &off);
        if (n < 0)
                return n;
 
+       sgl->need_unpin = iov_iter_extract_will_pin(iter);
+
        npages = DIV_ROUND_UP(off + n, PAGE_SIZE);
        if (WARN_ON(npages == 0))
                return -EINVAL;
@@ -573,8 +576,9 @@ void af_alg_free_sg(struct af_alg_sgl *sgl)
 {
        int i;
 
-       for (i = 0; i < sgl->npages; i++)
-               put_page(sgl->pages[i]);
+       if (sgl->need_unpin)
+               for (i = 0; i < sgl->npages; i++)
+                       unpin_user_page(sgl->pages[i]);
 }
 EXPORT_SYMBOL_GPL(af_alg_free_sg);