diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-06-28 02:00:25 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2013-06-28 02:00:25 -0400 |
commit | 31881d74b6dd1a6c530cff61248def4f2da38bee (patch) | |
tree | be62420cf39192074e13b25553d172b9d5e58a33 /net/unix | |
parent | 8855f30cd2b68012571932c7b01290c20be4508c (diff) | |
parent | 257867dc8d893690c175c1f717f91c3b6d44a63d (diff) |
Merge branch 'for-next' of git://github.com/rydberg/linux into next
Pull in changes from Henrik: "a trivial MT documentation fix".
Diffstat (limited to 'net/unix')
-rw-r--r-- | net/unix/af_unix.c | 54 | ||||
-rw-r--r-- | net/unix/garbage.c | 12 |
2 files changed, 33 insertions, 33 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 51be64f163ec..826e09938bff 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -382,7 +382,7 @@ static void unix_sock_destructor(struct sock *sk) | |||
382 | #endif | 382 | #endif |
383 | } | 383 | } |
384 | 384 | ||
385 | static int unix_release_sock(struct sock *sk, int embrion) | 385 | static void unix_release_sock(struct sock *sk, int embrion) |
386 | { | 386 | { |
387 | struct unix_sock *u = unix_sk(sk); | 387 | struct unix_sock *u = unix_sk(sk); |
388 | struct path path; | 388 | struct path path; |
@@ -451,8 +451,6 @@ static int unix_release_sock(struct sock *sk, int embrion) | |||
451 | 451 | ||
452 | if (unix_tot_inflight) | 452 | if (unix_tot_inflight) |
453 | unix_gc(); /* Garbage collect fds */ | 453 | unix_gc(); /* Garbage collect fds */ |
454 | |||
455 | return 0; | ||
456 | } | 454 | } |
457 | 455 | ||
458 | static void init_peercred(struct sock *sk) | 456 | static void init_peercred(struct sock *sk) |
@@ -699,9 +697,10 @@ static int unix_release(struct socket *sock) | |||
699 | if (!sk) | 697 | if (!sk) |
700 | return 0; | 698 | return 0; |
701 | 699 | ||
700 | unix_release_sock(sk, 0); | ||
702 | sock->sk = NULL; | 701 | sock->sk = NULL; |
703 | 702 | ||
704 | return unix_release_sock(sk, 0); | 703 | return 0; |
705 | } | 704 | } |
706 | 705 | ||
707 | static int unix_autobind(struct socket *sock) | 706 | static int unix_autobind(struct socket *sock) |
@@ -1341,7 +1340,6 @@ static void unix_destruct_scm(struct sk_buff *skb) | |||
1341 | struct scm_cookie scm; | 1340 | struct scm_cookie scm; |
1342 | memset(&scm, 0, sizeof(scm)); | 1341 | memset(&scm, 0, sizeof(scm)); |
1343 | scm.pid = UNIXCB(skb).pid; | 1342 | scm.pid = UNIXCB(skb).pid; |
1344 | scm.cred = UNIXCB(skb).cred; | ||
1345 | if (UNIXCB(skb).fp) | 1343 | if (UNIXCB(skb).fp) |
1346 | unix_detach_fds(&scm, skb); | 1344 | unix_detach_fds(&scm, skb); |
1347 | 1345 | ||
@@ -1392,8 +1390,8 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen | |||
1392 | int err = 0; | 1390 | int err = 0; |
1393 | 1391 | ||
1394 | UNIXCB(skb).pid = get_pid(scm->pid); | 1392 | UNIXCB(skb).pid = get_pid(scm->pid); |
1395 | if (scm->cred) | 1393 | UNIXCB(skb).uid = scm->creds.uid; |
1396 | UNIXCB(skb).cred = get_cred(scm->cred); | 1394 | UNIXCB(skb).gid = scm->creds.gid; |
1397 | UNIXCB(skb).fp = NULL; | 1395 | UNIXCB(skb).fp = NULL; |
1398 | if (scm->fp && send_fds) | 1396 | if (scm->fp && send_fds) |
1399 | err = unix_attach_fds(scm, skb); | 1397 | err = unix_attach_fds(scm, skb); |
@@ -1410,13 +1408,13 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen | |||
1410 | static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, | 1408 | static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, |
1411 | const struct sock *other) | 1409 | const struct sock *other) |
1412 | { | 1410 | { |
1413 | if (UNIXCB(skb).cred) | 1411 | if (UNIXCB(skb).pid) |
1414 | return; | 1412 | return; |
1415 | if (test_bit(SOCK_PASSCRED, &sock->flags) || | 1413 | if (test_bit(SOCK_PASSCRED, &sock->flags) || |
1416 | !other->sk_socket || | 1414 | !other->sk_socket || |
1417 | test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { | 1415 | test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { |
1418 | UNIXCB(skb).pid = get_pid(task_tgid(current)); | 1416 | UNIXCB(skb).pid = get_pid(task_tgid(current)); |
1419 | UNIXCB(skb).cred = get_current_cred(); | 1417 | current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); |
1420 | } | 1418 | } |
1421 | } | 1419 | } |
1422 | 1420 | ||
@@ -1820,7 +1818,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1820 | siocb->scm = &tmp_scm; | 1818 | siocb->scm = &tmp_scm; |
1821 | memset(&tmp_scm, 0, sizeof(tmp_scm)); | 1819 | memset(&tmp_scm, 0, sizeof(tmp_scm)); |
1822 | } | 1820 | } |
1823 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); | 1821 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); |
1824 | unix_set_secdata(siocb->scm, skb); | 1822 | unix_set_secdata(siocb->scm, skb); |
1825 | 1823 | ||
1826 | if (!(flags & MSG_PEEK)) { | 1824 | if (!(flags & MSG_PEEK)) { |
@@ -1860,10 +1858,10 @@ out: | |||
1860 | } | 1858 | } |
1861 | 1859 | ||
1862 | /* | 1860 | /* |
1863 | * Sleep until data has arrive. But check for races.. | 1861 | * Sleep until more data has arrived. But check for races.. |
1864 | */ | 1862 | */ |
1865 | 1863 | static long unix_stream_data_wait(struct sock *sk, long timeo, | |
1866 | static long unix_stream_data_wait(struct sock *sk, long timeo) | 1864 | struct sk_buff *last) |
1867 | { | 1865 | { |
1868 | DEFINE_WAIT(wait); | 1866 | DEFINE_WAIT(wait); |
1869 | 1867 | ||
@@ -1872,7 +1870,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo) | |||
1872 | for (;;) { | 1870 | for (;;) { |
1873 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); | 1871 | prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1874 | 1872 | ||
1875 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 1873 | if (skb_peek_tail(&sk->sk_receive_queue) != last || |
1876 | sk->sk_err || | 1874 | sk->sk_err || |
1877 | (sk->sk_shutdown & RCV_SHUTDOWN) || | 1875 | (sk->sk_shutdown & RCV_SHUTDOWN) || |
1878 | signal_pending(current) || | 1876 | signal_pending(current) || |
@@ -1891,8 +1889,6 @@ static long unix_stream_data_wait(struct sock *sk, long timeo) | |||
1891 | return timeo; | 1889 | return timeo; |
1892 | } | 1890 | } |
1893 | 1891 | ||
1894 | |||
1895 | |||
1896 | static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | 1892 | static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, |
1897 | struct msghdr *msg, size_t size, | 1893 | struct msghdr *msg, size_t size, |
1898 | int flags) | 1894 | int flags) |
@@ -1937,14 +1933,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1937 | goto out; | 1933 | goto out; |
1938 | } | 1934 | } |
1939 | 1935 | ||
1940 | skip = sk_peek_offset(sk, flags); | ||
1941 | |||
1942 | do { | 1936 | do { |
1943 | int chunk; | 1937 | int chunk; |
1944 | struct sk_buff *skb; | 1938 | struct sk_buff *skb, *last; |
1945 | 1939 | ||
1946 | unix_state_lock(sk); | 1940 | unix_state_lock(sk); |
1947 | skb = skb_peek(&sk->sk_receive_queue); | 1941 | last = skb = skb_peek(&sk->sk_receive_queue); |
1948 | again: | 1942 | again: |
1949 | if (skb == NULL) { | 1943 | if (skb == NULL) { |
1950 | unix_sk(sk)->recursion_level = 0; | 1944 | unix_sk(sk)->recursion_level = 0; |
@@ -1967,7 +1961,7 @@ again: | |||
1967 | break; | 1961 | break; |
1968 | mutex_unlock(&u->readlock); | 1962 | mutex_unlock(&u->readlock); |
1969 | 1963 | ||
1970 | timeo = unix_stream_data_wait(sk, timeo); | 1964 | timeo = unix_stream_data_wait(sk, timeo, last); |
1971 | 1965 | ||
1972 | if (signal_pending(current) | 1966 | if (signal_pending(current) |
1973 | || mutex_lock_interruptible(&u->readlock)) { | 1967 | || mutex_lock_interruptible(&u->readlock)) { |
@@ -1981,10 +1975,13 @@ again: | |||
1981 | break; | 1975 | break; |
1982 | } | 1976 | } |
1983 | 1977 | ||
1984 | if (skip >= skb->len) { | 1978 | skip = sk_peek_offset(sk, flags); |
1979 | while (skip >= skb->len) { | ||
1985 | skip -= skb->len; | 1980 | skip -= skb->len; |
1981 | last = skb; | ||
1986 | skb = skb_peek_next(skb, &sk->sk_receive_queue); | 1982 | skb = skb_peek_next(skb, &sk->sk_receive_queue); |
1987 | goto again; | 1983 | if (!skb) |
1984 | goto again; | ||
1988 | } | 1985 | } |
1989 | 1986 | ||
1990 | unix_state_unlock(sk); | 1987 | unix_state_unlock(sk); |
@@ -1992,11 +1989,12 @@ again: | |||
1992 | if (check_creds) { | 1989 | if (check_creds) { |
1993 | /* Never glue messages from different writers */ | 1990 | /* Never glue messages from different writers */ |
1994 | if ((UNIXCB(skb).pid != siocb->scm->pid) || | 1991 | if ((UNIXCB(skb).pid != siocb->scm->pid) || |
1995 | (UNIXCB(skb).cred != siocb->scm->cred)) | 1992 | !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) || |
1993 | !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid)) | ||
1996 | break; | 1994 | break; |
1997 | } else { | 1995 | } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { |
1998 | /* Copy credentials */ | 1996 | /* Copy credentials */ |
1999 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); | 1997 | scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); |
2000 | check_creds = 1; | 1998 | check_creds = 1; |
2001 | } | 1999 | } |
2002 | 2000 | ||
@@ -2197,7 +2195,9 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock, | |||
2197 | 2195 | ||
2198 | /* exceptional events? */ | 2196 | /* exceptional events? */ |
2199 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | 2197 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) |
2200 | mask |= POLLERR; | 2198 | mask |= POLLERR | |
2199 | (sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0); | ||
2200 | |||
2201 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 2201 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
2202 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; | 2202 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
2203 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 2203 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
diff --git a/net/unix/garbage.c b/net/unix/garbage.c index d0f6545b0010..9bc73f87f64a 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c | |||
@@ -185,7 +185,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), | |||
185 | * have been added to the queues after | 185 | * have been added to the queues after |
186 | * starting the garbage collection | 186 | * starting the garbage collection |
187 | */ | 187 | */ |
188 | if (u->gc_candidate) { | 188 | if (test_bit(UNIX_GC_CANDIDATE, &u->gc_flags)) { |
189 | hit = true; | 189 | hit = true; |
190 | func(u); | 190 | func(u); |
191 | } | 191 | } |
@@ -254,7 +254,7 @@ static void inc_inflight_move_tail(struct unix_sock *u) | |||
254 | * of the list, so that it's checked even if it was already | 254 | * of the list, so that it's checked even if it was already |
255 | * passed over | 255 | * passed over |
256 | */ | 256 | */ |
257 | if (u->gc_maybe_cycle) | 257 | if (test_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags)) |
258 | list_move_tail(&u->link, &gc_candidates); | 258 | list_move_tail(&u->link, &gc_candidates); |
259 | } | 259 | } |
260 | 260 | ||
@@ -315,8 +315,8 @@ void unix_gc(void) | |||
315 | BUG_ON(total_refs < inflight_refs); | 315 | BUG_ON(total_refs < inflight_refs); |
316 | if (total_refs == inflight_refs) { | 316 | if (total_refs == inflight_refs) { |
317 | list_move_tail(&u->link, &gc_candidates); | 317 | list_move_tail(&u->link, &gc_candidates); |
318 | u->gc_candidate = 1; | 318 | __set_bit(UNIX_GC_CANDIDATE, &u->gc_flags); |
319 | u->gc_maybe_cycle = 1; | 319 | __set_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags); |
320 | } | 320 | } |
321 | } | 321 | } |
322 | 322 | ||
@@ -344,7 +344,7 @@ void unix_gc(void) | |||
344 | 344 | ||
345 | if (atomic_long_read(&u->inflight) > 0) { | 345 | if (atomic_long_read(&u->inflight) > 0) { |
346 | list_move_tail(&u->link, ¬_cycle_list); | 346 | list_move_tail(&u->link, ¬_cycle_list); |
347 | u->gc_maybe_cycle = 0; | 347 | __clear_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags); |
348 | scan_children(&u->sk, inc_inflight_move_tail, NULL); | 348 | scan_children(&u->sk, inc_inflight_move_tail, NULL); |
349 | } | 349 | } |
350 | } | 350 | } |
@@ -356,7 +356,7 @@ void unix_gc(void) | |||
356 | */ | 356 | */ |
357 | while (!list_empty(¬_cycle_list)) { | 357 | while (!list_empty(¬_cycle_list)) { |
358 | u = list_entry(not_cycle_list.next, struct unix_sock, link); | 358 | u = list_entry(not_cycle_list.next, struct unix_sock, link); |
359 | u->gc_candidate = 0; | 359 | __clear_bit(UNIX_GC_CANDIDATE, &u->gc_flags); |
360 | list_move_tail(&u->link, &gc_inflight_list); | 360 | list_move_tail(&u->link, &gc_inflight_list); |
361 | } | 361 | } |
362 | 362 | ||