diff options
Diffstat (limited to 'net/kcm/kcmsock.c')
-rw-r--r-- | net/kcm/kcmsock.c | 32 |
1 files changed, 13 insertions, 19 deletions
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index 1184d40167b8..24aec295a51c 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c @@ -627,7 +627,8 @@ retry: skb = txm->frag_skb; } - if (WARN_ON(!skb_shinfo(skb)->nr_frags)) { + if (WARN_ON(!skb_shinfo(skb)->nr_frags) || + WARN_ON_ONCE(!skb_frag_page(&skb_shinfo(skb)->frags[0]))) { ret = -EINVAL; goto out; } @@ -637,8 +638,8 @@ retry: msize += skb_frag_size(&skb_shinfo(skb)->frags[i]); iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, - skb_shinfo(skb)->frags, skb_shinfo(skb)->nr_frags, - msize); + (const struct bio_vec *)skb_shinfo(skb)->frags, + skb_shinfo(skb)->nr_frags, msize); iov_iter_advance(&msg.msg_iter, txm->frag_offset); do { @@ -754,6 +755,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) !(msg->msg_flags & MSG_MORE) : !!(msg->msg_flags & MSG_EOR); int err = -EPIPE; + mutex_lock(&kcm->tx_mutex); lock_sock(sk); /* Per tcp_sendmsg this should be in poll */ @@ -925,6 +927,7 @@ partial_message: KCM_STATS_ADD(kcm->stats.tx_bytes, copied); release_sock(sk); + mutex_unlock(&kcm->tx_mutex); return copied; out_error: @@ -950,6 +953,7 @@ out_error: sk->sk_write_space(sk); release_sock(sk); + mutex_unlock(&kcm->tx_mutex); return err; } @@ -1152,10 +1156,11 @@ static int kcm_getsockopt(struct socket *sock, int level, int optname, if (get_user(len, optlen)) return -EFAULT; - len = min_t(unsigned int, len, sizeof(int)); if (len < 0) return -EINVAL; + len = min_t(unsigned int, len, sizeof(int)); + switch (optname) { case KCM_RECV_DISABLE: val = kcm->rx_disabled; @@ -1202,6 +1207,7 @@ static void init_kcm_sock(struct kcm_sock *kcm, struct kcm_mux *mux) spin_unlock_bh(&mux->lock); INIT_WORK(&kcm->tx_work, kcm_tx_work); + mutex_init(&kcm->tx_mutex); spin_lock_bh(&mux->rx_lock); kcm_rcv_ready(kcm); @@ -1578,14 +1584,6 @@ static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return err; } -static void free_mux(struct rcu_head *rcu) -{ - struct kcm_mux *mux = container_of(rcu, - struct kcm_mux, rcu); - - kmem_cache_free(kcm_muxp, mux); -} - static void release_mux(struct kcm_mux *mux) { struct kcm_net *knet = mux->knet; @@ -1613,7 +1611,7 @@ static void release_mux(struct kcm_mux *mux) knet->count--; mutex_unlock(&knet->mutex); - call_rcu(&mux->rcu, free_mux); + kfree_rcu(mux, rcu); } static void kcm_done(struct kcm_sock *kcm) @@ -1877,15 +1875,11 @@ static int __init kcm_init(void) { int err = -ENOMEM; - kcm_muxp = kmem_cache_create("kcm_mux_cache", - sizeof(struct kcm_mux), 0, - SLAB_HWCACHE_ALIGN, NULL); + kcm_muxp = KMEM_CACHE(kcm_mux, SLAB_HWCACHE_ALIGN); if (!kcm_muxp) goto fail; - kcm_psockp = kmem_cache_create("kcm_psock_cache", - sizeof(struct kcm_psock), 0, - SLAB_HWCACHE_ALIGN, NULL); + kcm_psockp = KMEM_CACHE(kcm_psock, SLAB_HWCACHE_ALIGN); if (!kcm_psockp) goto fail; |