Skip to content

Commit

Permalink
tipc: Don't use iocb argument in socket layer
Browse files Browse the repository at this point in the history
Currently the iocb argument is used to idenfiy whether or not socket
lock is hold before tipc_sendmsg()/tipc_send_stream() is called. But
this usage prevents iocb argument from being dropped through sendmsg()
at socket common layer. Therefore, in the commit we introduce two new
functions called __tipc_sendmsg() and __tipc_send_stream(). When they
are invoked, it assumes that their callers have taken socket lock,
thereby avoiding the weird usage of iocb argument.

Cc: Al Viro <viro@ZenIV.linux.org.uk>
Cc: Christoph Hellwig <hch@lst.de>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ying Xue authored and David S. Miller committed Mar 2, 2015
1 parent 6556c38 commit 39a0295
Showing 1 changed file with 44 additions and 38 deletions.
82 changes: 44 additions & 38 deletions net/tipc/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope,
static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid);
static int tipc_sk_insert(struct tipc_sock *tsk);
static void tipc_sk_remove(struct tipc_sock *tsk);
static int __tipc_send_stream(struct socket *sock, struct msghdr *m,
size_t dsz);
static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz);

static const struct proto_ops packet_ops;
static const struct proto_ops stream_ops;
Expand Down Expand Up @@ -906,6 +909,18 @@ static int tipc_wait_for_sndmsg(struct socket *sock, long *timeo_p)
*/
static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t dsz)
{
struct sock *sk = sock->sk;
int ret;

lock_sock(sk);
ret = __tipc_sendmsg(sock, m, dsz);
release_sock(sk);

return ret;
}

static int __tipc_sendmsg(struct socket *sock, struct msghdr *m, size_t dsz)
{
DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
struct sock *sk = sock->sk;
Expand All @@ -931,22 +946,13 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
if (dsz > TIPC_MAX_USER_MSG_SIZE)
return -EMSGSIZE;

if (iocb)
lock_sock(sk);

if (unlikely(sock->state != SS_READY)) {
if (sock->state == SS_LISTENING) {
rc = -EPIPE;
goto exit;
}
if (sock->state != SS_UNCONNECTED) {
rc = -EISCONN;
goto exit;
}
if (tsk->published) {
rc = -EOPNOTSUPP;
goto exit;
}
if (sock->state == SS_LISTENING)
return -EPIPE;
if (sock->state != SS_UNCONNECTED)
return -EISCONN;
if (tsk->published)
return -EOPNOTSUPP;
if (dest->addrtype == TIPC_ADDR_NAME) {
tsk->conn_type = dest->addr.name.name.type;
tsk->conn_instance = dest->addr.name.name.instance;
Expand All @@ -956,8 +962,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);

if (dest->addrtype == TIPC_ADDR_MCAST) {
rc = tipc_sendmcast(sock, seq, m, dsz, timeo);
goto exit;
return tipc_sendmcast(sock, seq, m, dsz, timeo);
} else if (dest->addrtype == TIPC_ADDR_NAME) {
u32 type = dest->addr.name.name.type;
u32 inst = dest->addr.name.name.instance;
Expand All @@ -972,10 +977,8 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
dport = tipc_nametbl_translate(net, type, inst, &dnode);
msg_set_destnode(mhdr, dnode);
msg_set_destport(mhdr, dport);
if (unlikely(!dport && !dnode)) {
rc = -EHOSTUNREACH;
goto exit;
}
if (unlikely(!dport && !dnode))
return -EHOSTUNREACH;
} else if (dest->addrtype == TIPC_ADDR_ID) {
dnode = dest->addr.id.node;
msg_set_type(mhdr, TIPC_DIRECT_MSG);
Expand All @@ -990,7 +993,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
mtu = tipc_node_get_mtu(net, dnode, tsk->portid);
rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, pktchain);
if (rc < 0)
goto exit;
return rc;

do {
skb = skb_peek(pktchain);
Expand All @@ -1013,9 +1016,6 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
if (rc)
__skb_queue_purge(pktchain);
} while (!rc);
exit:
if (iocb)
release_sock(sk);

return rc;
}
Expand Down Expand Up @@ -1064,6 +1064,18 @@ static int tipc_wait_for_sndpkt(struct socket *sock, long *timeo_p)
*/
static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t dsz)
{
struct sock *sk = sock->sk;
int ret;

lock_sock(sk);
ret = __tipc_send_stream(sock, m, dsz);
release_sock(sk);

return ret;
}

static int __tipc_send_stream(struct socket *sock, struct msghdr *m, size_t dsz)
{
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
Expand All @@ -1080,23 +1092,19 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,

/* Handle implied connection establishment */
if (unlikely(dest)) {
rc = tipc_sendmsg(iocb, sock, m, dsz);
rc = __tipc_sendmsg(sock, m, dsz);
if (dsz && (dsz == rc))
tsk->sent_unacked = 1;
return rc;
}
if (dsz > (uint)INT_MAX)
return -EMSGSIZE;

if (iocb)
lock_sock(sk);

if (unlikely(sock->state != SS_CONNECTED)) {
if (sock->state == SS_DISCONNECTING)
rc = -EPIPE;
return -EPIPE;
else
rc = -ENOTCONN;
goto exit;
return -ENOTCONN;
}

timeo = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
Expand All @@ -1108,7 +1116,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
rc = tipc_msg_build(mhdr, m, sent, send, mtu, pktchain);
if (unlikely(rc < 0))
goto exit;
return rc;
do {
if (likely(!tsk_conn_cong(tsk))) {
rc = tipc_link_xmit(net, pktchain, dnode, portid);
Expand All @@ -1133,9 +1141,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
if (rc)
__skb_queue_purge(pktchain);
} while (!rc);
exit:
if (iocb)
release_sock(sk);

return sent ? sent : rc;
}

Expand Down Expand Up @@ -1947,7 +1953,7 @@ static int tipc_connect(struct socket *sock, struct sockaddr *dest,
if (!timeout)
m.msg_flags = MSG_DONTWAIT;

res = tipc_sendmsg(NULL, sock, &m, 0);
res = __tipc_sendmsg(sock, &m, 0);
if ((res < 0) && (res != -EWOULDBLOCK))
goto exit;

Expand Down Expand Up @@ -2103,7 +2109,7 @@ static int tipc_accept(struct socket *sock, struct socket *new_sock, int flags)
struct msghdr m = {NULL,};

tsk_advance_rx_queue(sk);
tipc_send_packet(NULL, new_sock, &m, 0);
__tipc_send_stream(new_sock, &m, 0);
} else {
__skb_dequeue(&sk->sk_receive_queue);
__skb_queue_head(&new_sk->sk_receive_queue, buf);
Expand Down

0 comments on commit 39a0295

Please sign in to comment.