Skip to content

Commit e63c91c

Browse files
q2venkawasaki
authored andcommitted
inet: Add inet_shutdown_locked().
When NBD calls sendmsg() and shutdown() for TCP sockets, it must use lock_sock_try() to avoid potential deadlock. While TCP already exports tcp_sendmsg_locked(), there is no locked variant for inet_shutdown(). Let's add inet_shutdown_locked(). Signed-off-by: Kuniyuki Iwashima <[email protected]>
1 parent d1444e3 commit e63c91c

2 files changed

Lines changed: 33 additions & 11 deletions

File tree

include/net/inet_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ void inet_splice_eof(struct socket *sock);
3838
int inet_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
3939
int flags);
4040
int inet_shutdown(struct socket *sock, int how);
41+
int inet_shutdown_locked(struct socket *sock, int how);
4142
int inet_listen(struct socket *sock, int backlog);
4243
int __inet_listen_sk(struct sock *sk, int backlog);
4344
void inet_sock_destruct(struct sock *sk);

net/ipv4/af_inet.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -902,21 +902,11 @@ int inet_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
902902
}
903903
EXPORT_SYMBOL(inet_recvmsg);
904904

905-
int inet_shutdown(struct socket *sock, int how)
905+
static int __inet_shutdown(struct socket *sock, int how)
906906
{
907907
struct sock *sk = sock->sk;
908908
int err = 0;
909909

910-
/* This should really check to make sure
911-
* the socket is a TCP socket. (WHY AC...)
912-
*/
913-
how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
914-
1->2 bit 2 snds.
915-
2->3 */
916-
if ((how & ~SHUTDOWN_MASK) || !how) /* MAXINT->0 */
917-
return -EINVAL;
918-
919-
lock_sock(sk);
920910
if (sock->state == SS_CONNECTING) {
921911
if ((1 << sk->sk_state) &
922912
(TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_CLOSE))
@@ -953,11 +943,42 @@ int inet_shutdown(struct socket *sock, int how)
953943

954944
/* Wake up anyone sleeping in poll. */
955945
sk->sk_state_change(sk);
946+
947+
return err;
948+
}
949+
950+
int inet_shutdown(struct socket *sock, int how)
951+
{
952+
struct sock *sk = sock->sk;
953+
int err;
954+
955+
/* maps SHUT_RD (0) -> RCV_SHUTDOWN (1), etc */
956+
how++;
957+
958+
if ((how & ~SHUTDOWN_MASK) || !how)
959+
return -EINVAL;
960+
961+
lock_sock(sk);
962+
err = __inet_shutdown(sock, how);
956963
release_sock(sk);
964+
957965
return err;
958966
}
959967
EXPORT_SYMBOL(inet_shutdown);
960968

969+
int inet_shutdown_locked(struct socket *sock, int how)
970+
{
971+
sock_owned_by_me(sock->sk);
972+
973+
how++;
974+
975+
if ((how & ~SHUTDOWN_MASK) || !how)
976+
return -EINVAL;
977+
978+
return __inet_shutdown(sock, how);
979+
}
980+
EXPORT_SYMBOL_GPL(inet_shutdown_locked);
981+
961982
/*
962983
* ioctl() calls you can issue on an INET socket. Most of these are
963984
* device configuration and stuff and very rarely used. Some ioctls

0 commit comments

Comments
 (0)