[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <5086C45A.4030703@parallels.com>
Date: Tue, 23 Oct 2012 20:22:50 +0400
From: Pavel Emelyanov <xemul@...allels.com>
To: Linux Netdev List <netdev@...r.kernel.org>,
David Miller <davem@...emloft.net>
Subject: [PATCH 1/3] sk: Introduce the shutdown user-to-mask routine
The sys_shutdown "how" argument is converted into kernel-side mask
with a trick -- the "how++" does proper bits conversion. And since
this is a trick, it's commented in the respective places.
When there will be sk_shutdown reporting mechanism it will be natural
to report not the kernel-side mask, but the values known by userspace
(this "how" thing), i.e. we'll have to do the reciprocal trick.
I propose to encapsulate both tricks in helpers, here's the user to
kernel one.
Signed-off-by: Pavel Emelyanov <xemul@...allels.com>
---
include/net/sock.h | 18 ++++++++++++++++++
net/ipv4/af_inet.c | 7 +++----
net/iucv/af_iucv.c | 5 ++---
net/unix/af_unix.c | 9 ++-------
4 files changed, 25 insertions(+), 14 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index c945fba..c42c115 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1265,6 +1265,24 @@ void sk_prot_clear_portaddr_nulls(struct sock *sk, int size);
#define RCV_SHUTDOWN 1
#define SEND_SHUTDOWN 2
+static inline int shutdown_u2mask(int uhow)
+{
+ /*
+ * map
+ * SHUT_RD -> RCV_SHUTDOWN
+ * SHUT_WR -> SEND_SHUTDOWN
+ * SHUT_RDWR -> SHUTDOWN_MASK
+ *
+ * or report 0 on error
+ */
+
+ uhow++;
+ if (uhow & ~SHUTDOWN_MASK)
+ uhow = 0;
+
+ return uhow;
+}
+
#define SOCK_SNDBUF_LOCK 1
#define SOCK_RCVBUF_LOCK 2
#define SOCK_BINDADDR_LOCK 4
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 766c596..3b3940c 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -825,10 +825,9 @@ int inet_shutdown(struct socket *sock, int how)
/* This should really check to make sure
* the socket is a TCP socket. (WHY AC...)
*/
- how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
- 1->2 bit 2 snds.
- 2->3 */
- if ((how & ~SHUTDOWN_MASK) || !how) /* MAXINT->0 */
+
+ how = shutdown_u2mask(how);
+ if (!how)
return -EINVAL;
lock_sock(sk);
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index cd6f7a9..308024c 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -1497,9 +1497,8 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
struct iucv_message txmsg;
int err = 0;
- how++;
-
- if ((how & ~SHUTDOWN_MASK) || !how)
+ how = shutdown_u2mask(how);
+ if (!how)
return -EINVAL;
lock_sock(sk);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 5b5c876..14543f2 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2057,14 +2057,9 @@ static int unix_shutdown(struct socket *sock, int mode)
struct sock *sk = sock->sk;
struct sock *other;
- if (mode < SHUT_RD || mode > SHUT_RDWR)
+ mode = shutdown_u2mask(mode);
+ if (!mode)
return -EINVAL;
- /* This maps:
- * SHUT_RD (0) -> RCV_SHUTDOWN (1)
- * SHUT_WR (1) -> SEND_SHUTDOWN (2)
- * SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
- */
- ++mode;
unix_state_lock(sk);
sk->sk_shutdown |= mode;
--
1.7.6.5
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists