Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 57324
b: refs/heads/master
c: 278a3de
h: refs/heads/master
v: v3
  • Loading branch information
David S. Miller committed Jun 4, 2007
1 parent 1ad9a11 commit 3d630db
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 007a880d627aee0e854e793099bb33d0c1130678
refs/heads/master: 278a3de5abc7901805689a66340b5af9882b4f9a
43 changes: 38 additions & 5 deletions trunk/net/unix/af_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,31 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
goto out_up;
}

static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
{
if (unlikely(sk1 == sk2) || !sk2) {
unix_state_lock(sk1);
return;
}
if (sk1 < sk2) {
unix_state_lock(sk1);
unix_state_lock_nested(sk2);
} else {
unix_state_lock(sk2);
unix_state_lock_nested(sk1);
}
}

static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
{
if (unlikely(sk1 == sk2) || !sk2) {
unix_state_unlock(sk1);
return;
}
unix_state_unlock(sk1);
unix_state_unlock(sk2);
}

static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
int alen, int flags)
{
Expand All @@ -877,11 +902,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
!unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
goto out;

restart:
other=unix_find_other(sunaddr, alen, sock->type, hash, &err);
if (!other)
goto out;

unix_state_lock(sk);
unix_state_double_lock(sk, other);

/* Apparently VFS overslept socket death. Retry. */
if (sock_flag(other, SOCK_DEAD)) {
unix_state_double_unlock(sk, other);
sock_put(other);
goto restart;
}

err = -EPERM;
if (!unix_may_send(sk, other))
Expand All @@ -896,7 +929,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
* 1003.1g breaking connected state with AF_UNSPEC
*/
other = NULL;
unix_state_lock(sk);
unix_state_double_lock(sk, other);
}

/*
Expand All @@ -905,19 +938,19 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
if (unix_peer(sk)) {
struct sock *old_peer = unix_peer(sk);
unix_peer(sk)=other;
unix_state_unlock(sk);
unix_state_double_unlock(sk, other);

if (other != old_peer)
unix_dgram_disconnected(sk, old_peer);
sock_put(old_peer);
} else {
unix_peer(sk)=other;
unix_state_unlock(sk);
unix_state_double_unlock(sk, other);
}
return 0;

out_unlock:
unix_state_unlock(sk);
unix_state_double_unlock(sk, other);
sock_put(other);
out:
return err;
Expand Down

0 comments on commit 3d630db

Please sign in to comment.