[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,
int addr_len, int flags);
extern int inet_accept(struct socket *sock,
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,
struct socket *sock,
struct msghdr *msg,
size_t size);
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 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 void inet_sock_release(struct sock *sk);
extern void inet_sock_destruct(struct sock *sk);
extern atomic_t inet_sock_nr;
......
......@@ -770,6 +770,19 @@ extern ssize_t sock_no_sendpage(struct socket *sock,
int offset, size_t size,
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
*/
......
......@@ -118,6 +118,7 @@
#include <net/protocol.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <net/xfrm.h>
#include <linux/ipsec.h>
#include <linux/filter.h>
......@@ -1259,6 +1260,93 @@ void sock_disable_timestamp(struct sock *sk)
}
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(__release_sock);
EXPORT_SYMBOL(sk_alloc);
......
......@@ -166,79 +166,12 @@ void inet_sock_destruct(struct sock *sk)
#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
* socket object. Mostly it punts to the subprotocols of IP to do
* 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.
*/
......@@ -422,7 +355,7 @@ static int inet_create(struct socket *sock, int protocol)
if (sk->sk_prot->init) {
err = sk->sk_prot->init(sk);
if (err)
inet_sock_release(sk);
sk_common_release(sk);
}
out:
return err;
......@@ -729,22 +662,6 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr,
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,
size_t size)
{
......@@ -891,10 +808,10 @@ struct proto_ops inet_stream_ops = {
.ioctl = inet_ioctl,
.listen = inet_listen,
.shutdown = inet_shutdown,
.setsockopt = inet_setsockopt,
.getsockopt = inet_getsockopt,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg,
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
.sendpage = tcp_sendpage
};
......@@ -906,16 +823,16 @@ struct proto_ops inet_dgram_ops = {
.bind = inet_bind,
.connect = inet_dgram_connect,
.socketpair = sock_no_socketpair,
.accept = sock_no_accept,
.accept = inet_accept,
.getname = inet_getname,
.poll = datagram_poll,
.ioctl = inet_ioctl,
.listen = sock_no_listen,
.shutdown = inet_shutdown,
.setsockopt = inet_setsockopt,
.getsockopt = inet_getsockopt,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg,
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
.sendpage = inet_sendpage,
};
......@@ -1242,17 +1159,13 @@ EXPORT_SYMBOL(inet_dgram_connect);
EXPORT_SYMBOL(inet_dgram_ops);
EXPORT_SYMBOL(inet_family_ops);
EXPORT_SYMBOL(inet_getname);
EXPORT_SYMBOL(inet_getsockopt);
EXPORT_SYMBOL(inet_ioctl);
EXPORT_SYMBOL(inet_listen);
EXPORT_SYMBOL(inet_recvmsg);
EXPORT_SYMBOL(inet_register_protosw);
EXPORT_SYMBOL(inet_release);
EXPORT_SYMBOL(inet_sendmsg);
EXPORT_SYMBOL(inet_setsockopt);
EXPORT_SYMBOL(inet_shutdown);
EXPORT_SYMBOL(inet_sock_destruct);
EXPORT_SYMBOL(inet_sock_release);
EXPORT_SYMBOL(inet_stream_connect);
EXPORT_SYMBOL(inet_stream_ops);
EXPORT_SYMBOL(inet_unregister_protosw);
......
......@@ -480,7 +480,7 @@ static void raw_close(struct sock *sk, long timeout)
*/
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 */
......
......@@ -931,7 +931,7 @@ int udp_disconnect(struct sock *sk, int flags)
static void udp_close(struct sock *sk, long timeout)
{
inet_sock_release(sk);
sk_common_release(sk);
}
/* return:
......
......@@ -250,7 +250,7 @@ static int inet6_create(struct socket *sock, int protocol)
if (sk->sk_prot->init) {
int err = sk->sk_prot->init(sk);
if (err != 0) {
inet_sock_release(sk);
sk_common_release(sk);
return err;
}
}
......@@ -510,10 +510,10 @@ struct proto_ops inet6_stream_ops = {
.ioctl = inet6_ioctl, /* must change */
.listen = inet_listen, /* ok */
.shutdown = inet_shutdown, /* ok */
.setsockopt = inet_setsockopt, /* ok */
.getsockopt = inet_getsockopt, /* ok */
.setsockopt = sock_common_setsockopt, /* ok */
.getsockopt = sock_common_getsockopt, /* ok */
.sendmsg = inet_sendmsg, /* ok */
.recvmsg = inet_recvmsg, /* ok */
.recvmsg = sock_common_recvmsg, /* ok */
.mmap = sock_no_mmap,
.sendpage = tcp_sendpage
};
......@@ -531,10 +531,10 @@ struct proto_ops inet6_dgram_ops = {
.ioctl = inet6_ioctl, /* must change */
.listen = sock_no_listen, /* ok */
.shutdown = inet_shutdown, /* ok */
.setsockopt = inet_setsockopt, /* ok */
.getsockopt = inet_getsockopt, /* ok */
.setsockopt = sock_common_setsockopt, /* ok */
.getsockopt = sock_common_getsockopt, /* ok */
.sendmsg = inet_sendmsg, /* ok */
.recvmsg = inet_recvmsg, /* ok */
.recvmsg = sock_common_recvmsg, /* ok */
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
};
......
......@@ -900,7 +900,7 @@ static void rawv6_close(struct sock *sk, long timeout)
if (inet_sk(sk)->num == IPPROTO_RAW)
ip6_ra_control(sk, -1, NULL);
inet_sock_release(sk);
sk_common_release(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)
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,
#endif
if (newsk->sk_prot->init(newsk)) {
inet_sock_release(newsk);
sk_common_release(newsk);
newsk = NULL;
}
......@@ -882,10 +882,10 @@ static struct proto_ops inet6_seqpacket_ops = {
.ioctl = inet6_ioctl,
.listen = sctp_inet_listen,
.shutdown = inet_shutdown,
.setsockopt = inet_setsockopt,
.getsockopt = inet_getsockopt,
.setsockopt = sock_common_setsockopt,
.getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg,
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
};
......
......@@ -603,7 +603,7 @@ struct sock *sctp_v4_create_accept_sk(struct sock *sk,
#endif
if (newsk->sk_prot->init(newsk)) {
inet_sock_release(newsk);
sk_common_release(newsk);
newsk = NULL;
}
......@@ -846,10 +846,10 @@ struct proto_ops inet_seqpacket_ops = {
.ioctl = inet_ioctl,
.listen = sctp_inet_listen,
.shutdown = inet_shutdown, /* Looks harmless. */
.setsockopt = inet_setsockopt, /* IP_SOL IP_OPTION is a problem. */
.getsockopt = inet_getsockopt,
.setsockopt = sock_common_setsockopt, /* IP_SOL IP_OPTION is a problem. */
.getsockopt = sock_common_getsockopt,
.sendmsg = inet_sendmsg,
.recvmsg = inet_recvmsg,
.recvmsg = sock_common_recvmsg,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
};
......
......@@ -945,11 +945,11 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
sctp_local_bh_disable();
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.
*/
sock_hold(sk);
inet_sock_release(sk);
sk_common_release(sk);
sctp_bh_unlock_sock(sk);
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