]> Pileus Git - ~andy/linux/blobdiff - net/unix/af_unix.c
net: unix: non blocking recvmsg() should not return -EINTR
[~andy/linux] / net / unix / af_unix.c
index a427623ee574e88d9926c7972a0650c5c6f9a3eb..94404f19f9deebbb7c55b7a1660dd011510ba3fd 100644 (file)
@@ -80,6 +80,8 @@
  *               with BSD names.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
@@ -161,9 +163,8 @@ static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
 
 static inline unsigned int unix_hash_fold(__wsum n)
 {
-       unsigned int hash = (__force unsigned int)n;
+       unsigned int hash = (__force unsigned int)csum_fold(n);
 
-       hash ^= hash>>16;
        hash ^= hash>>8;
        return hash&(UNIX_HASH_SIZE-1);
 }
@@ -366,7 +367,7 @@ static void unix_sock_destructor(struct sock *sk)
        WARN_ON(!sk_unhashed(sk));
        WARN_ON(sk->sk_socket);
        if (!sock_flag(sk, SOCK_DEAD)) {
-               printk(KERN_INFO "Attempt to release alive unix socket: %p\n", sk);
+               pr_info("Attempt to release alive unix socket: %p\n", sk);
                return;
        }
 
@@ -378,7 +379,7 @@ static void unix_sock_destructor(struct sock *sk)
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
        local_bh_enable();
 #ifdef UNIX_REFCNT_DEBUG
-       printk(KERN_DEBUG "UNIX %p is destroyed, %ld are still alive.\n", sk,
+       pr_debug("UNIX %p is destroyed, %ld are still alive.\n", sk,
                atomic_long_read(&unix_nr_socks));
 #endif
 }
@@ -1448,7 +1449,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct net *net = sock_net(sk);
        struct unix_sock *u = unix_sk(sk);
-       struct sockaddr_un *sunaddr = msg->msg_name;
+       DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
        struct sock *other = NULL;
        int namelen = 0; /* fake GCC */
        int err;
@@ -1786,8 +1787,11 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
                goto out;
 
        err = mutex_lock_interruptible(&u->readlock);
-       if (err) {
-               err = sock_intr_errno(sock_rcvtimeo(sk, noblock));
+       if (unlikely(err)) {
+               /* recvmsg() in non blocking mode is supposed to return -EAGAIN
+                * sk_rcvtimeo is not honored by mutex_lock_interruptible()
+                */
+               err = noblock ? -EAGAIN : -ERESTARTSYS;
                goto out;
        }
 
@@ -1910,8 +1914,9 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct scm_cookie tmp_scm;
        struct sock *sk = sock->sk;
        struct unix_sock *u = unix_sk(sk);
-       struct sockaddr_un *sunaddr = msg->msg_name;
+       DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
        int copied = 0;
+       int noblock = flags & MSG_DONTWAIT;
        int check_creds = 0;
        int target;
        int err = 0;
@@ -1927,7 +1932,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
                goto out;
 
        target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
-       timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
+       timeo = sock_rcvtimeo(sk, noblock);
 
        /* Lock the socket to prevent queue disordering
         * while sleeps in memcpy_tomsg
@@ -1939,8 +1944,11 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
        }
 
        err = mutex_lock_interruptible(&u->readlock);
-       if (err) {
-               err = sock_intr_errno(timeo);
+       if (unlikely(err)) {
+               /* recvmsg() in non blocking mode is supposed to return -EAGAIN
+                * sk_rcvtimeo is not honored by mutex_lock_interruptible()
+                */
+               err = noblock ? -EAGAIN : -ERESTARTSYS;
                goto out;
        }
 
@@ -2441,8 +2449,7 @@ static int __init af_unix_init(void)
 
        rc = proto_register(&unix_proto, 1);
        if (rc != 0) {
-               printk(KERN_CRIT "%s: Cannot create unix_sock SLAB cache!\n",
-                      __func__);
+               pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
                goto out;
        }