aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2012-04-06 21:48:59 -0400
committerLen Brown <len.brown@intel.com>2012-04-06 21:48:59 -0400
commiteeaab2d8af2cf1d36d7086f22e9de42d6dd2995c (patch)
tree369b9c91a6d808944f07d2290fec6f9fe2731904 /net/unix/af_unix.c
parentee01e663373343c63e0e3d364d09f6155378dbcc (diff)
parentaaef292acf3a78d9c0bb6fb72226077d286b45d7 (diff)
Merge branches 'idle-fix' and 'misc' into release
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c91
1 files changed, 61 insertions, 30 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 85d3bb7490aa..d510353ef431 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -293,7 +293,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
293 spin_lock(&unix_table_lock); 293 spin_lock(&unix_table_lock);
294 sk_for_each(s, node, 294 sk_for_each(s, node,
295 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { 295 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
296 struct dentry *dentry = unix_sk(s)->dentry; 296 struct dentry *dentry = unix_sk(s)->path.dentry;
297 297
298 if (dentry && dentry->d_inode == i) { 298 if (dentry && dentry->d_inode == i) {
299 sock_hold(s); 299 sock_hold(s);
@@ -377,8 +377,7 @@ static void unix_sock_destructor(struct sock *sk)
377static int unix_release_sock(struct sock *sk, int embrion) 377static int unix_release_sock(struct sock *sk, int embrion)
378{ 378{
379 struct unix_sock *u = unix_sk(sk); 379 struct unix_sock *u = unix_sk(sk);
380 struct dentry *dentry; 380 struct path path;
381 struct vfsmount *mnt;
382 struct sock *skpair; 381 struct sock *skpair;
383 struct sk_buff *skb; 382 struct sk_buff *skb;
384 int state; 383 int state;
@@ -389,10 +388,9 @@ static int unix_release_sock(struct sock *sk, int embrion)
389 unix_state_lock(sk); 388 unix_state_lock(sk);
390 sock_orphan(sk); 389 sock_orphan(sk);
391 sk->sk_shutdown = SHUTDOWN_MASK; 390 sk->sk_shutdown = SHUTDOWN_MASK;
392 dentry = u->dentry; 391 path = u->path;
393 u->dentry = NULL; 392 u->path.dentry = NULL;
394 mnt = u->mnt; 393 u->path.mnt = NULL;
395 u->mnt = NULL;
396 state = sk->sk_state; 394 state = sk->sk_state;
397 sk->sk_state = TCP_CLOSE; 395 sk->sk_state = TCP_CLOSE;
398 unix_state_unlock(sk); 396 unix_state_unlock(sk);
@@ -425,10 +423,8 @@ static int unix_release_sock(struct sock *sk, int embrion)
425 kfree_skb(skb); 423 kfree_skb(skb);
426 } 424 }
427 425
428 if (dentry) { 426 if (path.dentry)
429 dput(dentry); 427 path_put(&path);
430 mntput(mnt);
431 }
432 428
433 sock_put(sk); 429 sock_put(sk);
434 430
@@ -530,6 +526,16 @@ static int unix_seqpacket_sendmsg(struct kiocb *, struct socket *,
530static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *, 526static int unix_seqpacket_recvmsg(struct kiocb *, struct socket *,
531 struct msghdr *, size_t, int); 527 struct msghdr *, size_t, int);
532 528
529static void unix_set_peek_off(struct sock *sk, int val)
530{
531 struct unix_sock *u = unix_sk(sk);
532
533 mutex_lock(&u->readlock);
534 sk->sk_peek_off = val;
535 mutex_unlock(&u->readlock);
536}
537
538
533static const struct proto_ops unix_stream_ops = { 539static const struct proto_ops unix_stream_ops = {
534 .family = PF_UNIX, 540 .family = PF_UNIX,
535 .owner = THIS_MODULE, 541 .owner = THIS_MODULE,
@@ -549,6 +555,7 @@ static const struct proto_ops unix_stream_ops = {
549 .recvmsg = unix_stream_recvmsg, 555 .recvmsg = unix_stream_recvmsg,
550 .mmap = sock_no_mmap, 556 .mmap = sock_no_mmap,
551 .sendpage = sock_no_sendpage, 557 .sendpage = sock_no_sendpage,
558 .set_peek_off = unix_set_peek_off,
552}; 559};
553 560
554static const struct proto_ops unix_dgram_ops = { 561static const struct proto_ops unix_dgram_ops = {
@@ -570,6 +577,7 @@ static const struct proto_ops unix_dgram_ops = {
570 .recvmsg = unix_dgram_recvmsg, 577 .recvmsg = unix_dgram_recvmsg,
571 .mmap = sock_no_mmap, 578 .mmap = sock_no_mmap,
572 .sendpage = sock_no_sendpage, 579 .sendpage = sock_no_sendpage,
580 .set_peek_off = unix_set_peek_off,
573}; 581};
574 582
575static const struct proto_ops unix_seqpacket_ops = { 583static const struct proto_ops unix_seqpacket_ops = {
@@ -591,6 +599,7 @@ static const struct proto_ops unix_seqpacket_ops = {
591 .recvmsg = unix_seqpacket_recvmsg, 599 .recvmsg = unix_seqpacket_recvmsg,
592 .mmap = sock_no_mmap, 600 .mmap = sock_no_mmap,
593 .sendpage = sock_no_sendpage, 601 .sendpage = sock_no_sendpage,
602 .set_peek_off = unix_set_peek_off,
594}; 603};
595 604
596static struct proto unix_proto = { 605static struct proto unix_proto = {
@@ -628,8 +637,8 @@ static struct sock *unix_create1(struct net *net, struct socket *sock)
628 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen; 637 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
629 sk->sk_destruct = unix_sock_destructor; 638 sk->sk_destruct = unix_sock_destructor;
630 u = unix_sk(sk); 639 u = unix_sk(sk);
631 u->dentry = NULL; 640 u->path.dentry = NULL;
632 u->mnt = NULL; 641 u->path.mnt = NULL;
633 spin_lock_init(&u->lock); 642 spin_lock_init(&u->lock);
634 atomic_long_set(&u->inflight, 0); 643 atomic_long_set(&u->inflight, 0);
635 INIT_LIST_HEAD(&u->link); 644 INIT_LIST_HEAD(&u->link);
@@ -775,7 +784,7 @@ static struct sock *unix_find_other(struct net *net,
775 goto put_fail; 784 goto put_fail;
776 785
777 if (u->sk_type == type) 786 if (u->sk_type == type)
778 touch_atime(path.mnt, path.dentry); 787 touch_atime(&path);
779 788
780 path_put(&path); 789 path_put(&path);
781 790
@@ -789,9 +798,9 @@ static struct sock *unix_find_other(struct net *net,
789 u = unix_find_socket_byname(net, sunname, len, type, hash); 798 u = unix_find_socket_byname(net, sunname, len, type, hash);
790 if (u) { 799 if (u) {
791 struct dentry *dentry; 800 struct dentry *dentry;
792 dentry = unix_sk(u)->dentry; 801 dentry = unix_sk(u)->path.dentry;
793 if (dentry) 802 if (dentry)
794 touch_atime(unix_sk(u)->mnt, dentry); 803 touch_atime(&unix_sk(u)->path);
795 } else 804 } else
796 goto fail; 805 goto fail;
797 } 806 }
@@ -897,8 +906,7 @@ out_mknod_drop_write:
897 list = &unix_socket_table[addr->hash]; 906 list = &unix_socket_table[addr->hash];
898 } else { 907 } else {
899 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)]; 908 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
900 u->dentry = path.dentry; 909 u->path = path;
901 u->mnt = path.mnt;
902 } 910 }
903 911
904 err = 0; 912 err = 0;
@@ -1180,9 +1188,9 @@ restart:
1180 atomic_inc(&otheru->addr->refcnt); 1188 atomic_inc(&otheru->addr->refcnt);
1181 newu->addr = otheru->addr; 1189 newu->addr = otheru->addr;
1182 } 1190 }
1183 if (otheru->dentry) { 1191 if (otheru->path.dentry) {
1184 newu->dentry = dget(otheru->dentry); 1192 path_get(&otheru->path);
1185 newu->mnt = mntget(otheru->mnt); 1193 newu->path = otheru->path;
1186 } 1194 }
1187 1195
1188 /* Set credentials */ 1196 /* Set credentials */
@@ -1756,6 +1764,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1756 int noblock = flags & MSG_DONTWAIT; 1764 int noblock = flags & MSG_DONTWAIT;
1757 struct sk_buff *skb; 1765 struct sk_buff *skb;
1758 int err; 1766 int err;
1767 int peeked, skip;
1759 1768
1760 err = -EOPNOTSUPP; 1769 err = -EOPNOTSUPP;
1761 if (flags&MSG_OOB) 1770 if (flags&MSG_OOB)
@@ -1769,7 +1778,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1769 goto out; 1778 goto out;
1770 } 1779 }
1771 1780
1772 skb = skb_recv_datagram(sk, flags, noblock, &err); 1781 skip = sk_peek_offset(sk, flags);
1782
1783 skb = __skb_recv_datagram(sk, flags, &peeked, &skip, &err);
1773 if (!skb) { 1784 if (!skb) {
1774 unix_state_lock(sk); 1785 unix_state_lock(sk);
1775 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */ 1786 /* Signal EOF on disconnected non-blocking SEQPACKET socket. */
@@ -1786,12 +1797,12 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1786 if (msg->msg_name) 1797 if (msg->msg_name)
1787 unix_copy_addr(msg, skb->sk); 1798 unix_copy_addr(msg, skb->sk);
1788 1799
1789 if (size > skb->len) 1800 if (size > skb->len - skip)
1790 size = skb->len; 1801 size = skb->len - skip;
1791 else if (size < skb->len) 1802 else if (size < skb->len - skip)
1792 msg->msg_flags |= MSG_TRUNC; 1803 msg->msg_flags |= MSG_TRUNC;
1793 1804
1794 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size); 1805 err = skb_copy_datagram_iovec(skb, skip, msg->msg_iov, size);
1795 if (err) 1806 if (err)
1796 goto out_free; 1807 goto out_free;
1797 1808
@@ -1808,6 +1819,8 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1808 if (!(flags & MSG_PEEK)) { 1819 if (!(flags & MSG_PEEK)) {
1809 if (UNIXCB(skb).fp) 1820 if (UNIXCB(skb).fp)
1810 unix_detach_fds(siocb->scm, skb); 1821 unix_detach_fds(siocb->scm, skb);
1822
1823 sk_peek_offset_bwd(sk, skb->len);
1811 } else { 1824 } else {
1812 /* It is questionable: on PEEK we could: 1825 /* It is questionable: on PEEK we could:
1813 - do not return fds - good, but too simple 8) 1826 - do not return fds - good, but too simple 8)
@@ -1821,10 +1834,13 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1821 clearly however! 1834 clearly however!
1822 1835
1823 */ 1836 */
1837
1838 sk_peek_offset_fwd(sk, size);
1839
1824 if (UNIXCB(skb).fp) 1840 if (UNIXCB(skb).fp)
1825 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); 1841 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
1826 } 1842 }
1827 err = size; 1843 err = (flags & MSG_TRUNC) ? skb->len - skip : size;
1828 1844
1829 scm_recv(sock, msg, siocb->scm, flags); 1845 scm_recv(sock, msg, siocb->scm, flags);
1830 1846
@@ -1884,6 +1900,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1884 int target; 1900 int target;
1885 int err = 0; 1901 int err = 0;
1886 long timeo; 1902 long timeo;
1903 int skip;
1887 1904
1888 err = -EINVAL; 1905 err = -EINVAL;
1889 if (sk->sk_state != TCP_ESTABLISHED) 1906 if (sk->sk_state != TCP_ESTABLISHED)
@@ -1913,12 +1930,15 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1913 goto out; 1930 goto out;
1914 } 1931 }
1915 1932
1933 skip = sk_peek_offset(sk, flags);
1934
1916 do { 1935 do {
1917 int chunk; 1936 int chunk;
1918 struct sk_buff *skb; 1937 struct sk_buff *skb;
1919 1938
1920 unix_state_lock(sk); 1939 unix_state_lock(sk);
1921 skb = skb_peek(&sk->sk_receive_queue); 1940 skb = skb_peek(&sk->sk_receive_queue);
1941again:
1922 if (skb == NULL) { 1942 if (skb == NULL) {
1923 unix_sk(sk)->recursion_level = 0; 1943 unix_sk(sk)->recursion_level = 0;
1924 if (copied >= target) 1944 if (copied >= target)
@@ -1953,6 +1973,13 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1953 unix_state_unlock(sk); 1973 unix_state_unlock(sk);
1954 break; 1974 break;
1955 } 1975 }
1976
1977 if (skip >= skb->len) {
1978 skip -= skb->len;
1979 skb = skb_peek_next(skb, &sk->sk_receive_queue);
1980 goto again;
1981 }
1982
1956 unix_state_unlock(sk); 1983 unix_state_unlock(sk);
1957 1984
1958 if (check_creds) { 1985 if (check_creds) {
@@ -1972,8 +1999,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1972 sunaddr = NULL; 1999 sunaddr = NULL;
1973 } 2000 }
1974 2001
1975 chunk = min_t(unsigned int, skb->len, size); 2002 chunk = min_t(unsigned int, skb->len - skip, size);
1976 if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { 2003 if (memcpy_toiovec(msg->msg_iov, skb->data + skip, chunk)) {
1977 if (copied == 0) 2004 if (copied == 0)
1978 copied = -EFAULT; 2005 copied = -EFAULT;
1979 break; 2006 break;
@@ -1985,6 +2012,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1985 if (!(flags & MSG_PEEK)) { 2012 if (!(flags & MSG_PEEK)) {
1986 skb_pull(skb, chunk); 2013 skb_pull(skb, chunk);
1987 2014
2015 sk_peek_offset_bwd(sk, chunk);
2016
1988 if (UNIXCB(skb).fp) 2017 if (UNIXCB(skb).fp)
1989 unix_detach_fds(siocb->scm, skb); 2018 unix_detach_fds(siocb->scm, skb);
1990 2019
@@ -2002,6 +2031,8 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
2002 if (UNIXCB(skb).fp) 2031 if (UNIXCB(skb).fp)
2003 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp); 2032 siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
2004 2033
2034 sk_peek_offset_fwd(sk, chunk);
2035
2005 break; 2036 break;
2006 } 2037 }
2007 } while (size); 2038 } while (size);
@@ -2175,7 +2206,7 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
2175 } 2206 }
2176 2207
2177 /* No write status requested, avoid expensive OUT tests. */ 2208 /* No write status requested, avoid expensive OUT tests. */
2178 if (wait && !(wait->key & (POLLWRBAND | POLLWRNORM | POLLOUT))) 2209 if (!(poll_requested_events(wait) & (POLLWRBAND|POLLWRNORM|POLLOUT)))
2179 return mask; 2210 return mask;
2180 2211
2181 writable = unix_writable(sk); 2212 writable = unix_writable(sk);