crypto: af_alg: Support MSG_SPLICE_PAGES
[platform/kernel/linux-starfive.git] / crypto / af_alg.c
index fd56ccf..9c12530 100644 (file)
@@ -985,7 +985,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
        while (size) {
                struct scatterlist *sg;
                size_t len = size;
-               size_t plen;
+               ssize_t plen;
 
                /* use the existing memory in an allocated page */
                if (ctx->merge) {
@@ -1030,7 +1030,27 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
                if (sgl->cur)
                        sg_unmark_end(sg + sgl->cur - 1);
 
-               if (1 /* TODO check MSG_SPLICE_PAGES */) {
+               if (msg->msg_flags & MSG_SPLICE_PAGES) {
+                       struct sg_table sgtable = {
+                               .sgl            = sg,
+                               .nents          = sgl->cur,
+                               .orig_nents     = sgl->cur,
+                       };
+
+                       plen = extract_iter_to_sg(&msg->msg_iter, len, &sgtable,
+                                                 MAX_SGL_ENTS, 0);
+                       if (plen < 0) {
+                               err = plen;
+                               goto unlock;
+                       }
+
+                       for (; sgl->cur < sgtable.nents; sgl->cur++)
+                               get_page(sg_page(&sg[sgl->cur]));
+                       len -= plen;
+                       ctx->used += plen;
+                       copied += plen;
+                       size -= plen;
+               } else {
                        do {
                                struct page *pg;
                                unsigned int i = sgl->cur;