af_unix: Move CINQ/COUTQ code to helpers
Pavel Emelyanov [Fri, 30 Dec 2011 00:54:11 +0000 (00:54 +0000)]
Currently tcp diag reports rqlen and wqlen values similar to how
the CINQ/COUTQ iotcls do. To make unix diag report these values
in the same way move the respective code into helpers.

Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

include/net/af_unix.h
net/unix/af_unix.c

index 63b1781..5a4e29b 100644 (file)
@@ -66,6 +66,9 @@ struct unix_sock {
 
 #define peer_wait peer_wq.wait
 
+long unix_inq_len(struct sock *sk);
+long unix_outq_len(struct sock *sk);
+
 #ifdef CONFIG_SYSCTL
 extern int unix_sysctl_register(struct net *net);
 extern void unix_sysctl_unregister(struct net *net);
index e1b9358..7cc3d7b 100644 (file)
@@ -2065,6 +2065,36 @@ static int unix_shutdown(struct socket *sock, int mode)
        return 0;
 }
 
+long unix_inq_len(struct sock *sk)
+{
+       struct sk_buff *skb;
+       long amount = 0;
+
+       if (sk->sk_state == TCP_LISTEN)
+               return -EINVAL;
+
+       spin_lock(&sk->sk_receive_queue.lock);
+       if (sk->sk_type == SOCK_STREAM ||
+           sk->sk_type == SOCK_SEQPACKET) {
+               skb_queue_walk(&sk->sk_receive_queue, skb)
+                       amount += skb->len;
+       } else {
+               skb = skb_peek(&sk->sk_receive_queue);
+               if (skb)
+                       amount = skb->len;
+       }
+       spin_unlock(&sk->sk_receive_queue.lock);
+
+       return amount;
+}
+EXPORT_SYMBOL_GPL(unix_inq_len);
+
+long unix_outq_len(struct sock *sk)
+{
+       return sk_wmem_alloc_get(sk);
+}
+EXPORT_SYMBOL_GPL(unix_outq_len);
+
 static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        struct sock *sk = sock->sk;
@@ -2073,33 +2103,16 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
        switch (cmd) {
        case SIOCOUTQ:
-               amount = sk_wmem_alloc_get(sk);
+               amount = unix_outq_len(sk);
                err = put_user(amount, (int __user *)arg);
                break;
        case SIOCINQ:
-               {
-                       struct sk_buff *skb;
-
-                       if (sk->sk_state == TCP_LISTEN) {
-                               err = -EINVAL;
-                               break;
-                       }
-
-                       spin_lock(&sk->sk_receive_queue.lock);
-                       if (sk->sk_type == SOCK_STREAM ||
-                           sk->sk_type == SOCK_SEQPACKET) {
-                               skb_queue_walk(&sk->sk_receive_queue, skb)
-                                       amount += skb->len;
-                       } else {
-                               skb = skb_peek(&sk->sk_receive_queue);
-                               if (skb)
-                                       amount = skb->len;
-                       }
-                       spin_unlock(&sk->sk_receive_queue.lock);
+               amount = unix_inq_len(sk);
+               if (amount < 0)
+                       err = amount;
+               else
                        err = put_user(amount, (int __user *)arg);
-                       break;
-               }
-
+               break;
        default:
                err = -ENOIOCTLCMD;
                break;