diff options
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r-- | net/unix/af_unix.c | 55 |
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 @@ | |||
121 | int sysctl_unix_max_dgram_qlen = 10; | 121 | int sysctl_unix_max_dgram_qlen = 10; |
122 | 122 | ||
123 | struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; | 123 | struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; |
124 | DEFINE_RWLOCK(unix_table_lock); | 124 | DEFINE_SPINLOCK(unix_table_lock); |
125 | static atomic_t unix_nr_socks = ATOMIC_INIT(0); | 125 | static 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 | ||
215 | static inline void unix_remove_socket(struct sock *sk) | 215 | static 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 | ||
222 | static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk) | 222 | static 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 | ||
229 | static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname, | 229 | static 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; |
278 | found: | 278 | found: |
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 *, | |||
473 | static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, | 473 | static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *, |
474 | struct msghdr *, size_t); | 474 | struct msghdr *, size_t); |
475 | 475 | ||
476 | static struct proto_ops unix_stream_ops = { | 476 | static 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 | ||
497 | static struct proto_ops unix_dgram_ops = { | 497 | static 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 | ||
518 | static struct proto_ops unix_seqpacket_ops = { | 518 | static 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 | ||
664 | out: up(&u->readsem); | 664 | out: 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 | ||
816 | out_unlock: | 816 | out_unlock: |
817 | write_unlock(&unix_table_lock); | 817 | spin_unlock(&unix_table_lock); |
818 | out_up: | 818 | out_up: |
819 | up(&u->readsem); | 819 | up(&u->readsem); |
820 | out: | 820 | out: |
@@ -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; |
1493 | out_err: | 1494 | out_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 | ||
1918 | static void *unix_seq_start(struct seq_file *seq, loff_t *pos) | 1917 | static 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 | ||
1933 | static void unix_seq_stop(struct seq_file *seq, void *v) | 1932 | static 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 | ||
1938 | static int unix_seq_show(struct seq_file *seq, void *v) | 1937 | static int unix_seq_show(struct seq_file *seq, void *v) |