diff options
author | Rémi Denis-Courmont <remi.denis-courmont@nokia.com> | 2009-11-08 23:06:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-10 23:54:34 -0500 |
commit | b1704374fd525e50c44e1a03098728f64231a6f5 (patch) | |
tree | 7b86c3d2e32cdfd0a0159c2cc2da3f500a182117 /net/phonet/pep.c | |
parent | 6b0d07ba152893b40f1014a9db8da5aa564aa00e (diff) |
Phonet: allocate and copy for pipe TX without sock lock
Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/phonet/pep.c')
-rw-r--r-- | net/phonet/pep.c | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/net/phonet/pep.c b/net/phonet/pep.c index cbaa1d67d77b..bdc17bdad366 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c | |||
@@ -843,7 +843,7 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
843 | struct msghdr *msg, size_t len) | 843 | struct msghdr *msg, size_t len) |
844 | { | 844 | { |
845 | struct pep_sock *pn = pep_sk(sk); | 845 | struct pep_sock *pn = pep_sk(sk); |
846 | struct sk_buff *skb = NULL; | 846 | struct sk_buff *skb; |
847 | long timeo; | 847 | long timeo; |
848 | int flags = msg->msg_flags; | 848 | int flags = msg->msg_flags; |
849 | int err, done; | 849 | int err, done; |
@@ -851,6 +851,16 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
851 | if (msg->msg_flags & MSG_OOB || !(msg->msg_flags & MSG_EOR)) | 851 | if (msg->msg_flags & MSG_OOB || !(msg->msg_flags & MSG_EOR)) |
852 | return -EOPNOTSUPP; | 852 | return -EOPNOTSUPP; |
853 | 853 | ||
854 | skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len, | ||
855 | flags & MSG_DONTWAIT, &err); | ||
856 | if (!skb) | ||
857 | return -ENOBUFS; | ||
858 | |||
859 | skb_reserve(skb, MAX_PHONET_HEADER + 3); | ||
860 | err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | ||
861 | if (err < 0) | ||
862 | goto outfree; | ||
863 | |||
854 | lock_sock(sk); | 864 | lock_sock(sk); |
855 | timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); | 865 | timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); |
856 | if ((1 << sk->sk_state) & (TCPF_LISTEN|TCPF_CLOSE)) { | 866 | if ((1 << sk->sk_state) & (TCPF_LISTEN|TCPF_CLOSE)) { |
@@ -894,28 +904,13 @@ disabled: | |||
894 | goto disabled; | 904 | goto disabled; |
895 | } | 905 | } |
896 | 906 | ||
897 | if (!skb) { | ||
898 | skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len, | ||
899 | flags & MSG_DONTWAIT, &err); | ||
900 | if (skb == NULL) | ||
901 | goto out; | ||
902 | skb_reserve(skb, MAX_PHONET_HEADER + 3); | ||
903 | |||
904 | if (sk->sk_state != TCP_ESTABLISHED || | ||
905 | !atomic_read(&pn->tx_credits)) | ||
906 | goto disabled; /* sock_alloc_send_skb might sleep */ | ||
907 | } | ||
908 | |||
909 | err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); | ||
910 | if (err < 0) | ||
911 | goto out; | ||
912 | |||
913 | err = pipe_skb_send(sk, skb); | 907 | err = pipe_skb_send(sk, skb); |
914 | if (err >= 0) | 908 | if (err >= 0) |
915 | err = len; /* success! */ | 909 | err = len; /* success! */ |
916 | skb = NULL; | 910 | skb = NULL; |
917 | out: | 911 | out: |
918 | release_sock(sk); | 912 | release_sock(sk); |
913 | outfree: | ||
919 | kfree_skb(skb); | 914 | kfree_skb(skb); |
920 | return err; | 915 | return err; |
921 | } | 916 | } |