uarg->callback(NULL, uarg, true);
 }
 
+static inline void skb_zcopy_put_abort(struct ubuf_info *uarg, bool have_uref)
+{
+       if (uarg) {
+               if (uarg->callback == sock_zerocopy_callback)
+                       sock_zerocopy_put_abort(uarg, have_uref);
+               else if (have_uref)
+                       skb_zcopy_put(uarg);
+       }
+}
+
 /* Release a reference on a zerocopy structure */
 static inline void skb_zcopy_clear(struct sk_buff *skb, bool zerocopy_success)
 {
 
 
 void sock_zerocopy_put_abort(struct ubuf_info *uarg, bool have_uref)
 {
-       if (uarg) {
-               struct sock *sk = skb_from_uarg(uarg)->sk;
+       struct sock *sk = skb_from_uarg(uarg)->sk;
 
-               atomic_dec(&sk->sk_zckey);
-               uarg->len--;
+       atomic_dec(&sk->sk_zckey);
+       uarg->len--;
 
-               if (have_uref)
-                       skb_zcopy_put(uarg);
-       }
+       if (have_uref)
+               sock_zerocopy_callback(NULL, uarg, true);
 }
 EXPORT_SYMBOL_GPL(sock_zerocopy_put_abort);
 
 
 error_efault:
        err = -EFAULT;
 error:
-       if (uarg)
-               sock_zerocopy_put_abort(uarg, extra_uref);
+       skb_zcopy_put_abort(uarg, extra_uref);
        cork->length -= length;
        IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTDISCARDS);
        refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);
 
        if (copied + copied_syn)
                goto out;
 out_err:
-       sock_zerocopy_put_abort(uarg, true);
+       skb_zcopy_put_abort(uarg, true);
        err = sk_stream_error(sk, flags, err);
        /* make sure we wake any epoll edge trigger waiter */
        if (unlikely(tcp_rtx_and_write_queues_empty(sk) && err == -EAGAIN)) {
 
 error_efault:
        err = -EFAULT;
 error:
-       if (uarg)
-               sock_zerocopy_put_abort(uarg, extra_uref);
+       skb_zcopy_put_abort(uarg, extra_uref);
        cork->length -= length;
        IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
        refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc);