@@ -859,6 +859,12 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
859859 }
860860
861861 lock_sock (sk );
862+ if (ctx -> write ) {
863+ release_sock (sk );
864+ return - EBUSY ;
865+ }
866+ ctx -> write = true;
867+
862868 if (ctx -> init && !ctx -> more ) {
863869 if (ctx -> used ) {
864870 err = - EINVAL ;
@@ -908,6 +914,8 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
908914 continue ;
909915 }
910916
917+ ctx -> merge = 0 ;
918+
911919 if (!af_alg_writable (sk )) {
912920 err = af_alg_wait_for_wmem (sk , msg -> msg_flags );
913921 if (err )
@@ -927,35 +935,38 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
927935 if (sgl -> cur )
928936 sg_unmark_end (sg + sgl -> cur - 1 );
929937
930- do {
931- struct page * pg ;
932- unsigned int i = sgl -> cur ;
938+ if (1 /* TODO check MSG_SPLICE_PAGES */ ) {
939+ do {
940+ struct page * pg ;
941+ unsigned int i = sgl -> cur ;
933942
934- plen = min_t (size_t , len , PAGE_SIZE );
943+ plen = min_t (size_t , len , PAGE_SIZE );
935944
936- pg = alloc_page (GFP_KERNEL );
937- if (!pg ) {
938- err = - ENOMEM ;
939- goto unlock ;
940- }
945+ pg = alloc_page (GFP_KERNEL );
946+ if (!pg ) {
947+ err = - ENOMEM ;
948+ goto unlock ;
949+ }
941950
942- sg_assign_page (sg + i , pg );
951+ sg_assign_page (sg + i , pg );
943952
944- err = memcpy_from_msg (page_address (sg_page (sg + i )),
945- msg , plen );
946- if (err ) {
947- __free_page (sg_page (sg + i ));
948- sg_assign_page (sg + i , NULL );
949- goto unlock ;
950- }
953+ err = memcpy_from_msg (
954+ page_address (sg_page (sg + i )),
955+ msg , plen );
956+ if (err ) {
957+ __free_page (sg_page (sg + i ));
958+ sg_assign_page (sg + i , NULL );
959+ goto unlock ;
960+ }
951961
952- sg [i ].length = plen ;
953- len -= plen ;
954- ctx -> used += plen ;
955- copied += plen ;
956- size -= plen ;
957- sgl -> cur ++ ;
958- } while (len && sgl -> cur < MAX_SGL_ENTS );
962+ sg [i ].length = plen ;
963+ len -= plen ;
964+ ctx -> used += plen ;
965+ copied += plen ;
966+ size -= plen ;
967+ sgl -> cur ++ ;
968+ } while (len && sgl -> cur < MAX_SGL_ENTS );
969+ }
959970
960971 if (!size )
961972 sg_mark_end (sg + sgl -> cur - 1 );
@@ -969,6 +980,7 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
969980
970981unlock :
971982 af_alg_data_wakeup (sk );
983+ ctx -> write = false;
972984 release_sock (sk );
973985
974986 return copied ?: err ;
@@ -988,53 +1000,17 @@ EXPORT_SYMBOL_GPL(af_alg_sendmsg);
9881000ssize_t af_alg_sendpage (struct socket * sock , struct page * page ,
9891001 int offset , size_t size , int flags )
9901002{
991- struct sock * sk = sock -> sk ;
992- struct alg_sock * ask = alg_sk (sk );
993- struct af_alg_ctx * ctx = ask -> private ;
994- struct af_alg_tsgl * sgl ;
995- int err = - EINVAL ;
1003+ struct bio_vec bvec ;
1004+ struct msghdr msg = {
1005+ .msg_flags = flags | MSG_SPLICE_PAGES ,
1006+ };
9961007
9971008 if (flags & MSG_SENDPAGE_NOTLAST )
998- flags |= MSG_MORE ;
999-
1000- lock_sock (sk );
1001- if (!ctx -> more && ctx -> used )
1002- goto unlock ;
1003-
1004- if (!size )
1005- goto done ;
1006-
1007- if (!af_alg_writable (sk )) {
1008- err = af_alg_wait_for_wmem (sk , flags );
1009- if (err )
1010- goto unlock ;
1011- }
1012-
1013- err = af_alg_alloc_tsgl (sk );
1014- if (err )
1015- goto unlock ;
1016-
1017- ctx -> merge = 0 ;
1018- sgl = list_entry (ctx -> tsgl_list .prev , struct af_alg_tsgl , list );
1019-
1020- if (sgl -> cur )
1021- sg_unmark_end (sgl -> sg + sgl -> cur - 1 );
1022-
1023- sg_mark_end (sgl -> sg + sgl -> cur );
1024-
1025- get_page (page );
1026- sg_set_page (sgl -> sg + sgl -> cur , page , size , offset );
1027- sgl -> cur ++ ;
1028- ctx -> used += size ;
1029-
1030- done :
1031- ctx -> more = flags & MSG_MORE ;
1032-
1033- unlock :
1034- af_alg_data_wakeup (sk );
1035- release_sock (sk );
1009+ msg .msg_flags |= MSG_MORE ;
10361010
1037- return err ?: size ;
1011+ bvec_set_page (& bvec , page , size , offset );
1012+ iov_iter_bvec (& msg .msg_iter , ITER_SOURCE , & bvec , 1 , size );
1013+ return sock_sendmsg (sock , & msg );
10381014}
10391015EXPORT_SYMBOL_GPL (af_alg_sendpage );
10401016
0 commit comments