diff options
author | Arnd Bergmann <arnd@arndb.de> | 2019-04-17 16:51:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-04-19 17:07:40 -0400 |
commit | c7cbdbf29f488a19982cd9f4a109887f18028bbb (patch) | |
tree | 74b39321c14b93411eda0939683dc9b8b713717b | |
parent | 1ab839281cf72476988901a2606378d76530f99c (diff) |
net: rework SIOCGSTAMP ioctl handling
The SIOCGSTAMP/SIOCGSTAMPNS ioctl commands are implemented by many
socket protocol handlers, and all of those end up calling the same
sock_get_timestamp()/sock_get_timestampns() helper functions, which
results in a lot of duplicate code.
With the introduction of 64-bit time_t on 32-bit architectures, this
gets worse, as we then need four different ioctl commands in each
socket protocol implementation.
To simplify that, let's add a new .gettstamp() operation in
struct proto_ops, and move ioctl implementation into the common
sock_ioctl()/compat_sock_ioctl_trans() functions that these all go
through.
We can reuse the sock_get_timestamp() implementation, but generalize
it so it can deal with both native and compat mode, as well as
timeval and timespec structures.
Acked-by: Stefan Schmidt <stefan@datenfreihafen.org>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
Link: https://lore.kernel.org/lkml/CAK8P3a038aDQQotzua_QtKGhq8O9n+rdiz2=WDCp82ys8eUT+A@mail.gmail.com/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/net.h | 2 | ||||
-rw-r--r-- | include/net/compat.h | 3 | ||||
-rw-r--r-- | include/net/sock.h | 4 | ||||
-rw-r--r-- | net/appletalk/ddp.c | 7 | ||||
-rw-r--r-- | net/atm/ioctl.c | 16 | ||||
-rw-r--r-- | net/atm/pvc.c | 1 | ||||
-rw-r--r-- | net/atm/svc.c | 1 | ||||
-rw-r--r-- | net/ax25/af_ax25.c | 9 | ||||
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 8 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 1 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 1 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 1 | ||||
-rw-r--r-- | net/can/af_can.c | 6 | ||||
-rw-r--r-- | net/can/bcm.c | 1 | ||||
-rw-r--r-- | net/can/raw.c | 1 | ||||
-rw-r--r-- | net/compat.c | 57 | ||||
-rw-r--r-- | net/core/sock.c | 51 | ||||
-rw-r--r-- | net/dccp/ipv4.c | 1 | ||||
-rw-r--r-- | net/dccp/ipv6.c | 1 | ||||
-rw-r--r-- | net/ieee802154/socket.c | 6 | ||||
-rw-r--r-- | net/ipv4/af_inet.c | 9 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 8 | ||||
-rw-r--r-- | net/ipv6/raw.c | 1 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip.c | 1 | ||||
-rw-r--r-- | net/l2tp/l2tp_ip6.c | 1 | ||||
-rw-r--r-- | net/netrom/af_netrom.c | 14 | ||||
-rw-r--r-- | net/packet/af_packet.c | 7 | ||||
-rw-r--r-- | net/qrtr/qrtr.c | 4 | ||||
-rw-r--r-- | net/rose/af_rose.c | 7 | ||||
-rw-r--r-- | net/sctp/ipv6.c | 1 | ||||
-rw-r--r-- | net/sctp/protocol.c | 1 | ||||
-rw-r--r-- | net/socket.c | 48 | ||||
-rw-r--r-- | net/x25/af_x25.c | 27 |
33 files changed, 75 insertions, 232 deletions
diff --git a/include/linux/net.h b/include/linux/net.h index c606c72311d0..50bf5206ead6 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -161,6 +161,8 @@ struct proto_ops { | |||
161 | int (*compat_ioctl) (struct socket *sock, unsigned int cmd, | 161 | int (*compat_ioctl) (struct socket *sock, unsigned int cmd, |
162 | unsigned long arg); | 162 | unsigned long arg); |
163 | #endif | 163 | #endif |
164 | int (*gettstamp) (struct socket *sock, void __user *userstamp, | ||
165 | bool timeval, bool time32); | ||
164 | int (*listen) (struct socket *sock, int len); | 166 | int (*listen) (struct socket *sock, int len); |
165 | int (*shutdown) (struct socket *sock, int flags); | 167 | int (*shutdown) (struct socket *sock, int flags); |
166 | int (*setsockopt)(struct socket *sock, int level, | 168 | int (*setsockopt)(struct socket *sock, int level, |
diff --git a/include/net/compat.h b/include/net/compat.h index 4c6d75612b6c..f277653c7e17 100644 --- a/include/net/compat.h +++ b/include/net/compat.h | |||
@@ -30,9 +30,6 @@ struct compat_cmsghdr { | |||
30 | compat_int_t cmsg_type; | 30 | compat_int_t cmsg_type; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | int compat_sock_get_timestamp(struct sock *, struct timeval __user *); | ||
34 | int compat_sock_get_timestampns(struct sock *, struct timespec __user *); | ||
35 | |||
36 | #else /* defined(CONFIG_COMPAT) */ | 33 | #else /* defined(CONFIG_COMPAT) */ |
37 | /* | 34 | /* |
38 | * To avoid compiler warnings: | 35 | * To avoid compiler warnings: |
diff --git a/include/net/sock.h b/include/net/sock.h index bdd77bbce7d8..784cd19d5ff7 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -1614,6 +1614,8 @@ int sock_setsockopt(struct socket *sock, int level, int op, | |||
1614 | 1614 | ||
1615 | int sock_getsockopt(struct socket *sock, int level, int op, | 1615 | int sock_getsockopt(struct socket *sock, int level, int op, |
1616 | char __user *optval, int __user *optlen); | 1616 | char __user *optval, int __user *optlen); |
1617 | int sock_gettstamp(struct socket *sock, void __user *userstamp, | ||
1618 | bool timeval, bool time32); | ||
1617 | struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, | 1619 | struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, |
1618 | int noblock, int *errcode); | 1620 | int noblock, int *errcode); |
1619 | struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, | 1621 | struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, |
@@ -2503,8 +2505,6 @@ static inline bool sk_listener(const struct sock *sk) | |||
2503 | } | 2505 | } |
2504 | 2506 | ||
2505 | void sock_enable_timestamp(struct sock *sk, int flag); | 2507 | void sock_enable_timestamp(struct sock *sk, int flag); |
2506 | int sock_get_timestamp(struct sock *, struct timeval __user *); | ||
2507 | int sock_get_timestampns(struct sock *, struct timespec __user *); | ||
2508 | int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level, | 2508 | int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level, |
2509 | int type); | 2509 | int type); |
2510 | 2510 | ||
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 709d2542f729..e2511027d19b 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -1806,12 +1806,6 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1806 | rc = put_user(amount, (int __user *)argp); | 1806 | rc = put_user(amount, (int __user *)argp); |
1807 | break; | 1807 | break; |
1808 | } | 1808 | } |
1809 | case SIOCGSTAMP: | ||
1810 | rc = sock_get_timestamp(sk, argp); | ||
1811 | break; | ||
1812 | case SIOCGSTAMPNS: | ||
1813 | rc = sock_get_timestampns(sk, argp); | ||
1814 | break; | ||
1815 | /* Routing */ | 1809 | /* Routing */ |
1816 | case SIOCADDRT: | 1810 | case SIOCADDRT: |
1817 | case SIOCDELRT: | 1811 | case SIOCDELRT: |
@@ -1871,6 +1865,7 @@ static const struct proto_ops atalk_dgram_ops = { | |||
1871 | .getname = atalk_getname, | 1865 | .getname = atalk_getname, |
1872 | .poll = datagram_poll, | 1866 | .poll = datagram_poll, |
1873 | .ioctl = atalk_ioctl, | 1867 | .ioctl = atalk_ioctl, |
1868 | .gettstamp = sock_gettstamp, | ||
1874 | #ifdef CONFIG_COMPAT | 1869 | #ifdef CONFIG_COMPAT |
1875 | .compat_ioctl = atalk_compat_ioctl, | 1870 | .compat_ioctl = atalk_compat_ioctl, |
1876 | #endif | 1871 | #endif |
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c index 2ff0e5e470e3..d955b683aa7c 100644 --- a/net/atm/ioctl.c +++ b/net/atm/ioctl.c | |||
@@ -81,22 +81,6 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd, | |||
81 | (int __user *)argp) ? -EFAULT : 0; | 81 | (int __user *)argp) ? -EFAULT : 0; |
82 | goto done; | 82 | goto done; |
83 | } | 83 | } |
84 | case SIOCGSTAMP: /* borrowed from IP */ | ||
85 | #ifdef CONFIG_COMPAT | ||
86 | if (compat) | ||
87 | error = compat_sock_get_timestamp(sk, argp); | ||
88 | else | ||
89 | #endif | ||
90 | error = sock_get_timestamp(sk, argp); | ||
91 | goto done; | ||
92 | case SIOCGSTAMPNS: /* borrowed from IP */ | ||
93 | #ifdef CONFIG_COMPAT | ||
94 | if (compat) | ||
95 | error = compat_sock_get_timestampns(sk, argp); | ||
96 | else | ||
97 | #endif | ||
98 | error = sock_get_timestampns(sk, argp); | ||
99 | goto done; | ||
100 | case ATM_SETSC: | 84 | case ATM_SETSC: |
101 | net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n", | 85 | net_warn_ratelimited("ATM_SETSC is obsolete; used by %s:%d\n", |
102 | current->comm, task_pid_nr(current)); | 86 | current->comm, task_pid_nr(current)); |
diff --git a/net/atm/pvc.c b/net/atm/pvc.c index 2cb10af16afc..02bd2a436bdf 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c | |||
@@ -118,6 +118,7 @@ static const struct proto_ops pvc_proto_ops = { | |||
118 | #ifdef CONFIG_COMPAT | 118 | #ifdef CONFIG_COMPAT |
119 | .compat_ioctl = vcc_compat_ioctl, | 119 | .compat_ioctl = vcc_compat_ioctl, |
120 | #endif | 120 | #endif |
121 | .gettstamp = sock_gettstamp, | ||
121 | .listen = sock_no_listen, | 122 | .listen = sock_no_listen, |
122 | .shutdown = pvc_shutdown, | 123 | .shutdown = pvc_shutdown, |
123 | .setsockopt = pvc_setsockopt, | 124 | .setsockopt = pvc_setsockopt, |
diff --git a/net/atm/svc.c b/net/atm/svc.c index 2f91b766ac42..908cbb8654f5 100644 --- a/net/atm/svc.c +++ b/net/atm/svc.c | |||
@@ -641,6 +641,7 @@ static const struct proto_ops svc_proto_ops = { | |||
641 | #ifdef CONFIG_COMPAT | 641 | #ifdef CONFIG_COMPAT |
642 | .compat_ioctl = svc_compat_ioctl, | 642 | .compat_ioctl = svc_compat_ioctl, |
643 | #endif | 643 | #endif |
644 | .gettstamp = sock_gettstamp, | ||
644 | .listen = svc_listen, | 645 | .listen = svc_listen, |
645 | .shutdown = svc_shutdown, | 646 | .shutdown = svc_shutdown, |
646 | .setsockopt = svc_setsockopt, | 647 | .setsockopt = svc_setsockopt, |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 5d01edf8d819..449e7b7190c1 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -1714,14 +1714,6 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1714 | break; | 1714 | break; |
1715 | } | 1715 | } |
1716 | 1716 | ||
1717 | case SIOCGSTAMP: | ||
1718 | res = sock_get_timestamp(sk, argp); | ||
1719 | break; | ||
1720 | |||
1721 | case SIOCGSTAMPNS: | ||
1722 | res = sock_get_timestampns(sk, argp); | ||
1723 | break; | ||
1724 | |||
1725 | case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */ | 1717 | case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */ |
1726 | case SIOCAX25DELUID: /* Delete a uid from the uid/call map table */ | 1718 | case SIOCAX25DELUID: /* Delete a uid from the uid/call map table */ |
1727 | case SIOCAX25GETUID: { | 1719 | case SIOCAX25GETUID: { |
@@ -1950,6 +1942,7 @@ static const struct proto_ops ax25_proto_ops = { | |||
1950 | .getname = ax25_getname, | 1942 | .getname = ax25_getname, |
1951 | .poll = datagram_poll, | 1943 | .poll = datagram_poll, |
1952 | .ioctl = ax25_ioctl, | 1944 | .ioctl = ax25_ioctl, |
1945 | .gettstamp = sock_gettstamp, | ||
1953 | .listen = ax25_listen, | 1946 | .listen = ax25_listen, |
1954 | .shutdown = ax25_shutdown, | 1947 | .shutdown = ax25_shutdown, |
1955 | .setsockopt = ax25_setsockopt, | 1948 | .setsockopt = ax25_setsockopt, |
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 8d12198eaa94..94ddf19998c7 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -521,14 +521,6 @@ int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
521 | err = put_user(amount, (int __user *) arg); | 521 | err = put_user(amount, (int __user *) arg); |
522 | break; | 522 | break; |
523 | 523 | ||
524 | case SIOCGSTAMP: | ||
525 | err = sock_get_timestamp(sk, (struct timeval __user *) arg); | ||
526 | break; | ||
527 | |||
528 | case SIOCGSTAMPNS: | ||
529 | err = sock_get_timestampns(sk, (struct timespec __user *) arg); | ||
530 | break; | ||
531 | |||
532 | default: | 524 | default: |
533 | err = -ENOIOCTLCMD; | 525 | err = -ENOIOCTLCMD; |
534 | break; | 526 | break; |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index a3a2cd55e23a..dcb14abebeba 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -1655,6 +1655,7 @@ static const struct proto_ops l2cap_sock_ops = { | |||
1655 | .recvmsg = l2cap_sock_recvmsg, | 1655 | .recvmsg = l2cap_sock_recvmsg, |
1656 | .poll = bt_sock_poll, | 1656 | .poll = bt_sock_poll, |
1657 | .ioctl = bt_sock_ioctl, | 1657 | .ioctl = bt_sock_ioctl, |
1658 | .gettstamp = sock_gettstamp, | ||
1658 | .mmap = sock_no_mmap, | 1659 | .mmap = sock_no_mmap, |
1659 | .socketpair = sock_no_socketpair, | 1660 | .socketpair = sock_no_socketpair, |
1660 | .shutdown = l2cap_sock_shutdown, | 1661 | .shutdown = l2cap_sock_shutdown, |
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index b1f49fcc0478..90bb53aa4bee 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -1039,6 +1039,7 @@ static const struct proto_ops rfcomm_sock_ops = { | |||
1039 | .setsockopt = rfcomm_sock_setsockopt, | 1039 | .setsockopt = rfcomm_sock_setsockopt, |
1040 | .getsockopt = rfcomm_sock_getsockopt, | 1040 | .getsockopt = rfcomm_sock_getsockopt, |
1041 | .ioctl = rfcomm_sock_ioctl, | 1041 | .ioctl = rfcomm_sock_ioctl, |
1042 | .gettstamp = sock_gettstamp, | ||
1042 | .poll = bt_sock_poll, | 1043 | .poll = bt_sock_poll, |
1043 | .socketpair = sock_no_socketpair, | 1044 | .socketpair = sock_no_socketpair, |
1044 | .mmap = sock_no_mmap | 1045 | .mmap = sock_no_mmap |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index d892b7c3cc42..b91d6b440fdf 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -1190,6 +1190,7 @@ static const struct proto_ops sco_sock_ops = { | |||
1190 | .recvmsg = sco_sock_recvmsg, | 1190 | .recvmsg = sco_sock_recvmsg, |
1191 | .poll = bt_sock_poll, | 1191 | .poll = bt_sock_poll, |
1192 | .ioctl = bt_sock_ioctl, | 1192 | .ioctl = bt_sock_ioctl, |
1193 | .gettstamp = sock_gettstamp, | ||
1193 | .mmap = sock_no_mmap, | 1194 | .mmap = sock_no_mmap, |
1194 | .socketpair = sock_no_socketpair, | 1195 | .socketpair = sock_no_socketpair, |
1195 | .shutdown = sco_sock_shutdown, | 1196 | .shutdown = sco_sock_shutdown, |
diff --git a/net/can/af_can.c b/net/can/af_can.c index 1684ba5b51eb..e8fd5dc1780a 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -89,13 +89,7 @@ static atomic_t skbcounter = ATOMIC_INIT(0); | |||
89 | 89 | ||
90 | int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 90 | int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
91 | { | 91 | { |
92 | struct sock *sk = sock->sk; | ||
93 | |||
94 | switch (cmd) { | 92 | switch (cmd) { |
95 | |||
96 | case SIOCGSTAMP: | ||
97 | return sock_get_timestamp(sk, (struct timeval __user *)arg); | ||
98 | |||
99 | default: | 93 | default: |
100 | return -ENOIOCTLCMD; | 94 | return -ENOIOCTLCMD; |
101 | } | 95 | } |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 79bb8afa9c0c..a34ee52f19ea 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -1689,6 +1689,7 @@ static const struct proto_ops bcm_ops = { | |||
1689 | .getname = sock_no_getname, | 1689 | .getname = sock_no_getname, |
1690 | .poll = datagram_poll, | 1690 | .poll = datagram_poll, |
1691 | .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ | 1691 | .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ |
1692 | .gettstamp = sock_gettstamp, | ||
1692 | .listen = sock_no_listen, | 1693 | .listen = sock_no_listen, |
1693 | .shutdown = sock_no_shutdown, | 1694 | .shutdown = sock_no_shutdown, |
1694 | .setsockopt = sock_no_setsockopt, | 1695 | .setsockopt = sock_no_setsockopt, |
diff --git a/net/can/raw.c b/net/can/raw.c index c70207537488..afcbff063a67 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -846,6 +846,7 @@ static const struct proto_ops raw_ops = { | |||
846 | .getname = raw_getname, | 846 | .getname = raw_getname, |
847 | .poll = datagram_poll, | 847 | .poll = datagram_poll, |
848 | .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ | 848 | .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */ |
849 | .gettstamp = sock_gettstamp, | ||
849 | .listen = sock_no_listen, | 850 | .listen = sock_no_listen, |
850 | .shutdown = sock_no_shutdown, | 851 | .shutdown = sock_no_shutdown, |
851 | .setsockopt = raw_setsockopt, | 852 | .setsockopt = raw_setsockopt, |
diff --git a/net/compat.c b/net/compat.c index eeea5eb71639..a031bd333092 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -395,63 +395,6 @@ COMPAT_SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, | |||
395 | return __compat_sys_setsockopt(fd, level, optname, optval, optlen); | 395 | return __compat_sys_setsockopt(fd, level, optname, optval, optlen); |
396 | } | 396 | } |
397 | 397 | ||
398 | int compat_sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) | ||
399 | { | ||
400 | struct compat_timeval __user *ctv; | ||
401 | int err; | ||
402 | struct timeval tv; | ||
403 | |||
404 | if (COMPAT_USE_64BIT_TIME) | ||
405 | return sock_get_timestamp(sk, userstamp); | ||
406 | |||
407 | ctv = (struct compat_timeval __user *) userstamp; | ||
408 | err = -ENOENT; | ||
409 | sock_enable_timestamp(sk, SOCK_TIMESTAMP); | ||
410 | tv = ktime_to_timeval(sock_read_timestamp(sk)); | ||
411 | |||
412 | if (tv.tv_sec == -1) | ||
413 | return err; | ||
414 | if (tv.tv_sec == 0) { | ||
415 | ktime_t kt = ktime_get_real(); | ||
416 | sock_write_timestamp(sk, kt); | ||
417 | tv = ktime_to_timeval(kt); | ||
418 | } | ||
419 | err = 0; | ||
420 | if (put_user(tv.tv_sec, &ctv->tv_sec) || | ||
421 | put_user(tv.tv_usec, &ctv->tv_usec)) | ||
422 | err = -EFAULT; | ||
423 | return err; | ||
424 | } | ||
425 | EXPORT_SYMBOL(compat_sock_get_timestamp); | ||
426 | |||
427 | int compat_sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp) | ||
428 | { | ||
429 | struct compat_timespec __user *ctv; | ||
430 | int err; | ||
431 | struct timespec ts; | ||
432 | |||
433 | if (COMPAT_USE_64BIT_TIME) | ||
434 | return sock_get_timestampns (sk, userstamp); | ||
435 | |||
436 | ctv = (struct compat_timespec __user *) userstamp; | ||
437 | err = -ENOENT; | ||
438 | sock_enable_timestamp(sk, SOCK_TIMESTAMP); | ||
439 | ts = ktime_to_timespec(sock_read_timestamp(sk)); | ||
440 | if (ts.tv_sec == -1) | ||
441 | return err; | ||
442 | if (ts.tv_sec == 0) { | ||
443 | ktime_t kt = ktime_get_real(); | ||
444 | sock_write_timestamp(sk, kt); | ||
445 | ts = ktime_to_timespec(kt); | ||
446 | } | ||
447 | err = 0; | ||
448 | if (put_user(ts.tv_sec, &ctv->tv_sec) || | ||
449 | put_user(ts.tv_nsec, &ctv->tv_nsec)) | ||
450 | err = -EFAULT; | ||
451 | return err; | ||
452 | } | ||
453 | EXPORT_SYMBOL(compat_sock_get_timestampns); | ||
454 | |||
455 | static int __compat_sys_getsockopt(int fd, int level, int optname, | 398 | static int __compat_sys_getsockopt(int fd, int level, int optname, |
456 | char __user *optval, | 399 | char __user *optval, |
457 | int __user *optlen) | 400 | int __user *optlen) |
diff --git a/net/core/sock.c b/net/core/sock.c index 067878a1e4c5..443b98d05f1e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -2977,39 +2977,44 @@ bool lock_sock_fast(struct sock *sk) | |||
2977 | } | 2977 | } |
2978 | EXPORT_SYMBOL(lock_sock_fast); | 2978 | EXPORT_SYMBOL(lock_sock_fast); |
2979 | 2979 | ||
2980 | int sock_get_timestamp(struct sock *sk, struct timeval __user *userstamp) | 2980 | int sock_gettstamp(struct socket *sock, void __user *userstamp, |
2981 | bool timeval, bool time32) | ||
2981 | { | 2982 | { |
2982 | struct timeval tv; | 2983 | struct sock *sk = sock->sk; |
2984 | struct timespec64 ts; | ||
2983 | 2985 | ||
2984 | sock_enable_timestamp(sk, SOCK_TIMESTAMP); | 2986 | sock_enable_timestamp(sk, SOCK_TIMESTAMP); |
2985 | tv = ktime_to_timeval(sock_read_timestamp(sk)); | 2987 | ts = ktime_to_timespec64(sock_read_timestamp(sk)); |
2986 | if (tv.tv_sec == -1) | 2988 | if (ts.tv_sec == -1) |
2987 | return -ENOENT; | 2989 | return -ENOENT; |
2988 | if (tv.tv_sec == 0) { | 2990 | if (ts.tv_sec == 0) { |
2989 | ktime_t kt = ktime_get_real(); | 2991 | ktime_t kt = ktime_get_real(); |
2990 | sock_write_timestamp(sk, kt); | 2992 | sock_write_timestamp(sk, kt);; |
2991 | tv = ktime_to_timeval(kt); | 2993 | ts = ktime_to_timespec64(kt); |
2992 | } | 2994 | } |
2993 | return copy_to_user(userstamp, &tv, sizeof(tv)) ? -EFAULT : 0; | ||
2994 | } | ||
2995 | EXPORT_SYMBOL(sock_get_timestamp); | ||
2996 | 2995 | ||
2997 | int sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp) | 2996 | if (timeval) |
2998 | { | 2997 | ts.tv_nsec /= 1000; |
2999 | struct timespec ts; | ||
3000 | 2998 | ||
3001 | sock_enable_timestamp(sk, SOCK_TIMESTAMP); | 2999 | #ifdef CONFIG_COMPAT_32BIT_TIME |
3002 | ts = ktime_to_timespec(sock_read_timestamp(sk)); | 3000 | if (time32) |
3003 | if (ts.tv_sec == -1) | 3001 | return put_old_timespec32(&ts, userstamp); |
3004 | return -ENOENT; | 3002 | #endif |
3005 | if (ts.tv_sec == 0) { | 3003 | #ifdef CONFIG_SPARC64 |
3006 | ktime_t kt = ktime_get_real(); | 3004 | /* beware of padding in sparc64 timeval */ |
3007 | sock_write_timestamp(sk, kt); | 3005 | if (timeval && !in_compat_syscall()) { |
3008 | ts = ktime_to_timespec(sk->sk_stamp); | 3006 | struct __kernel_old_timeval __user tv = { |
3007 | .tv_sec = ts.tv_sec; | ||
3008 | .tv_usec = ts.tv_nsec; | ||
3009 | }; | ||
3010 | if (copy_to_user(userstamp, &tv, sizeof(tv)) | ||
3011 | return -EFAULT; | ||
3012 | return 0; | ||
3009 | } | 3013 | } |
3010 | return copy_to_user(userstamp, &ts, sizeof(ts)) ? -EFAULT : 0; | 3014 | #endif |
3015 | return put_timespec64(&ts, userstamp); | ||
3011 | } | 3016 | } |
3012 | EXPORT_SYMBOL(sock_get_timestampns); | 3017 | EXPORT_SYMBOL(sock_gettstamp); |
3013 | 3018 | ||
3014 | void sock_enable_timestamp(struct sock *sk, int flag) | 3019 | void sock_enable_timestamp(struct sock *sk, int flag) |
3015 | { | 3020 | { |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 26a21d97b6b0..004535e4c070 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -991,6 +991,7 @@ static const struct proto_ops inet_dccp_ops = { | |||
991 | /* FIXME: work on tcp_poll to rename it to inet_csk_poll */ | 991 | /* FIXME: work on tcp_poll to rename it to inet_csk_poll */ |
992 | .poll = dccp_poll, | 992 | .poll = dccp_poll, |
993 | .ioctl = inet_ioctl, | 993 | .ioctl = inet_ioctl, |
994 | .gettstamp = sock_gettstamp, | ||
994 | /* FIXME: work on inet_listen to rename it to sock_common_listen */ | 995 | /* FIXME: work on inet_listen to rename it to sock_common_listen */ |
995 | .listen = inet_dccp_listen, | 996 | .listen = inet_dccp_listen, |
996 | .shutdown = inet_shutdown, | 997 | .shutdown = inet_shutdown, |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 57d84e9b7b6f..c4e4d1301062 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -1075,6 +1075,7 @@ static const struct proto_ops inet6_dccp_ops = { | |||
1075 | .getname = inet6_getname, | 1075 | .getname = inet6_getname, |
1076 | .poll = dccp_poll, | 1076 | .poll = dccp_poll, |
1077 | .ioctl = inet6_ioctl, | 1077 | .ioctl = inet6_ioctl, |
1078 | .gettstamp = sock_gettstamp, | ||
1078 | .listen = inet_dccp_listen, | 1079 | .listen = inet_dccp_listen, |
1079 | .shutdown = inet_shutdown, | 1080 | .shutdown = inet_shutdown, |
1080 | .setsockopt = sock_common_setsockopt, | 1081 | .setsockopt = sock_common_setsockopt, |
diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c index bc6b912603f1..ce2dfb997537 100644 --- a/net/ieee802154/socket.c +++ b/net/ieee802154/socket.c | |||
@@ -164,10 +164,6 @@ static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd, | |||
164 | struct sock *sk = sock->sk; | 164 | struct sock *sk = sock->sk; |
165 | 165 | ||
166 | switch (cmd) { | 166 | switch (cmd) { |
167 | case SIOCGSTAMP: | ||
168 | return sock_get_timestamp(sk, (struct timeval __user *)arg); | ||
169 | case SIOCGSTAMPNS: | ||
170 | return sock_get_timestampns(sk, (struct timespec __user *)arg); | ||
171 | case SIOCGIFADDR: | 167 | case SIOCGIFADDR: |
172 | case SIOCSIFADDR: | 168 | case SIOCSIFADDR: |
173 | return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg, | 169 | return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg, |
@@ -426,6 +422,7 @@ static const struct proto_ops ieee802154_raw_ops = { | |||
426 | .getname = sock_no_getname, | 422 | .getname = sock_no_getname, |
427 | .poll = datagram_poll, | 423 | .poll = datagram_poll, |
428 | .ioctl = ieee802154_sock_ioctl, | 424 | .ioctl = ieee802154_sock_ioctl, |
425 | .gettstamp = sock_gettstamp, | ||
429 | .listen = sock_no_listen, | 426 | .listen = sock_no_listen, |
430 | .shutdown = sock_no_shutdown, | 427 | .shutdown = sock_no_shutdown, |
431 | .setsockopt = sock_common_setsockopt, | 428 | .setsockopt = sock_common_setsockopt, |
@@ -988,6 +985,7 @@ static const struct proto_ops ieee802154_dgram_ops = { | |||
988 | .getname = sock_no_getname, | 985 | .getname = sock_no_getname, |
989 | .poll = datagram_poll, | 986 | .poll = datagram_poll, |
990 | .ioctl = ieee802154_sock_ioctl, | 987 | .ioctl = ieee802154_sock_ioctl, |
988 | .gettstamp = sock_gettstamp, | ||
991 | .listen = sock_no_listen, | 989 | .listen = sock_no_listen, |
992 | .shutdown = sock_no_shutdown, | 990 | .shutdown = sock_no_shutdown, |
993 | .setsockopt = sock_common_setsockopt, | 991 | .setsockopt = sock_common_setsockopt, |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 08a8430f5647..5183a2daba64 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -915,12 +915,6 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
915 | struct rtentry rt; | 915 | struct rtentry rt; |
916 | 916 | ||
917 | switch (cmd) { | 917 | switch (cmd) { |
918 | case SIOCGSTAMP: | ||
919 | err = sock_get_timestamp(sk, (struct timeval __user *)arg); | ||
920 | break; | ||
921 | case SIOCGSTAMPNS: | ||
922 | err = sock_get_timestampns(sk, (struct timespec __user *)arg); | ||
923 | break; | ||
924 | case SIOCADDRT: | 918 | case SIOCADDRT: |
925 | case SIOCDELRT: | 919 | case SIOCDELRT: |
926 | if (copy_from_user(&rt, p, sizeof(struct rtentry))) | 920 | if (copy_from_user(&rt, p, sizeof(struct rtentry))) |
@@ -992,6 +986,7 @@ const struct proto_ops inet_stream_ops = { | |||
992 | .getname = inet_getname, | 986 | .getname = inet_getname, |
993 | .poll = tcp_poll, | 987 | .poll = tcp_poll, |
994 | .ioctl = inet_ioctl, | 988 | .ioctl = inet_ioctl, |
989 | .gettstamp = sock_gettstamp, | ||
995 | .listen = inet_listen, | 990 | .listen = inet_listen, |
996 | .shutdown = inet_shutdown, | 991 | .shutdown = inet_shutdown, |
997 | .setsockopt = sock_common_setsockopt, | 992 | .setsockopt = sock_common_setsockopt, |
@@ -1027,6 +1022,7 @@ const struct proto_ops inet_dgram_ops = { | |||
1027 | .getname = inet_getname, | 1022 | .getname = inet_getname, |
1028 | .poll = udp_poll, | 1023 | .poll = udp_poll, |
1029 | .ioctl = inet_ioctl, | 1024 | .ioctl = inet_ioctl, |
1025 | .gettstamp = sock_gettstamp, | ||
1030 | .listen = sock_no_listen, | 1026 | .listen = sock_no_listen, |
1031 | .shutdown = inet_shutdown, | 1027 | .shutdown = inet_shutdown, |
1032 | .setsockopt = sock_common_setsockopt, | 1028 | .setsockopt = sock_common_setsockopt, |
@@ -1059,6 +1055,7 @@ static const struct proto_ops inet_sockraw_ops = { | |||
1059 | .getname = inet_getname, | 1055 | .getname = inet_getname, |
1060 | .poll = datagram_poll, | 1056 | .poll = datagram_poll, |
1061 | .ioctl = inet_ioctl, | 1057 | .ioctl = inet_ioctl, |
1058 | .gettstamp = sock_gettstamp, | ||
1062 | .listen = sock_no_listen, | 1059 | .listen = sock_no_listen, |
1063 | .shutdown = inet_shutdown, | 1060 | .shutdown = inet_shutdown, |
1064 | .setsockopt = sock_common_setsockopt, | 1061 | .setsockopt = sock_common_setsockopt, |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 3d1de28aaa9e..c04ae282f4e4 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -547,12 +547,6 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
547 | struct net *net = sock_net(sk); | 547 | struct net *net = sock_net(sk); |
548 | 548 | ||
549 | switch (cmd) { | 549 | switch (cmd) { |
550 | case SIOCGSTAMP: | ||
551 | return sock_get_timestamp(sk, (struct timeval __user *)arg); | ||
552 | |||
553 | case SIOCGSTAMPNS: | ||
554 | return sock_get_timestampns(sk, (struct timespec __user *)arg); | ||
555 | |||
556 | case SIOCADDRT: | 550 | case SIOCADDRT: |
557 | case SIOCDELRT: | 551 | case SIOCDELRT: |
558 | 552 | ||
@@ -585,6 +579,7 @@ const struct proto_ops inet6_stream_ops = { | |||
585 | .getname = inet6_getname, | 579 | .getname = inet6_getname, |
586 | .poll = tcp_poll, /* ok */ | 580 | .poll = tcp_poll, /* ok */ |
587 | .ioctl = inet6_ioctl, /* must change */ | 581 | .ioctl = inet6_ioctl, /* must change */ |
582 | .gettstamp = sock_gettstamp, | ||
588 | .listen = inet_listen, /* ok */ | 583 | .listen = inet_listen, /* ok */ |
589 | .shutdown = inet_shutdown, /* ok */ | 584 | .shutdown = inet_shutdown, /* ok */ |
590 | .setsockopt = sock_common_setsockopt, /* ok */ | 585 | .setsockopt = sock_common_setsockopt, /* ok */ |
@@ -618,6 +613,7 @@ const struct proto_ops inet6_dgram_ops = { | |||
618 | .getname = inet6_getname, | 613 | .getname = inet6_getname, |
619 | .poll = udp_poll, /* ok */ | 614 | .poll = udp_poll, /* ok */ |
620 | .ioctl = inet6_ioctl, /* must change */ | 615 | .ioctl = inet6_ioctl, /* must change */ |
616 | .gettstamp = sock_gettstamp, | ||
621 | .listen = sock_no_listen, /* ok */ | 617 | .listen = sock_no_listen, /* ok */ |
622 | .shutdown = inet_shutdown, /* ok */ | 618 | .shutdown = inet_shutdown, /* ok */ |
623 | .setsockopt = sock_common_setsockopt, /* ok */ | 619 | .setsockopt = sock_common_setsockopt, /* ok */ |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 5a426226c762..84dbe21b71e5 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -1356,6 +1356,7 @@ const struct proto_ops inet6_sockraw_ops = { | |||
1356 | .getname = inet6_getname, | 1356 | .getname = inet6_getname, |
1357 | .poll = datagram_poll, /* ok */ | 1357 | .poll = datagram_poll, /* ok */ |
1358 | .ioctl = inet6_ioctl, /* must change */ | 1358 | .ioctl = inet6_ioctl, /* must change */ |
1359 | .gettstamp = sock_gettstamp, | ||
1359 | .listen = sock_no_listen, /* ok */ | 1360 | .listen = sock_no_listen, /* ok */ |
1360 | .shutdown = inet_shutdown, /* ok */ | 1361 | .shutdown = inet_shutdown, /* ok */ |
1361 | .setsockopt = sock_common_setsockopt, /* ok */ | 1362 | .setsockopt = sock_common_setsockopt, /* ok */ |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index d4c60523c549..2cac910c1cd4 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -618,6 +618,7 @@ static const struct proto_ops l2tp_ip_ops = { | |||
618 | .getname = l2tp_ip_getname, | 618 | .getname = l2tp_ip_getname, |
619 | .poll = datagram_poll, | 619 | .poll = datagram_poll, |
620 | .ioctl = inet_ioctl, | 620 | .ioctl = inet_ioctl, |
621 | .gettstamp = sock_gettstamp, | ||
621 | .listen = sock_no_listen, | 622 | .listen = sock_no_listen, |
622 | .shutdown = inet_shutdown, | 623 | .shutdown = inet_shutdown, |
623 | .setsockopt = sock_common_setsockopt, | 624 | .setsockopt = sock_common_setsockopt, |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 37a69df17cab..4ec546cc1dd6 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -752,6 +752,7 @@ static const struct proto_ops l2tp_ip6_ops = { | |||
752 | .getname = l2tp_ip6_getname, | 752 | .getname = l2tp_ip6_getname, |
753 | .poll = datagram_poll, | 753 | .poll = datagram_poll, |
754 | .ioctl = inet6_ioctl, | 754 | .ioctl = inet6_ioctl, |
755 | .gettstamp = sock_gettstamp, | ||
755 | .listen = sock_no_listen, | 756 | .listen = sock_no_listen, |
756 | .shutdown = inet_shutdown, | 757 | .shutdown = inet_shutdown, |
757 | .setsockopt = sock_common_setsockopt, | 758 | .setsockopt = sock_common_setsockopt, |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 71ffd1a6dc7c..167c09e1ea90 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -1199,7 +1199,6 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1199 | { | 1199 | { |
1200 | struct sock *sk = sock->sk; | 1200 | struct sock *sk = sock->sk; |
1201 | void __user *argp = (void __user *)arg; | 1201 | void __user *argp = (void __user *)arg; |
1202 | int ret; | ||
1203 | 1202 | ||
1204 | switch (cmd) { | 1203 | switch (cmd) { |
1205 | case TIOCOUTQ: { | 1204 | case TIOCOUTQ: { |
@@ -1225,18 +1224,6 @@ static int nr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1225 | return put_user(amount, (int __user *)argp); | 1224 | return put_user(amount, (int __user *)argp); |
1226 | } | 1225 | } |
1227 | 1226 | ||
1228 | case SIOCGSTAMP: | ||
1229 | lock_sock(sk); | ||
1230 | ret = sock_get_timestamp(sk, argp); | ||
1231 | release_sock(sk); | ||
1232 | return ret; | ||
1233 | |||
1234 | case SIOCGSTAMPNS: | ||
1235 | lock_sock(sk); | ||
1236 | ret = sock_get_timestampns(sk, argp); | ||
1237 | release_sock(sk); | ||
1238 | return ret; | ||
1239 | |||
1240 | case SIOCGIFADDR: | 1227 | case SIOCGIFADDR: |
1241 | case SIOCSIFADDR: | 1228 | case SIOCSIFADDR: |
1242 | case SIOCGIFDSTADDR: | 1229 | case SIOCGIFDSTADDR: |
@@ -1362,6 +1349,7 @@ static const struct proto_ops nr_proto_ops = { | |||
1362 | .getname = nr_getname, | 1349 | .getname = nr_getname, |
1363 | .poll = datagram_poll, | 1350 | .poll = datagram_poll, |
1364 | .ioctl = nr_ioctl, | 1351 | .ioctl = nr_ioctl, |
1352 | .gettstamp = sock_gettstamp, | ||
1365 | .listen = nr_listen, | 1353 | .listen = nr_listen, |
1366 | .shutdown = sock_no_shutdown, | 1354 | .shutdown = sock_no_shutdown, |
1367 | .setsockopt = nr_setsockopt, | 1355 | .setsockopt = nr_setsockopt, |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 08fe8b79c0bf..5c4a118d6f96 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -4075,11 +4075,6 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd, | |||
4075 | spin_unlock_bh(&sk->sk_receive_queue.lock); | 4075 | spin_unlock_bh(&sk->sk_receive_queue.lock); |
4076 | return put_user(amount, (int __user *)arg); | 4076 | return put_user(amount, (int __user *)arg); |
4077 | } | 4077 | } |
4078 | case SIOCGSTAMP: | ||
4079 | return sock_get_timestamp(sk, (struct timeval __user *)arg); | ||
4080 | case SIOCGSTAMPNS: | ||
4081 | return sock_get_timestampns(sk, (struct timespec __user *)arg); | ||
4082 | |||
4083 | #ifdef CONFIG_INET | 4078 | #ifdef CONFIG_INET |
4084 | case SIOCADDRT: | 4079 | case SIOCADDRT: |
4085 | case SIOCDELRT: | 4080 | case SIOCDELRT: |
@@ -4455,6 +4450,7 @@ static const struct proto_ops packet_ops_spkt = { | |||
4455 | .getname = packet_getname_spkt, | 4450 | .getname = packet_getname_spkt, |
4456 | .poll = datagram_poll, | 4451 | .poll = datagram_poll, |
4457 | .ioctl = packet_ioctl, | 4452 | .ioctl = packet_ioctl, |
4453 | .gettstamp = sock_gettstamp, | ||
4458 | .listen = sock_no_listen, | 4454 | .listen = sock_no_listen, |
4459 | .shutdown = sock_no_shutdown, | 4455 | .shutdown = sock_no_shutdown, |
4460 | .setsockopt = sock_no_setsockopt, | 4456 | .setsockopt = sock_no_setsockopt, |
@@ -4476,6 +4472,7 @@ static const struct proto_ops packet_ops = { | |||
4476 | .getname = packet_getname, | 4472 | .getname = packet_getname, |
4477 | .poll = packet_poll, | 4473 | .poll = packet_poll, |
4478 | .ioctl = packet_ioctl, | 4474 | .ioctl = packet_ioctl, |
4475 | .gettstamp = sock_gettstamp, | ||
4479 | .listen = sock_no_listen, | 4476 | .listen = sock_no_listen, |
4480 | .shutdown = sock_no_shutdown, | 4477 | .shutdown = sock_no_shutdown, |
4481 | .setsockopt = packet_setsockopt, | 4478 | .setsockopt = packet_setsockopt, |
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index b37e6e0a1026..7c5e8292cc0a 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c | |||
@@ -968,9 +968,6 @@ static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
968 | break; | 968 | break; |
969 | } | 969 | } |
970 | break; | 970 | break; |
971 | case SIOCGSTAMP: | ||
972 | rc = sock_get_timestamp(sk, argp); | ||
973 | break; | ||
974 | case SIOCADDRT: | 971 | case SIOCADDRT: |
975 | case SIOCDELRT: | 972 | case SIOCDELRT: |
976 | case SIOCSIFADDR: | 973 | case SIOCSIFADDR: |
@@ -1033,6 +1030,7 @@ static const struct proto_ops qrtr_proto_ops = { | |||
1033 | .recvmsg = qrtr_recvmsg, | 1030 | .recvmsg = qrtr_recvmsg, |
1034 | .getname = qrtr_getname, | 1031 | .getname = qrtr_getname, |
1035 | .ioctl = qrtr_ioctl, | 1032 | .ioctl = qrtr_ioctl, |
1033 | .gettstamp = sock_gettstamp, | ||
1036 | .poll = datagram_poll, | 1034 | .poll = datagram_poll, |
1037 | .shutdown = sock_no_shutdown, | 1035 | .shutdown = sock_no_shutdown, |
1038 | .setsockopt = sock_no_setsockopt, | 1036 | .setsockopt = sock_no_setsockopt, |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index c96f63ffe31e..e274bc6e1458 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -1301,12 +1301,6 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1301 | return put_user(amount, (unsigned int __user *) argp); | 1301 | return put_user(amount, (unsigned int __user *) argp); |
1302 | } | 1302 | } |
1303 | 1303 | ||
1304 | case SIOCGSTAMP: | ||
1305 | return sock_get_timestamp(sk, (struct timeval __user *) argp); | ||
1306 | |||
1307 | case SIOCGSTAMPNS: | ||
1308 | return sock_get_timestampns(sk, (struct timespec __user *) argp); | ||
1309 | |||
1310 | case SIOCGIFADDR: | 1304 | case SIOCGIFADDR: |
1311 | case SIOCSIFADDR: | 1305 | case SIOCSIFADDR: |
1312 | case SIOCGIFDSTADDR: | 1306 | case SIOCGIFDSTADDR: |
@@ -1474,6 +1468,7 @@ static const struct proto_ops rose_proto_ops = { | |||
1474 | .getname = rose_getname, | 1468 | .getname = rose_getname, |
1475 | .poll = datagram_poll, | 1469 | .poll = datagram_poll, |
1476 | .ioctl = rose_ioctl, | 1470 | .ioctl = rose_ioctl, |
1471 | .gettstamp = sock_gettstamp, | ||
1477 | .listen = rose_listen, | 1472 | .listen = rose_listen, |
1478 | .shutdown = sock_no_shutdown, | 1473 | .shutdown = sock_no_shutdown, |
1479 | .setsockopt = rose_setsockopt, | 1474 | .setsockopt = rose_setsockopt, |
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 6200cd2b4b99..188c47eb206e 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -1030,6 +1030,7 @@ static const struct proto_ops inet6_seqpacket_ops = { | |||
1030 | .getname = sctp_getname, | 1030 | .getname = sctp_getname, |
1031 | .poll = sctp_poll, | 1031 | .poll = sctp_poll, |
1032 | .ioctl = inet6_ioctl, | 1032 | .ioctl = inet6_ioctl, |
1033 | .gettstamp = sock_gettstamp, | ||
1033 | .listen = sctp_inet_listen, | 1034 | .listen = sctp_inet_listen, |
1034 | .shutdown = inet_shutdown, | 1035 | .shutdown = inet_shutdown, |
1035 | .setsockopt = sock_common_setsockopt, | 1036 | .setsockopt = sock_common_setsockopt, |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 951afdeea5e9..f0631bf486b6 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1026,6 +1026,7 @@ static const struct proto_ops inet_seqpacket_ops = { | |||
1026 | .getname = inet_getname, /* Semantics are different. */ | 1026 | .getname = inet_getname, /* Semantics are different. */ |
1027 | .poll = sctp_poll, | 1027 | .poll = sctp_poll, |
1028 | .ioctl = inet_ioctl, | 1028 | .ioctl = inet_ioctl, |
1029 | .gettstamp = sock_gettstamp, | ||
1029 | .listen = sctp_inet_listen, | 1030 | .listen = sctp_inet_listen, |
1030 | .shutdown = inet_shutdown, /* Looks harmless. */ | 1031 | .shutdown = inet_shutdown, /* Looks harmless. */ |
1031 | .setsockopt = sock_common_setsockopt, /* IP_SOL IP_OPTION is a problem */ | 1032 | .setsockopt = sock_common_setsockopt, /* IP_SOL IP_OPTION is a problem */ |
diff --git a/net/socket.c b/net/socket.c index 8255f5bda0aa..ab624d42ead5 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1164,6 +1164,15 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
1164 | 1164 | ||
1165 | err = open_related_ns(&net->ns, get_net_ns); | 1165 | err = open_related_ns(&net->ns, get_net_ns); |
1166 | break; | 1166 | break; |
1167 | case SIOCGSTAMP: | ||
1168 | case SIOCGSTAMPNS: | ||
1169 | if (!sock->ops->gettstamp) { | ||
1170 | err = -ENOIOCTLCMD; | ||
1171 | break; | ||
1172 | } | ||
1173 | err = sock->ops->gettstamp(sock, argp, | ||
1174 | cmd == SIOCGSTAMP, false); | ||
1175 | break; | ||
1167 | default: | 1176 | default: |
1168 | err = sock_do_ioctl(net, sock, cmd, arg); | 1177 | err = sock_do_ioctl(net, sock, cmd, arg); |
1169 | break; | 1178 | break; |
@@ -2916,38 +2925,6 @@ void socket_seq_show(struct seq_file *seq) | |||
2916 | #endif /* CONFIG_PROC_FS */ | 2925 | #endif /* CONFIG_PROC_FS */ |
2917 | 2926 | ||
2918 | #ifdef CONFIG_COMPAT | 2927 | #ifdef CONFIG_COMPAT |
2919 | static int do_siocgstamp(struct net *net, struct socket *sock, | ||
2920 | unsigned int cmd, void __user *up) | ||
2921 | { | ||
2922 | mm_segment_t old_fs = get_fs(); | ||
2923 | struct timeval ktv; | ||
2924 | int err; | ||
2925 | |||
2926 | set_fs(KERNEL_DS); | ||
2927 | err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv); | ||
2928 | set_fs(old_fs); | ||
2929 | if (!err) | ||
2930 | err = compat_put_timeval(&ktv, up); | ||
2931 | |||
2932 | return err; | ||
2933 | } | ||
2934 | |||
2935 | static int do_siocgstampns(struct net *net, struct socket *sock, | ||
2936 | unsigned int cmd, void __user *up) | ||
2937 | { | ||
2938 | mm_segment_t old_fs = get_fs(); | ||
2939 | struct timespec kts; | ||
2940 | int err; | ||
2941 | |||
2942 | set_fs(KERNEL_DS); | ||
2943 | err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts); | ||
2944 | set_fs(old_fs); | ||
2945 | if (!err) | ||
2946 | err = compat_put_timespec(&kts, up); | ||
2947 | |||
2948 | return err; | ||
2949 | } | ||
2950 | |||
2951 | static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) | 2928 | static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) |
2952 | { | 2929 | { |
2953 | struct compat_ifconf ifc32; | 2930 | struct compat_ifconf ifc32; |
@@ -3348,9 +3325,12 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, | |||
3348 | case SIOCDELRT: | 3325 | case SIOCDELRT: |
3349 | return routing_ioctl(net, sock, cmd, argp); | 3326 | return routing_ioctl(net, sock, cmd, argp); |
3350 | case SIOCGSTAMP: | 3327 | case SIOCGSTAMP: |
3351 | return do_siocgstamp(net, sock, cmd, argp); | ||
3352 | case SIOCGSTAMPNS: | 3328 | case SIOCGSTAMPNS: |
3353 | return do_siocgstampns(net, sock, cmd, argp); | 3329 | if (!sock->ops->gettstamp) |
3330 | return -ENOIOCTLCMD; | ||
3331 | return sock->ops->gettstamp(sock, argp, cmd == SIOCGSTAMP, | ||
3332 | !COMPAT_USE_64BIT_TIME); | ||
3333 | |||
3354 | case SIOCBONDSLAVEINFOQUERY: | 3334 | case SIOCBONDSLAVEINFOQUERY: |
3355 | case SIOCBONDINFOQUERY: | 3335 | case SIOCBONDINFOQUERY: |
3356 | case SIOCSHWTSTAMP: | 3336 | case SIOCSHWTSTAMP: |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 20a511398389..0ea48a52ce79 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -1398,18 +1398,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
1398 | break; | 1398 | break; |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | case SIOCGSTAMP: | ||
1402 | rc = -EINVAL; | ||
1403 | if (sk) | ||
1404 | rc = sock_get_timestamp(sk, | ||
1405 | (struct timeval __user *)argp); | ||
1406 | break; | ||
1407 | case SIOCGSTAMPNS: | ||
1408 | rc = -EINVAL; | ||
1409 | if (sk) | ||
1410 | rc = sock_get_timestampns(sk, | ||
1411 | (struct timespec __user *)argp); | ||
1412 | break; | ||
1413 | case SIOCGIFADDR: | 1401 | case SIOCGIFADDR: |
1414 | case SIOCSIFADDR: | 1402 | case SIOCSIFADDR: |
1415 | case SIOCGIFDSTADDR: | 1403 | case SIOCGIFDSTADDR: |
@@ -1681,8 +1669,6 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, | |||
1681 | unsigned long arg) | 1669 | unsigned long arg) |
1682 | { | 1670 | { |
1683 | void __user *argp = compat_ptr(arg); | 1671 | void __user *argp = compat_ptr(arg); |
1684 | struct sock *sk = sock->sk; | ||
1685 | |||
1686 | int rc = -ENOIOCTLCMD; | 1672 | int rc = -ENOIOCTLCMD; |
1687 | 1673 | ||
1688 | switch(cmd) { | 1674 | switch(cmd) { |
@@ -1690,18 +1676,6 @@ static int compat_x25_ioctl(struct socket *sock, unsigned int cmd, | |||
1690 | case TIOCINQ: | 1676 | case TIOCINQ: |
1691 | rc = x25_ioctl(sock, cmd, (unsigned long)argp); | 1677 | rc = x25_ioctl(sock, cmd, (unsigned long)argp); |
1692 | break; | 1678 | break; |
1693 | case SIOCGSTAMP: | ||
1694 | rc = -EINVAL; | ||
1695 | if (sk) | ||
1696 | rc = compat_sock_get_timestamp(sk, | ||
1697 | (struct timeval __user*)argp); | ||
1698 | break; | ||
1699 | case SIOCGSTAMPNS: | ||
1700 | rc = -EINVAL; | ||
1701 | if (sk) | ||
1702 | rc = compat_sock_get_timestampns(sk, | ||
1703 | (struct timespec __user*)argp); | ||
1704 | break; | ||
1705 | case SIOCGIFADDR: | 1679 | case SIOCGIFADDR: |
1706 | case SIOCSIFADDR: | 1680 | case SIOCSIFADDR: |
1707 | case SIOCGIFDSTADDR: | 1681 | case SIOCGIFDSTADDR: |
@@ -1765,6 +1739,7 @@ static const struct proto_ops x25_proto_ops = { | |||
1765 | #ifdef CONFIG_COMPAT | 1739 | #ifdef CONFIG_COMPAT |
1766 | .compat_ioctl = compat_x25_ioctl, | 1740 | .compat_ioctl = compat_x25_ioctl, |
1767 | #endif | 1741 | #endif |
1742 | .gettstamp = sock_gettstamp, | ||
1768 | .listen = x25_listen, | 1743 | .listen = x25_listen, |
1769 | .shutdown = sock_no_shutdown, | 1744 | .shutdown = sock_no_shutdown, |
1770 | .setsockopt = x25_setsockopt, | 1745 | .setsockopt = x25_setsockopt, |