git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git]
/
net
/
unix
/
af_unix.c
diff --git
a/net/unix/af_unix.c
b/net/unix/af_unix.c
index
4e848ea
..
d2bdd01
100644
(file)
--- a/
net/unix/af_unix.c
+++ b/
net/unix/af_unix.c
@@
-105,7
+105,7
@@
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/sock.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/sock.h>
-#include <
linux/tcp
.h>
+#include <
net/tcp_states
.h>
#include <net/af_unix.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/af_unix.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
@@
-124,7
+124,7
@@
int sysctl_unix_max_dgram_qlen = 10;
struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
int sysctl_unix_max_dgram_qlen = 10;
struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
-DEFINE_
RW
LOCK(unix_table_lock);
+DEFINE_
SPIN
LOCK(unix_table_lock);
static atomic_t unix_nr_socks = ATOMIC_INIT(0);
#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE])
static atomic_t unix_nr_socks = ATOMIC_INIT(0);
#define unix_sockets_unbound (&unix_socket_table[UNIX_HASH_SIZE])
@@
-133,7
+133,7
@@
static atomic_t unix_nr_socks = ATOMIC_INIT(0);
/*
* SMP locking strategy:
/*
* SMP locking strategy:
- * hash table is protected with
rw
lock unix_table_lock
+ * hash table is protected with
spin
lock unix_table_lock
* each socket state is protected by separate rwlock.
*/
* each socket state is protected by separate rwlock.
*/
@@
-217,16
+217,16
@@
static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
static inline void unix_remove_socket(struct sock *sk)
{
static inline void unix_remove_socket(struct sock *sk)
{
-
write
_lock(&unix_table_lock);
+
spin
_lock(&unix_table_lock);
__unix_remove_socket(sk);
__unix_remove_socket(sk);
-
write
_unlock(&unix_table_lock);
+
spin
_unlock(&unix_table_lock);
}
static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
{
}
static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
{
-
write
_lock(&unix_table_lock);
+
spin
_lock(&unix_table_lock);
__unix_insert_socket(list, sk);
__unix_insert_socket(list, sk);
-
write
_unlock(&unix_table_lock);
+
spin
_unlock(&unix_table_lock);
}
static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
}
static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
@@
-238,6
+238,8
@@
static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
struct unix_sock *u = unix_sk(s);
sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
struct unix_sock *u = unix_sk(s);
+ if (!vx_check(s->sk_xid, VX_IDENT|VX_WATCH))
+ continue;
if (u->addr->len == len &&
!memcmp(u->addr->name, sunname, len))
goto found;
if (u->addr->len == len &&
!memcmp(u->addr->name, sunname, len))
goto found;
@@
-253,11
+255,11
@@
static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname,
{
struct sock *s;
{
struct sock *s;
-
read
_lock(&unix_table_lock);
+
spin
_lock(&unix_table_lock);
s = __unix_find_socket_byname(sunname, len, type, hash);
if (s)
sock_hold(s);
s = __unix_find_socket_byname(sunname, len, type, hash);
if (s)
sock_hold(s);
-
read
_unlock(&unix_table_lock);
+
spin
_unlock(&unix_table_lock);
return s;
}
return s;
}
@@
-266,7
+268,7
@@
static struct sock *unix_find_socket_byinode(struct inode *i)
struct sock *s;
struct hlist_node *node;
struct sock *s;
struct hlist_node *node;
-
read
_lock(&unix_table_lock);
+
spin
_lock(&unix_table_lock);
sk_for_each(s, node,
&unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
struct dentry *dentry = unix_sk(s)->dentry;
sk_for_each(s, node,
&unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
struct dentry *dentry = unix_sk(s)->dentry;
@@
-279,7
+281,7
@@
static struct sock *unix_find_socket_byinode(struct inode *i)
}
s = NULL;
found:
}
s = NULL;
found:
-
read
_unlock(&unix_table_lock);
+
spin
_unlock(&unix_table_lock);
return s;
}
return s;
}
@@
-305,7
+307,7
@@
static void unix_write_space(struct sock *sk)
* may receive messages only from that peer. */
static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
{
* may receive messages only from that peer. */
static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
{
- if (
skb_queue_len
(&sk->sk_receive_queue)) {
+ if (
!skb_queue_empty
(&sk->sk_receive_queue)) {
skb_queue_purge(&sk->sk_receive_queue);
wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
skb_queue_purge(&sk->sk_receive_queue);
wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
@@
-476,7
+478,7
@@
static int unix_dgram_connect(struct socket *, struct sockaddr *,
static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
struct msghdr *, size_t);
static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
struct msghdr *, size_t);
-static struct proto_ops unix_stream_ops = {
+static
const
struct proto_ops unix_stream_ops = {
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
@@
-497,7
+499,7
@@
static struct proto_ops unix_stream_ops = {
.sendpage = sock_no_sendpage,
};
.sendpage = sock_no_sendpage,
};
-static struct proto_ops unix_dgram_ops = {
+static
const
struct proto_ops unix_dgram_ops = {
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
@@
-518,7
+520,7
@@
static struct proto_ops unix_dgram_ops = {
.sendpage = sock_no_sendpage,
};
.sendpage = sock_no_sendpage,
};
-static struct proto_ops unix_seqpacket_ops = {
+static
const
struct proto_ops unix_seqpacket_ops = {
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
@@
-550,7
+552,7
@@
static struct sock * unix_create1(struct socket *sock)
struct sock *sk = NULL;
struct unix_sock *u;
struct sock *sk = NULL;
struct unix_sock *u;
- if (atomic_read(&unix_nr_socks) >= 2*
files_stat.max_files
)
+ if (atomic_read(&unix_nr_socks) >= 2*
get_max_files()
)
goto out;
sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1);
goto out;
sk = sk_alloc(PF_UNIX, GFP_KERNEL, &unix_proto, 1);
@@
-567,9
+569,9
@@
static struct sock * unix_create1(struct socket *sock)
u = unix_sk(sk);
u->dentry = NULL;
u->mnt = NULL;
u = unix_sk(sk);
u->dentry = NULL;
u->mnt = NULL;
-
rw
lock_init(&u->lock);
+
spin_
lock_init(&u->lock);
atomic_set(&u->inflight, sock ? 0 : -1);
atomic_set(&u->inflight, sock ? 0 : -1);
-
init_MUTEX(&u->readsem
); /* single task reading lock */
+
mutex_init(&u->readlock
); /* single task reading lock */
init_waitqueue_head(&u->peer_wait);
unix_insert_socket(unix_sockets_unbound, sk);
out:
init_waitqueue_head(&u->peer_wait);
unix_insert_socket(unix_sockets_unbound, sk);
out:
@@
-626,7
+628,7
@@
static int unix_autobind(struct socket *sock)
struct unix_address * addr;
int err;
struct unix_address * addr;
int err;
-
down(&u->readsem
);
+
mutex_lock(&u->readlock
);
err = 0;
if (u->addr)
err = 0;
if (u->addr)
@@
-645,12
+647,12
@@
retry:
addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
addr->hash = unix_hash_fold(csum_partial((void*)addr->name, addr->len, 0));
-
write
_lock(&unix_table_lock);
+
spin
_lock(&unix_table_lock);
ordernum = (ordernum+1)&0xFFFFF;
if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
addr->hash)) {
ordernum = (ordernum+1)&0xFFFFF;
if (__unix_find_socket_byname(addr->name, addr->len, sock->type,
addr->hash)) {
-
write
_unlock(&unix_table_lock);
+
spin
_unlock(&unix_table_lock);
/* Sanity yield. It is unusual case, but yet... */
if (!(ordernum&0xFF))
yield();
/* Sanity yield. It is unusual case, but yet... */
if (!(ordernum&0xFF))
yield();
@@
-661,10
+663,10
@@
retry:
__unix_remove_socket(sk);
u->addr = addr;
__unix_insert_socket(&unix_socket_table[addr->hash], sk);
__unix_remove_socket(sk);
u->addr = addr;
__unix_insert_socket(&unix_socket_table[addr->hash], sk);
-
write
_unlock(&unix_table_lock);
+
spin
_unlock(&unix_table_lock);
err = 0;
err = 0;
-out:
up(&u->readsem
);
+out:
mutex_unlock(&u->readlock
);
return err;
}
return err;
}
@@
-679,7
+681,7
@@
static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
if (err)
goto fail;
err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
if (err)
goto fail;
- err =
permission(nd.dentry->d_inode,MAY_WRITE, &nd
);
+ err =
vfs_permission(&nd, MAY_WRITE
);
if (err)
goto put_fail;
if (err)
goto put_fail;
@@
-747,7
+749,7
@@
static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
goto out;
addr_len = err;
goto out;
addr_len = err;
-
down(&u->readsem
);
+
mutex_lock(&u->readlock
);
err = -EINVAL;
if (u->addr)
err = -EINVAL;
if (u->addr)
@@
-784,17
+786,17
@@
static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
*/
mode = S_IFSOCK |
(SOCK_INODE(sock)->i_mode & ~current->fs->umask);
*/
mode = S_IFSOCK |
(SOCK_INODE(sock)->i_mode & ~current->fs->umask);
- err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0);
+ err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0
, NULL
);
if (err)
goto out_mknod_dput;
if (err)
goto out_mknod_dput;
-
up(&nd.dentry->d_inode->i_sem
);
+
mutex_unlock(&nd.dentry->d_inode->i_mutex
);
dput(nd.dentry);
nd.dentry = dentry;
addr->hash = UNIX_HASH_SIZE;
}
dput(nd.dentry);
nd.dentry = dentry;
addr->hash = UNIX_HASH_SIZE;
}
-
write
_lock(&unix_table_lock);
+
spin
_lock(&unix_table_lock);
if (!sunaddr->sun_path[0]) {
err = -EADDRINUSE;
if (!sunaddr->sun_path[0]) {
err = -EADDRINUSE;
@@
-817,16
+819,16
@@
static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
__unix_insert_socket(list, sk);
out_unlock:
__unix_insert_socket(list, sk);
out_unlock:
-
write
_unlock(&unix_table_lock);
+
spin
_unlock(&unix_table_lock);
out_up:
out_up:
-
up(&u->readsem
);
+
mutex_unlock(&u->readlock
);
out:
return err;
out_mknod_dput:
dput(dentry);
out_mknod_unlock:
out:
return err;
out_mknod_dput:
dput(dentry);
out_mknod_unlock:
-
up(&nd.dentry->d_inode->i_sem
);
+
mutex_unlock(&nd.dentry->d_inode->i_mutex
);
path_release(&nd);
out_mknod_parent:
if (err==-EEXIST)
path_release(&nd);
out_mknod_parent:
if (err==-EEXIST)
@@
-1066,10
+1068,12
@@
restart:
/* Set credentials */
sk->sk_peercred = other->sk_peercred;
/* Set credentials */
sk->sk_peercred = other->sk_peercred;
- sock_hold(newsk);
- unix_peer(sk) = newsk;
sock->state = SS_CONNECTED;
sk->sk_state = TCP_ESTABLISHED;
sock->state = SS_CONNECTED;
sk->sk_state = TCP_ESTABLISHED;
+ sock_hold(newsk);
+
+ smp_mb__after_atomic_inc(); /* sock_hold() does an atomic_inc() */
+ unix_peer(sk) = newsk;
unix_state_wunlock(sk);
unix_state_wunlock(sk);
@@
-1417,7
+1421,7
@@
static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
} else {
sunaddr = NULL;
err = -ENOTCONN;
} else {
sunaddr = NULL;
err = -ENOTCONN;
- other = unix_peer
_get
(sk);
+ other = unix_peer(sk);
if (!other)
goto out_err;
}
if (!other)
goto out_err;
}
@@
-1428,15
+1432,15
@@
static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
while(sent < len)
{
/*
while(sent < len)
{
/*
- * Optimisation for the fact that under 0.01% of X
messages typically
- * need breaking up.
+ * Optimisation for the fact that under 0.01% of X
+ *
messages typically
need breaking up.
*/
*/
- size
=
len-sent;
+ size
=
len-sent;
/* Keep two messages in the pipe so it schedules better */
/* Keep two messages in the pipe so it schedules better */
- if (size >
sk->sk_sndbuf / 2 - 64
)
- size =
sk->sk_sndbuf / 2
- 64;
+ if (size >
((sk->sk_sndbuf >> 1) - 64)
)
+ size =
(sk->sk_sndbuf >> 1)
- 64;
if (size > SKB_MAX_ALLOC)
size = SKB_MAX_ALLOC;
if (size > SKB_MAX_ALLOC)
size = SKB_MAX_ALLOC;
@@
-1479,7
+1483,6
@@
static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
other->sk_data_ready(other, size);
sent+=size;
}
other->sk_data_ready(other, size);
sent+=size;
}
- sock_put(other);
scm_destroy(siocb->scm);
siocb->scm = NULL;
scm_destroy(siocb->scm);
siocb->scm = NULL;
@@
-1494,8
+1497,6
@@
pipe_err:
send_sig(SIGPIPE,current,0);
err = -EPIPE;
out_err:
send_sig(SIGPIPE,current,0);
err = -EPIPE;
out_err:
- if (other)
- sock_put(other);
scm_destroy(siocb->scm);
siocb->scm = NULL;
return sent ? : err;
scm_destroy(siocb->scm);
siocb->scm = NULL;
return sent ? : err;
@@
-1549,7
+1550,7
@@
static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
msg->msg_namelen = 0;
msg->msg_namelen = 0;
-
down(&u->readsem
);
+
mutex_lock(&u->readlock
);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb)
@@
-1604,7
+1605,7
@@
static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
out_free:
skb_free_datagram(sk,skb);
out_unlock:
out_free:
skb_free_datagram(sk,skb);
out_unlock:
-
up(&u->readsem
);
+
mutex_unlock(&u->readlock
);
out:
return err;
}
out:
return err;
}
@@
-1622,7
+1623,7
@@
static long unix_stream_data_wait(struct sock * sk, long timeo)
for (;;) {
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
for (;;) {
prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
- if (
skb_queue_len
(&sk->sk_receive_queue) ||
+ if (
!skb_queue_empty
(&sk->sk_receive_queue) ||
sk->sk_err ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
signal_pending(current) ||
sk->sk_err ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
signal_pending(current) ||
@@
-1680,7
+1681,7
@@
static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
memset(&tmp_scm, 0, sizeof(tmp_scm));
}
memset(&tmp_scm, 0, sizeof(tmp_scm));
}
-
down(&u->readsem
);
+
mutex_lock(&u->readlock
);
do
{
do
{
@@
-1704,7
+1705,7
@@
static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
err = -EAGAIN;
if (!timeo)
break;
err = -EAGAIN;
if (!timeo)
break;
-
up(&u->readsem
);
+
mutex_unlock(&u->readlock
);
timeo = unix_stream_data_wait(sk, timeo);
timeo = unix_stream_data_wait(sk, timeo);
@@
-1712,7
+1713,7
@@
static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
err = sock_intr_errno(timeo);
goto out;
}
err = sock_intr_errno(timeo);
goto out;
}
-
down(&u->readsem
);
+
mutex_lock(&u->readlock
);
continue;
}
continue;
}
@@
-1778,7
+1779,7
@@
static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
}
} while (size);
}
} while (size);
-
up(&u->readsem
);
+
mutex_unlock(&u->readlock
);
scm_recv(sock, msg, siocb->scm, flags);
out:
return copied ? : err;
scm_recv(sock, msg, siocb->scm, flags);
out:
return copied ? : err;
@@
-1863,7
+1864,7
@@
static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
default:
}
default:
- err =
dev_ioctl(cmd, (void __user *)arg)
;
+ err =
-ENOIOCTLCMD
;
break;
}
return err;
break;
}
return err;
@@
-1882,6
+1883,8
@@
static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
mask |= POLLERR;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
mask |= POLLERR;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ mask |= POLLRDHUP;
/* readable? */
if (!skb_queue_empty(&sk->sk_receive_queue) ||
/* readable? */
if (!skb_queue_empty(&sk->sk_receive_queue) ||
@@
-1920,7
+1923,7
@@
static struct sock *unix_seq_idx(int *iter, loff_t pos)
static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
{
static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
{
-
read
_lock(&unix_table_lock);
+
spin
_lock(&unix_table_lock);
return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
}
return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1);
}
@@
-1935,7
+1938,7
@@
static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
static void unix_seq_stop(struct seq_file *seq, void *v)
{
static void unix_seq_stop(struct seq_file *seq, void *v)
{
-
read
_unlock(&unix_table_lock);
+
spin
_unlock(&unix_table_lock);
}
static int unix_seq_show(struct seq_file *seq, void *v)
}
static int unix_seq_show(struct seq_file *seq, void *v)
@@
-2029,14
+2032,6
@@
static struct net_proto_family unix_family_ops = {
.owner = THIS_MODULE,
};
.owner = THIS_MODULE,
};
-#ifdef CONFIG_SYSCTL
-extern void unix_sysctl_register(void);
-extern void unix_sysctl_unregister(void);
-#else
-static inline void unix_sysctl_register(void) {}
-static inline void unix_sysctl_unregister(void) {}
-#endif
-
static int __init af_unix_init(void)
{
int rc = -1;
static int __init af_unix_init(void)
{
int rc = -1;