aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c101
1 files changed, 74 insertions, 27 deletions
diff --git a/net/socket.c b/net/socket.c
index 35dd7371752a..791d71a36a93 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -328,7 +328,7 @@ static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen)
328 dentry->d_inode->i_ino); 328 dentry->d_inode->i_ino);
329} 329}
330 330
331static struct dentry_operations sockfs_dentry_operations = { 331static const struct dentry_operations sockfs_dentry_operations = {
332 .d_delete = sockfs_delete_dentry, 332 .d_delete = sockfs_delete_dentry,
333 .d_dname = sockfs_dname, 333 .d_dname = sockfs_dname,
334}; 334};
@@ -493,8 +493,7 @@ static struct socket *sock_alloc(void)
493 inode->i_uid = current_fsuid(); 493 inode->i_uid = current_fsuid();
494 inode->i_gid = current_fsgid(); 494 inode->i_gid = current_fsgid();
495 495
496 get_cpu_var(sockets_in_use)++; 496 percpu_add(sockets_in_use, 1);
497 put_cpu_var(sockets_in_use);
498 return sock; 497 return sock;
499} 498}
500 499
@@ -536,8 +535,7 @@ void sock_release(struct socket *sock)
536 if (sock->fasync_list) 535 if (sock->fasync_list)
537 printk(KERN_ERR "sock_release: fasync list not empty!\n"); 536 printk(KERN_ERR "sock_release: fasync list not empty!\n");
538 537
539 get_cpu_var(sockets_in_use)--; 538 percpu_sub(sockets_in_use, 1);
540 put_cpu_var(sockets_in_use);
541 if (!sock->file) { 539 if (!sock->file) {
542 iput(SOCK_INODE(sock)); 540 iput(SOCK_INODE(sock));
543 return; 541 return;
@@ -545,6 +543,18 @@ void sock_release(struct socket *sock)
545 sock->file = NULL; 543 sock->file = NULL;
546} 544}
547 545
546int sock_tx_timestamp(struct msghdr *msg, struct sock *sk,
547 union skb_shared_tx *shtx)
548{
549 shtx->flags = 0;
550 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
551 shtx->hardware = 1;
552 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
553 shtx->software = 1;
554 return 0;
555}
556EXPORT_SYMBOL(sock_tx_timestamp);
557
548static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock, 558static inline int __sock_sendmsg(struct kiocb *iocb, struct socket *sock,
549 struct msghdr *msg, size_t size) 559 struct msghdr *msg, size_t size)
550{ 560{
@@ -595,33 +605,65 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
595 return result; 605 return result;
596} 606}
597 607
608static int ktime2ts(ktime_t kt, struct timespec *ts)
609{
610 if (kt.tv64) {
611 *ts = ktime_to_timespec(kt);
612 return 1;
613 } else {
614 return 0;
615 }
616}
617
598/* 618/*
599 * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP) 619 * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
600 */ 620 */
601void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, 621void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
602 struct sk_buff *skb) 622 struct sk_buff *skb)
603{ 623{
604 ktime_t kt = skb->tstamp; 624 int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
605 625 struct timespec ts[3];
606 if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) { 626 int empty = 1;
607 struct timeval tv; 627 struct skb_shared_hwtstamps *shhwtstamps =
608 /* Race occurred between timestamp enabling and packet 628 skb_hwtstamps(skb);
609 receiving. Fill in the current time for now. */ 629
610 if (kt.tv64 == 0) 630 /* Race occurred between timestamp enabling and packet
611 kt = ktime_get_real(); 631 receiving. Fill in the current time for now. */
612 skb->tstamp = kt; 632 if (need_software_tstamp && skb->tstamp.tv64 == 0)
613 tv = ktime_to_timeval(kt); 633 __net_timestamp(skb);
614 put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, sizeof(tv), &tv); 634
615 } else { 635 if (need_software_tstamp) {
616 struct timespec ts; 636 if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
617 /* Race occurred between timestamp enabling and packet 637 struct timeval tv;
618 receiving. Fill in the current time for now. */ 638 skb_get_timestamp(skb, &tv);
619 if (kt.tv64 == 0) 639 put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
620 kt = ktime_get_real(); 640 sizeof(tv), &tv);
621 skb->tstamp = kt; 641 } else {
622 ts = ktime_to_timespec(kt); 642 struct timespec ts;
623 put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, sizeof(ts), &ts); 643 skb_get_timestampns(skb, &ts);
644 put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
645 sizeof(ts), &ts);
646 }
647 }
648
649
650 memset(ts, 0, sizeof(ts));
651 if (skb->tstamp.tv64 &&
652 sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE)) {
653 skb_get_timestampns(skb, ts + 0);
654 empty = 0;
624 } 655 }
656 if (shhwtstamps) {
657 if (sock_flag(sk, SOCK_TIMESTAMPING_SYS_HARDWARE) &&
658 ktime2ts(shhwtstamps->syststamp, ts + 1))
659 empty = 0;
660 if (sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE) &&
661 ktime2ts(shhwtstamps->hwtstamp, ts + 2))
662 empty = 0;
663 }
664 if (!empty)
665 put_cmsg(msg, SOL_SOCKET,
666 SCM_TIMESTAMPING, sizeof(ts), &ts);
625} 667}
626 668
627EXPORT_SYMBOL_GPL(__sock_recv_timestamp); 669EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
@@ -1030,6 +1072,13 @@ static int sock_fasync(int fd, struct file *filp, int on)
1030 1072
1031 lock_sock(sk); 1073 lock_sock(sk);
1032 1074
1075 spin_lock(&filp->f_lock);
1076 if (on)
1077 filp->f_flags |= FASYNC;
1078 else
1079 filp->f_flags &= ~FASYNC;
1080 spin_unlock(&filp->f_lock);
1081
1033 prev = &(sock->fasync_list); 1082 prev = &(sock->fasync_list);
1034 1083
1035 for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev) 1084 for (fa = *prev; fa != NULL; prev = &fa->fa_next, fa = *prev)
@@ -1485,8 +1534,6 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
1485 fd_install(newfd, newfile); 1534 fd_install(newfd, newfile);
1486 err = newfd; 1535 err = newfd;
1487 1536
1488 security_socket_post_accept(sock, newsock);
1489
1490out_put: 1537out_put:
1491 fput_light(sock->file, fput_needed); 1538 fput_light(sock->file, fput_needed);
1492out: 1539out: