diff options
Diffstat (limited to 'net/unix/af_unix.c')
| -rw-r--r-- | net/unix/af_unix.c | 70 | 
1 files changed, 43 insertions, 27 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index b595a3d8679f..aad8fb699989 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -115,8 +115,10 @@  #include <net/checksum.h>  #include <linux/security.h> -static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; -static DEFINE_SPINLOCK(unix_table_lock); +struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; +EXPORT_SYMBOL_GPL(unix_socket_table); +DEFINE_SPINLOCK(unix_table_lock); +EXPORT_SYMBOL_GPL(unix_table_lock);  static atomic_long_t unix_nr_socks;  #define unix_sockets_unbound	(&unix_socket_table[UNIX_HASH_SIZE]) @@ -172,7 +174,7 @@ static inline int unix_recvq_full(struct sock const *sk)  	return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;  } -static struct sock *unix_peer_get(struct sock *s) +struct sock *unix_peer_get(struct sock *s)  {  	struct sock *peer; @@ -183,6 +185,7 @@ static struct sock *unix_peer_get(struct sock *s)  	unix_state_unlock(s);  	return peer;  } +EXPORT_SYMBOL_GPL(unix_peer_get);  static inline void unix_release_addr(struct unix_address *addr)  { @@ -847,7 +850,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)  	atomic_set(&addr->refcnt, 1);  	if (sun_path[0]) { -		unsigned int mode; +		umode_t mode;  		err = 0;  		/*  		 * Get the parent directory, calculate the hash for last @@ -2062,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; @@ -2070,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;  | 
