aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c55
1 files changed, 27 insertions, 28 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index acc73ba8bade..5f6ae79b8b16 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -121,7 +121,7 @@
121int sysctl_unix_max_dgram_qlen = 10; 121int sysctl_unix_max_dgram_qlen = 10;
122 122
123struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; 123struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
124DEFINE_RWLOCK(unix_table_lock); 124DEFINE_SPINLOCK(unix_table_lock);
125static atomic_t unix_nr_socks = ATOMIC_INIT(0); 125static atomic_t unix_nr_socks = ATOMIC_INIT(0);
126 126
127#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE]) 127#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE])
@@ -130,7 +130,7 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0);
130 130
131/* 131/*
132 * SMP locking strategy: 132 * SMP locking strategy:
133 * hash table is protected with rwlock unix_table_lock 133 * hash table is protected with spinlock unix_table_lock
134 * each socket state is protected by separate rwlock. 134 * each socket state is protected by separate rwlock.
135 */ 135 */
136 136
@@ -214,16 +214,16 @@ static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
214 214
215static inline void unix_remove_socket(struct sock *sk) 215static inline void unix_remove_socket(struct sock *sk)
216{ 216{
217 write_lock(&unix_table_lock); 217 spin_lock(&unix_table_lock);
218 __unix_remove_socket(sk); 218 __unix_remove_socket(sk);
219 write_unlock(&unix_table_lock); 219 spin_unlock(&unix_table_lock);
220} 220}
221 221
222static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk) 222static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
223{ 223{
224 write_lock(&unix_table_lock); 224 spin_lock(&unix_table_lock);
225 __unix_insert_socket(list, sk); 225 __unix_insert_socket(list, sk);
226 write_unlock(&unix_table_lock); 226 spin_unlock(&unix_table_lock);
227} 227}
228 228
229static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname, 229static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
@@ -250,11 +250,11 @@ static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname,
250{ 250{
251 struct sock *s; 251 struct sock *s;
252 252
253 read_lock(&unix_table_lock); 253 spin_lock(&unix_table_lock);
254 s = __unix_find_socket_byname(sunname, len, type, hash); 254 s = __unix_find_socket_byname(sunname, len, type, hash);
255 if (s) 255 if (s)
256 sock_hold(s); 256 sock_hold(s);
257 read_unlock(&unix_table_lock); 257 spin_unlock(&unix_table_lock);
258 return s; 258 return s;
259} 259}
260 260
@@ -263,7 +263,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
263 struct sock *s; 263 struct sock *s;
264 struct hlist_node *node; 264 struct hlist_node *node;
265 265
266 read_lock(&unix_table_lock); 266 spin_lock(&unix_table_lock);
267 sk_for_each(s, node, 267 sk_for_each(s, node,
268 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { 268 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
269 struct dentry *dentry = unix_sk(s)->dentry; 269 struct dentry *dentry = unix_sk(s)->dentry;
@@ -276,7 +276,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
276 } 276 }
277 s = NULL; 277 s = NULL;
278found: 278found:
279 read_unlock(&unix_table_lock); 279 spin_unlock(&unix_table_lock);
280 return s; 280 return s;
281} 281}
282 282
@@ -473,7 +473,7 @@ static int unix_dgram_connect(struct socket *, struct sockaddr *,
473static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, 473static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
474 struct msghdr *, size_t); 474 struct msghdr *, size_t);
475 475
476static struct proto_ops unix_stream_ops = { 476static const struct proto_ops unix_stream_ops = {
477 .family = PF_UNIX, 477 .family = PF_UNIX,
478 .owner = THIS_MODULE, 478 .owner = THIS_MODULE,
479 .release = unix_release, 479 .release = unix_release,
@@ -494,7 +494,7 @@ static struct proto_ops unix_stream_ops = {
494 .sendpage = sock_no_sendpage, 494 .sendpage = sock_no_sendpage,
495}; 495};
496 496
497static struct proto_ops unix_dgram_ops = { 497static const struct proto_ops unix_dgram_ops = {
498 .family = PF_UNIX, 498 .family = PF_UNIX,
499 .owner = THIS_MODULE, 499 .owner = THIS_MODULE,
500 .release = unix_release, 500 .release = unix_release,
@@ -515,7 +515,7 @@ static struct proto_ops unix_dgram_ops = {
515 .sendpage = sock_no_sendpage, 515 .sendpage = sock_no_sendpage,
516}; 516};
517 517
518static struct proto_ops unix_seqpacket_ops = { 518static const struct proto_ops unix_seqpacket_ops = {
519 .family = PF_UNIX, 519 .family = PF_UNIX,
520 .owner = THIS_MODULE, 520 .owner = THIS_MODULE,
521 .release = unix_release, 521 .release = unix_release,
@@ -564,7 +564,7 @@ static struct sock * unix_create1(struct socket *sock)
564 u = unix_sk(sk); 564 u = unix_sk(sk);
565 u->dentry = NULL; 565 u->dentry = NULL;
566 u->mnt = NULL; 566 u->mnt = NULL;
567 rwlock_init(&u->lock); 567 spin_lock_init(&u->lock);
568 atomic_set(&u->inflight, sock ? 0 : -1); 568 atomic_set(&u->inflight, sock ? 0 : -1);
569 init_MUTEX(&u->readsem); /* single task reading lock */ 569 init_MUTEX(&u->readsem); /* single task reading lock */
570 init_waitqueue_head(&u->peer_wait); 570 init_waitqueue_head(&u->peer_wait);
@@ -642,12 +642,12 @@ retry:
642 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short); 642 addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
643 addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0)); 643 addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
644 644
645 write_lock(&unix_table_lock); 645 spin_lock(&unix_table_lock);
646 ordernum = (ordernum+1)&0xFFFFF; 646 ordernum = (ordernum+1)&0xFFFFF;
647 647
648 if (__unix_find_socket_byname(addr->name, addr->len, sock->type, 648 if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
649 addr->hash)) { 649 addr->hash)) {
650 write_unlock(&unix_table_lock); 650 spin_unlock(&unix_table_lock);
651 /* Sanity yield. It is unusual case, but yet... */ 651 /* Sanity yield. It is unusual case, but yet... */
652 if (!(ordernum&0xFF)) 652 if (!(ordernum&0xFF))
653 yield(); 653 yield();
@@ -658,7 +658,7 @@ retry:
658 __unix_remove_socket(sk); 658 __unix_remove_socket(sk);
659 u->addr = addr; 659 u->addr = addr;
660 __unix_insert_socket(&unix_socket_table[addr->hash], sk); 660 __unix_insert_socket(&unix_socket_table[addr->hash], sk);
661 write_unlock(&unix_table_lock); 661 spin_unlock(&unix_table_lock);
662 err = 0; 662 err = 0;
663 663
664out: up(&u->readsem); 664out: up(&u->readsem);
@@ -791,7 +791,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
791 addr->hash = UNIX_HASH_SIZE; 791 addr->hash = UNIX_HASH_SIZE;
792 } 792 }
793 793
794 write_lock(&unix_table_lock); 794 spin_lock(&unix_table_lock);
795 795
796 if (!sunaddr->sun_path[0]) { 796 if (!sunaddr->sun_path[0]) {
797 err = -EADDRINUSE; 797 err = -EADDRINUSE;
@@ -814,7 +814,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
814 __unix_insert_socket(list, sk); 814 __unix_insert_socket(list, sk);
815 815
816out_unlock: 816out_unlock:
817 write_unlock(&unix_table_lock); 817 spin_unlock(&unix_table_lock);
818out_up: 818out_up:
819 up(&u->readsem); 819 up(&u->readsem);
820out: 820out:
@@ -1063,10 +1063,12 @@ restart:
1063 /* Set credentials */ 1063 /* Set credentials */
1064 sk->sk_peercred = other->sk_peercred; 1064 sk->sk_peercred = other->sk_peercred;
1065 1065
1066 sock_hold(newsk);
1067 unix_peer(sk) = newsk;
1068 sock->state = SS_CONNECTED; 1066 sock->state = SS_CONNECTED;
1069 sk->sk_state = TCP_ESTABLISHED; 1067 sk->sk_state = TCP_ESTABLISHED;
1068 sock_hold(newsk);
1069
1070 smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */
1071 unix_peer(sk) = newsk;
1070 1072
1071 unix_state_wunlock(sk); 1073 unix_state_wunlock(sk);
1072 1074
@@ -1414,7 +1416,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1414 } else { 1416 } else {
1415 sunaddr = NULL; 1417 sunaddr = NULL;
1416 err = -ENOTCONN; 1418 err = -ENOTCONN;
1417 other = unix_peer_get(sk); 1419 other = unix_peer(sk);
1418 if (!other) 1420 if (!other)
1419 goto out_err; 1421 goto out_err;
1420 } 1422 }
@@ -1476,7 +1478,6 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1476 other->sk_data_ready(other, size); 1478 other->sk_data_ready(other, size);
1477 sent+=size; 1479 sent+=size;
1478 } 1480 }
1479 sock_put(other);
1480 1481
1481 scm_destroy(siocb->scm); 1482 scm_destroy(siocb->scm);
1482 siocb->scm = NULL; 1483 siocb->scm = NULL;
@@ -1491,8 +1492,6 @@ pipe_err:
1491 send_sig(SIGPIPE,current,0); 1492 send_sig(SIGPIPE,current,0);
1492 err = -EPIPE; 1493 err = -EPIPE;
1493out_err: 1494out_err:
1494 if (other)
1495 sock_put(other);
1496 scm_destroy(siocb->scm); 1495 scm_destroy(siocb->scm);
1497 siocb->scm = NULL; 1496 siocb->scm = NULL;
1498 return sent ? : err; 1497 return sent ? : err;
@@ -1860,7 +1859,7 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1860 } 1859 }
1861 1860
1862 default: 1861 default:
1863 err = dev_ioctl(cmd, (void __user *)arg); 1862 err = -ENOIOCTLCMD;
1864 break; 1863 break;
1865 } 1864 }
1866 return err; 1865 return err;
@@ -1917,7 +1916,7 @@ static struct sock *unix_seq_idx(int *iter, loff_t pos)
1917 1916
1918static void *unix_seq_start(struct seq_file *seq, loff_t *pos) 1917static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
1919{ 1918{
1920 read_lock(&unix_table_lock); 1919 spin_lock(&unix_table_lock);
1921 return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1); 1920 return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
1922} 1921}
1923 1922
@@ -1932,7 +1931,7 @@ static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1932 1931
1933static void unix_seq_stop(struct seq_file *seq, void *v) 1932static void unix_seq_stop(struct seq_file *seq, void *v)
1934{ 1933{
1935 read_unlock(&unix_table_lock); 1934 spin_unlock(&unix_table_lock);
1936} 1935}
1937 1936
1938static int unix_seq_show(struct seq_file *seq, void *v) 1937static int unix_seq_show(struct seq_file *seq, void *v)