@@ -1708,7 +1708,7 @@ static struct ubuf_info *msg_zerocopy_alloc(struct sock *sk, size_t size)
17081708 return NULL ;
17091709 }
17101710
1711- uarg -> ubuf .callback = msg_zerocopy_callback ;
1711+ uarg -> ubuf .ops = & msg_zerocopy_ubuf_ops ;
17121712 uarg -> id = ((u32 )atomic_inc_return (& sk -> sk_zckey )) - 1 ;
17131713 uarg -> len = 1 ;
17141714 uarg -> bytelen = size ;
@@ -1734,7 +1734,7 @@ struct ubuf_info *msg_zerocopy_realloc(struct sock *sk, size_t size,
17341734 u32 bytelen , next ;
17351735
17361736 /* there might be non MSG_ZEROCOPY users */
1737- if (uarg -> callback != msg_zerocopy_callback )
1737+ if (uarg -> ops != & msg_zerocopy_ubuf_ops )
17381738 return NULL ;
17391739
17401740 /* realloc only when socket is locked (TCP, UDP cork),
@@ -1845,8 +1845,8 @@ static void __msg_zerocopy_callback(struct ubuf_info_msgzc *uarg)
18451845 sock_put (sk );
18461846}
18471847
1848- void msg_zerocopy_callback (struct sk_buff * skb , struct ubuf_info * uarg ,
1849- bool success )
1848+ static void msg_zerocopy_complete (struct sk_buff * skb , struct ubuf_info * uarg ,
1849+ bool success )
18501850{
18511851 struct ubuf_info_msgzc * uarg_zc = uarg_to_msgzc (uarg );
18521852
@@ -1855,7 +1855,6 @@ void msg_zerocopy_callback(struct sk_buff *skb, struct ubuf_info *uarg,
18551855 if (refcount_dec_and_test (& uarg -> refcnt ))
18561856 __msg_zerocopy_callback (uarg_zc );
18571857}
1858- EXPORT_SYMBOL_GPL (msg_zerocopy_callback );
18591858
18601859void msg_zerocopy_put_abort (struct ubuf_info * uarg , bool have_uref )
18611860{
@@ -1865,22 +1864,34 @@ void msg_zerocopy_put_abort(struct ubuf_info *uarg, bool have_uref)
18651864 uarg_to_msgzc (uarg )-> len -- ;
18661865
18671866 if (have_uref )
1868- msg_zerocopy_callback (NULL , uarg , true);
1867+ msg_zerocopy_complete (NULL , uarg , true);
18691868}
18701869EXPORT_SYMBOL_GPL (msg_zerocopy_put_abort );
18711870
1871+ const struct ubuf_info_ops msg_zerocopy_ubuf_ops = {
1872+ .complete = msg_zerocopy_complete ,
1873+ };
1874+ EXPORT_SYMBOL_GPL (msg_zerocopy_ubuf_ops );
1875+
18721876int skb_zerocopy_iter_stream (struct sock * sk , struct sk_buff * skb ,
18731877 struct msghdr * msg , int len ,
18741878 struct ubuf_info * uarg )
18751879{
18761880 struct ubuf_info * orig_uarg = skb_zcopy (skb );
18771881 int err , orig_len = skb -> len ;
18781882
1879- /* An skb can only point to one uarg. This edge case happens when
1880- * TCP appends to an skb, but zerocopy_realloc triggered a new alloc.
1881- */
1882- if (orig_uarg && uarg != orig_uarg )
1883- return - EEXIST ;
1883+ if (uarg -> ops -> link_skb ) {
1884+ err = uarg -> ops -> link_skb (skb , uarg );
1885+ if (err )
1886+ return err ;
1887+ } else {
1888+ /* An skb can only point to one uarg. This edge case happens
1889+ * when TCP appends to an skb, but zerocopy_realloc triggered
1890+ * a new alloc.
1891+ */
1892+ if (orig_uarg && uarg != orig_uarg )
1893+ return - EEXIST ;
1894+ }
18841895
18851896 err = __zerocopy_sg_from_iter (msg , sk , skb , & msg -> msg_iter , len );
18861897 if (err == - EFAULT || (err == - EMSGSIZE && skb -> len == orig_len )) {
@@ -1894,7 +1905,8 @@ int skb_zerocopy_iter_stream(struct sock *sk, struct sk_buff *skb,
18941905 return err ;
18951906 }
18961907
1897- skb_zcopy_set (skb , uarg , NULL );
1908+ if (!uarg -> ops -> link_skb )
1909+ skb_zcopy_set (skb , uarg , NULL );
18981910 return skb -> len - orig_len ;
18991911}
19001912EXPORT_SYMBOL_GPL (skb_zerocopy_iter_stream );
0 commit comments