[NET] move already shared functions from inet to core

inet_recvmsg, inet_setsockopt, inet_getsockopt and inet_sock_release are
already shared with ipv6 and sctp, will be used as well by the poor cousins,
so reflect this properly renaming them to sock_common_NAME and move them to
net/core/sock.c
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@conectiva.com.br>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 2b83a8d6
...@@ -20,27 +20,14 @@ extern int inet_dgram_connect(struct socket *sock, ...@@ -20,27 +20,14 @@ extern int inet_dgram_connect(struct socket *sock,
int addr_len, int flags); int addr_len, int flags);
extern int inet_accept(struct socket *sock, extern int inet_accept(struct socket *sock,
struct socket *newsock, int flags); struct socket *newsock, int flags);
extern int inet_recvmsg(struct kiocb *iocb,
struct socket *sock,
struct msghdr *ubuf,
size_t size, int flags);
extern int inet_sendmsg(struct kiocb *iocb, extern int inet_sendmsg(struct kiocb *iocb,
struct socket *sock, struct socket *sock,
struct msghdr *msg, struct msghdr *msg,
size_t size); size_t size);
extern int inet_shutdown(struct socket *sock, int how); extern int inet_shutdown(struct socket *sock, int how);
extern unsigned int inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); extern unsigned int inet_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
extern int inet_setsockopt(struct socket *sock, int level,
int optname,
char __user *optval,
int optlen);
extern int inet_getsockopt(struct socket *sock, int level,
int optname,
char __user *optval,
int __user *optlen);
extern int inet_listen(struct socket *sock, int backlog); extern int inet_listen(struct socket *sock, int backlog);
extern void inet_sock_release(struct sock *sk);
extern void inet_sock_destruct(struct sock *sk); extern void inet_sock_destruct(struct sock *sk);
extern atomic_t inet_sock_nr; extern atomic_t inet_sock_nr;
......
...@@ -770,6 +770,19 @@ extern ssize_t sock_no_sendpage(struct socket *sock, ...@@ -770,6 +770,19 @@ extern ssize_t sock_no_sendpage(struct socket *sock,
int offset, size_t size, int offset, size_t size,
int flags); int flags);
/*
* Functions to fill in entries in struct proto_ops when a protocol
* uses the inet style.
*/
extern int sock_common_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen);
extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags);
extern int sock_common_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen);
extern void sk_common_release(struct sock *sk);
/* /*
* Default socket callbacks and setup code * Default socket callbacks and setup code
*/ */
......
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
#include <net/protocol.h> #include <net/protocol.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/xfrm.h>
#include <linux/ipsec.h> #include <linux/ipsec.h>
#include <linux/filter.h> #include <linux/filter.h>
...@@ -1259,6 +1260,93 @@ void sock_disable_timestamp(struct sock *sk) ...@@ -1259,6 +1260,93 @@ void sock_disable_timestamp(struct sock *sk)
} }
EXPORT_SYMBOL(sock_disable_timestamp); EXPORT_SYMBOL(sock_disable_timestamp);
/*
* Get a socket option on an socket.
*
* FIX: POSIX 1003.1g is very ambiguous here. It states that
* asynchronous errors should be reported by getsockopt. We assume
* this means if you specify SO_ERROR (otherwise whats the point of it).
*/
int sock_common_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
}
EXPORT_SYMBOL(sock_common_getsockopt);
int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
struct sock *sk = sock->sk;
int addr_len = 0;
int err;
err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,
flags & ~MSG_DONTWAIT, &addr_len);
if (err >= 0)
msg->msg_namelen = addr_len;
return err;
}
EXPORT_SYMBOL(sock_common_recvmsg);
/*
* Set socket options on an inet socket.
*/
int sock_common_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
{
struct sock *sk = sock->sk;
return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
}
EXPORT_SYMBOL(sock_common_setsockopt);
void sk_common_release(struct sock *sk)
{
if (sk->sk_prot->destroy)
sk->sk_prot->destroy(sk);
/*
* Observation: when sock_common_release is called, processes have
* no access to socket. But net still has.
* Step one, detach it from networking:
*
* A. Remove from hash tables.
*/
sk->sk_prot->unhash(sk);
/*
* In this point socket cannot receive new packets, but it is possible
* that some packets are in flight because some CPU runs receiver and
* did hash table lookup before we unhashed socket. They will achieve
* receive queue and will be purged by socket destructor.
*
* Also we still have packets pending on receive queue and probably,
* our own packets waiting in device queues. sock_destroy will drain
* receive queue, but transmitted packets will delay socket destruction
* until the last reference will be released.
*/
sock_orphan(sk);
xfrm_sk_free_policy(sk);
#ifdef INET_REFCNT_DEBUG
if (atomic_read(&sk->sk_refcnt) != 1)
printk(KERN_DEBUG "Destruction of the socket %p delayed, c=%d\n",
sk, atomic_read(&sk->sk_refcnt));
#endif
sock_put(sk);
}
EXPORT_SYMBOL(sk_common_release);
EXPORT_SYMBOL(__lock_sock); EXPORT_SYMBOL(__lock_sock);
EXPORT_SYMBOL(__release_sock); EXPORT_SYMBOL(__release_sock);
EXPORT_SYMBOL(sk_alloc); EXPORT_SYMBOL(sk_alloc);
......
...@@ -166,79 +166,12 @@ void inet_sock_destruct(struct sock *sk) ...@@ -166,79 +166,12 @@ void inet_sock_destruct(struct sock *sk)
#endif #endif
} }
void inet_sock_release(struct sock *sk)
{
if (sk->sk_prot->destroy)
sk->sk_prot->destroy(sk);
/* Observation: when inet_sock_release is called, processes have
* no access to socket. But net still has.
* Step one, detach it from networking:
*
* A. Remove from hash tables.
*/
sk->sk_prot->unhash(sk);
/* In this point socket cannot receive new packets,
* but it is possible that some packets are in flight
* because some CPU runs receiver and did hash table lookup
* before we unhashed socket. They will achieve receive queue
* and will be purged by socket destructor.
*
* Also we still have packets pending on receive
* queue and probably, our own packets waiting in device queues.
* sock_destroy will drain receive queue, but transmitted
* packets will delay socket destruction until the last reference
* will be released.
*/
sock_orphan(sk);
xfrm_sk_free_policy(sk);
#ifdef INET_REFCNT_DEBUG
if (atomic_read(&sk->sk_refcnt) != 1)
printk(KERN_DEBUG "Destruction inet %p delayed, c=%d\n",
sk, atomic_read(&sk->sk_refcnt));
#endif
sock_put(sk);
}
/* /*
* The routines beyond this point handle the behaviour of an AF_INET * The routines beyond this point handle the behaviour of an AF_INET
* socket object. Mostly it punts to the subprotocols of IP to do * socket object. Mostly it punts to the subprotocols of IP to do
* the work. * the work.
*/ */
/*
* Set socket options on an inet socket.
*/
int inet_setsockopt(struct socket *sock, int level, int optname,
char __user *optval, int optlen)
{
struct sock *sk = sock->sk;
return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
}
/*
* Get a socket option on an AF_INET socket.
*
* FIX: POSIX 1003.1g is very ambiguous here. It states that
* asynchronous errors should be reported by getsockopt. We assume
* this means if you specify SO_ERROR (otherwise whats the point of it).
*/
int inet_getsockopt(struct socket *sock, int level, int optname,
char __user *optval, int __user *optlen)
{
struct sock *sk = sock->sk;
return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
}
/* /*
* Automatically bind an unbound socket. * Automatically bind an unbound socket.
*/ */
...@@ -422,7 +355,7 @@ static int inet_create(struct socket *sock, int protocol) ...@@ -422,7 +355,7 @@ static int inet_create(struct socket *sock, int protocol)
if (sk->sk_prot->init) { if (sk->sk_prot->init) {
err = sk->sk_prot->init(sk); err = sk->sk_prot->init(sk);
if (err) if (err)
inet_sock_release(sk); sk_common_release(sk);
} }
out: out:
return err; return err;
...@@ -729,22 +662,6 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr, ...@@ -729,22 +662,6 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr,
return 0; return 0;
} }
int inet_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{
struct sock *sk = sock->sk;
int addr_len = 0;
int err;
err = sk->sk_prot->recvmsg(iocb, sk, msg, size, flags & MSG_DONTWAIT,
flags & ~MSG_DONTWAIT, &addr_len);
if (err >= 0)
msg->msg_namelen = addr_len;
return err;
}
int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int inet_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
size_t size) size_t size)
{ {
...@@ -891,10 +808,10 @@ struct proto_ops inet_stream_ops = { ...@@ -891,10 +808,10 @@ struct proto_ops inet_stream_ops = {
.ioctl = inet_ioctl, .ioctl = inet_ioctl,
.listen = inet_listen, .listen = inet_listen,
.shutdown = inet_shutdown, .shutdown = inet_shutdown,
.setsockopt = inet_setsockopt, .setsockopt = sock_common_setsockopt,
.getsockopt = inet_getsockopt, .getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg, .sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg, .recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.sendpage = tcp_sendpage .sendpage = tcp_sendpage
}; };
...@@ -906,16 +823,16 @@ struct proto_ops inet_dgram_ops = { ...@@ -906,16 +823,16 @@ struct proto_ops inet_dgram_ops = {
.bind = inet_bind, .bind = inet_bind,
.connect = inet_dgram_connect, .connect = inet_dgram_connect,
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.accept = sock_no_accept, .accept = inet_accept,
.getname = inet_getname, .getname = inet_getname,
.poll = datagram_poll, .poll = datagram_poll,
.ioctl = inet_ioctl, .ioctl = inet_ioctl,
.listen = sock_no_listen, .listen = sock_no_listen,
.shutdown = inet_shutdown, .shutdown = inet_shutdown,
.setsockopt = inet_setsockopt, .setsockopt = sock_common_setsockopt,
.getsockopt = inet_getsockopt, .getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg, .sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg, .recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.sendpage = inet_sendpage, .sendpage = inet_sendpage,
}; };
...@@ -1242,17 +1159,13 @@ EXPORT_SYMBOL(inet_dgram_connect); ...@@ -1242,17 +1159,13 @@ EXPORT_SYMBOL(inet_dgram_connect);
EXPORT_SYMBOL(inet_dgram_ops); EXPORT_SYMBOL(inet_dgram_ops);
EXPORT_SYMBOL(inet_family_ops); EXPORT_SYMBOL(inet_family_ops);
EXPORT_SYMBOL(inet_getname); EXPORT_SYMBOL(inet_getname);
EXPORT_SYMBOL(inet_getsockopt);
EXPORT_SYMBOL(inet_ioctl); EXPORT_SYMBOL(inet_ioctl);
EXPORT_SYMBOL(inet_listen); EXPORT_SYMBOL(inet_listen);
EXPORT_SYMBOL(inet_recvmsg);
EXPORT_SYMBOL(inet_register_protosw); EXPORT_SYMBOL(inet_register_protosw);
EXPORT_SYMBOL(inet_release); EXPORT_SYMBOL(inet_release);
EXPORT_SYMBOL(inet_sendmsg); EXPORT_SYMBOL(inet_sendmsg);
EXPORT_SYMBOL(inet_setsockopt);
EXPORT_SYMBOL(inet_shutdown); EXPORT_SYMBOL(inet_shutdown);
EXPORT_SYMBOL(inet_sock_destruct); EXPORT_SYMBOL(inet_sock_destruct);
EXPORT_SYMBOL(inet_sock_release);
EXPORT_SYMBOL(inet_stream_connect); EXPORT_SYMBOL(inet_stream_connect);
EXPORT_SYMBOL(inet_stream_ops); EXPORT_SYMBOL(inet_stream_ops);
EXPORT_SYMBOL(inet_unregister_protosw); EXPORT_SYMBOL(inet_unregister_protosw);
......
...@@ -480,7 +480,7 @@ static void raw_close(struct sock *sk, long timeout) ...@@ -480,7 +480,7 @@ static void raw_close(struct sock *sk, long timeout)
*/ */
ip_ra_control(sk, 0, NULL); ip_ra_control(sk, 0, NULL);
inet_sock_release(sk); sk_common_release(sk);
} }
/* This gets rid of all the nasties in af_inet. -DaveM */ /* This gets rid of all the nasties in af_inet. -DaveM */
......
...@@ -931,7 +931,7 @@ int udp_disconnect(struct sock *sk, int flags) ...@@ -931,7 +931,7 @@ int udp_disconnect(struct sock *sk, int flags)
static void udp_close(struct sock *sk, long timeout) static void udp_close(struct sock *sk, long timeout)
{ {
inet_sock_release(sk); sk_common_release(sk);
} }
/* return: /* return:
......
...@@ -250,7 +250,7 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -250,7 +250,7 @@ static int inet6_create(struct socket *sock, int protocol)
if (sk->sk_prot->init) { if (sk->sk_prot->init) {
int err = sk->sk_prot->init(sk); int err = sk->sk_prot->init(sk);
if (err != 0) { if (err != 0) {
inet_sock_release(sk); sk_common_release(sk);
return err; return err;
} }
} }
...@@ -510,10 +510,10 @@ struct proto_ops inet6_stream_ops = { ...@@ -510,10 +510,10 @@ struct proto_ops inet6_stream_ops = {
.ioctl = inet6_ioctl, /* must change */ .ioctl = inet6_ioctl, /* must change */
.listen = inet_listen, /* ok */ .listen = inet_listen, /* ok */
.shutdown = inet_shutdown, /* ok */ .shutdown = inet_shutdown, /* ok */
.setsockopt = inet_setsockopt, /* ok */ .setsockopt = sock_common_setsockopt, /* ok */
.getsockopt = inet_getsockopt, /* ok */ .getsockopt = sock_common_getsockopt, /* ok */
.sendmsg = inet_sendmsg, /* ok */ .sendmsg = inet_sendmsg, /* ok */
.recvmsg = inet_recvmsg, /* ok */ .recvmsg = sock_common_recvmsg, /* ok */
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.sendpage = tcp_sendpage .sendpage = tcp_sendpage
}; };
...@@ -531,10 +531,10 @@ struct proto_ops inet6_dgram_ops = { ...@@ -531,10 +531,10 @@ struct proto_ops inet6_dgram_ops = {
.ioctl = inet6_ioctl, /* must change */ .ioctl = inet6_ioctl, /* must change */
.listen = sock_no_listen, /* ok */ .listen = sock_no_listen, /* ok */
.shutdown = inet_shutdown, /* ok */ .shutdown = inet_shutdown, /* ok */
.setsockopt = inet_setsockopt, /* ok */ .setsockopt = sock_common_setsockopt, /* ok */
.getsockopt = inet_getsockopt, /* ok */ .getsockopt = sock_common_getsockopt, /* ok */
.sendmsg = inet_sendmsg, /* ok */ .sendmsg = inet_sendmsg, /* ok */
.recvmsg = inet_recvmsg, /* ok */ .recvmsg = sock_common_recvmsg, /* ok */
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.sendpage = sock_no_sendpage, .sendpage = sock_no_sendpage,
}; };
......
...@@ -900,7 +900,7 @@ static void rawv6_close(struct sock *sk, long timeout) ...@@ -900,7 +900,7 @@ static void rawv6_close(struct sock *sk, long timeout)
if (inet_sk(sk)->num == IPPROTO_RAW) if (inet_sk(sk)->num == IPPROTO_RAW)
ip6_ra_control(sk, -1, NULL); ip6_ra_control(sk, -1, NULL);
inet_sock_release(sk); sk_common_release(sk);
} }
static int rawv6_init_sk(struct sock *sk) static int rawv6_init_sk(struct sock *sk)
......
...@@ -358,7 +358,7 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -358,7 +358,7 @@ int udpv6_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
static void udpv6_close(struct sock *sk, long timeout) static void udpv6_close(struct sock *sk, long timeout)
{ {
inet_sock_release(sk); sk_common_release(sk);
} }
/* /*
......
...@@ -641,7 +641,7 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk, ...@@ -641,7 +641,7 @@ struct sock *sctp_v6_create_accept_sk(struct sock *sk,
#endif #endif
if (newsk->sk_prot->init(newsk)) { if (newsk->sk_prot->init(newsk)) {
inet_sock_release(newsk); sk_common_release(newsk);
newsk = NULL; newsk = NULL;
} }
...@@ -882,10 +882,10 @@ static struct proto_ops inet6_seqpacket_ops = { ...@@ -882,10 +882,10 @@ static struct proto_ops inet6_seqpacket_ops = {
.ioctl = inet6_ioctl, .ioctl = inet6_ioctl,
.listen = sctp_inet_listen, .listen = sctp_inet_listen,
.shutdown = inet_shutdown, .shutdown = inet_shutdown,
.setsockopt = inet_setsockopt, .setsockopt = sock_common_setsockopt,
.getsockopt = inet_getsockopt, .getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg, .sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg, .recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
}; };
......
...@@ -603,7 +603,7 @@ struct sock *sctp_v4_create_accept_sk(struct sock *sk, ...@@ -603,7 +603,7 @@ struct sock *sctp_v4_create_accept_sk(struct sock *sk,
#endif #endif
if (newsk->sk_prot->init(newsk)) { if (newsk->sk_prot->init(newsk)) {
inet_sock_release(newsk); sk_common_release(newsk);
newsk = NULL; newsk = NULL;
} }
...@@ -846,10 +846,10 @@ struct proto_ops inet_seqpacket_ops = { ...@@ -846,10 +846,10 @@ struct proto_ops inet_seqpacket_ops = {
.ioctl = inet_ioctl, .ioctl = inet_ioctl,
.listen = sctp_inet_listen, .listen = sctp_inet_listen,
.shutdown = inet_shutdown, /* Looks harmless. */ .shutdown = inet_shutdown, /* Looks harmless. */
.setsockopt = inet_setsockopt, /* IP_SOL IP_OPTION is a problem. */ .setsockopt = sock_common_setsockopt, /* IP_SOL IP_OPTION is a problem. */
.getsockopt = inet_getsockopt, .getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg, .sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg, .recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.sendpage = sock_no_sendpage, .sendpage = sock_no_sendpage,
}; };
......
...@@ -945,11 +945,11 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) ...@@ -945,11 +945,11 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
sctp_local_bh_disable(); sctp_local_bh_disable();
sctp_bh_lock_sock(sk); sctp_bh_lock_sock(sk);
/* Hold the sock, since inet_sock_release() will put sock_put() /* Hold the sock, since sk_common_release() will put sock_put()
* and we have just a little more cleanup. * and we have just a little more cleanup.
*/ */
sock_hold(sk); sock_hold(sk);
inet_sock_release(sk); sk_common_release(sk);
sctp_bh_unlock_sock(sk); sctp_bh_unlock_sock(sk);
sctp_local_bh_enable(); sctp_local_bh_enable();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment