mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
SUNRPC: introduce svc_xprt_create_from_sa utility routine
Add svc_xprt_create_from_sa utility routine and refactor svc_xprt_create() codebase in order to introduce the capability to create a svc port from socket address. Reviewed-by: Jeff Layton <jlayton@kernel.org> Tested-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
5a939bea25
commit
a79ec2aecb
@ -135,6 +135,9 @@ int svc_reg_xprt_class(struct svc_xprt_class *);
|
||||
void svc_unreg_xprt_class(struct svc_xprt_class *);
|
||||
void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
|
||||
struct svc_serv *);
|
||||
int svc_xprt_create_from_sa(struct svc_serv *serv, const char *xprt_name,
|
||||
struct net *net, struct sockaddr *sap,
|
||||
int flags, const struct cred *cred);
|
||||
int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
|
||||
struct net *net, const int family,
|
||||
const unsigned short port, int flags,
|
||||
|
@ -211,51 +211,6 @@ void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_xprt_init);
|
||||
|
||||
static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
|
||||
struct svc_serv *serv,
|
||||
struct net *net,
|
||||
const int family,
|
||||
const unsigned short port,
|
||||
int flags)
|
||||
{
|
||||
struct sockaddr_in sin = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = htonl(INADDR_ANY),
|
||||
.sin_port = htons(port),
|
||||
};
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
struct sockaddr_in6 sin6 = {
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_addr = IN6ADDR_ANY_INIT,
|
||||
.sin6_port = htons(port),
|
||||
};
|
||||
#endif
|
||||
struct svc_xprt *xprt;
|
||||
struct sockaddr *sap;
|
||||
size_t len;
|
||||
|
||||
switch (family) {
|
||||
case PF_INET:
|
||||
sap = (struct sockaddr *)&sin;
|
||||
len = sizeof(sin);
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
case PF_INET6:
|
||||
sap = (struct sockaddr *)&sin6;
|
||||
len = sizeof(sin6);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return ERR_PTR(-EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
xprt = xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
|
||||
if (IS_ERR(xprt))
|
||||
trace_svc_xprt_create_err(serv->sv_program->pg_name,
|
||||
xcl->xcl_name, sap, len, xprt);
|
||||
return xprt;
|
||||
}
|
||||
|
||||
/**
|
||||
* svc_xprt_received - start next receiver thread
|
||||
* @xprt: controlling transport
|
||||
@ -294,9 +249,8 @@ void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *new)
|
||||
}
|
||||
|
||||
static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
|
||||
struct net *net, const int family,
|
||||
const unsigned short port, int flags,
|
||||
const struct cred *cred)
|
||||
struct net *net, struct sockaddr *sap,
|
||||
size_t len, int flags, const struct cred *cred)
|
||||
{
|
||||
struct svc_xprt_class *xcl;
|
||||
|
||||
@ -312,8 +266,11 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
|
||||
goto err;
|
||||
|
||||
spin_unlock(&svc_xprt_class_lock);
|
||||
newxprt = __svc_xpo_create(xcl, serv, net, family, port, flags);
|
||||
newxprt = xcl->xcl_ops->xpo_create(serv, net, sap, len, flags);
|
||||
if (IS_ERR(newxprt)) {
|
||||
trace_svc_xprt_create_err(serv->sv_program->pg_name,
|
||||
xcl->xcl_name, sap, len,
|
||||
newxprt);
|
||||
module_put(xcl->xcl_owner);
|
||||
return PTR_ERR(newxprt);
|
||||
}
|
||||
@ -329,6 +286,48 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
/**
|
||||
* svc_xprt_create_from_sa - Add a new listener to @serv from socket address
|
||||
* @serv: target RPC service
|
||||
* @xprt_name: transport class name
|
||||
* @net: network namespace
|
||||
* @sap: socket address pointer
|
||||
* @flags: SVC_SOCK flags
|
||||
* @cred: credential to bind to this transport
|
||||
*
|
||||
* Return local xprt port on success or %-EPROTONOSUPPORT on failure
|
||||
*/
|
||||
int svc_xprt_create_from_sa(struct svc_serv *serv, const char *xprt_name,
|
||||
struct net *net, struct sockaddr *sap,
|
||||
int flags, const struct cred *cred)
|
||||
{
|
||||
size_t len;
|
||||
int err;
|
||||
|
||||
switch (sap->sa_family) {
|
||||
case AF_INET:
|
||||
len = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
case AF_INET6:
|
||||
len = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
err = _svc_xprt_create(serv, xprt_name, net, sap, len, flags, cred);
|
||||
if (err == -EPROTONOSUPPORT) {
|
||||
request_module("svc%s", xprt_name);
|
||||
err = _svc_xprt_create(serv, xprt_name, net, sap, len, flags,
|
||||
cred);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_xprt_create_from_sa);
|
||||
|
||||
/**
|
||||
* svc_xprt_create - Add a new listener to @serv
|
||||
* @serv: target RPC service
|
||||
@ -339,23 +338,41 @@ static int _svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
|
||||
* @flags: SVC_SOCK flags
|
||||
* @cred: credential to bind to this transport
|
||||
*
|
||||
* Return values:
|
||||
* %0: New listener added successfully
|
||||
* %-EPROTONOSUPPORT: Requested transport type not supported
|
||||
* Return local xprt port on success or %-EPROTONOSUPPORT on failure
|
||||
*/
|
||||
int svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
|
||||
struct net *net, const int family,
|
||||
const unsigned short port, int flags,
|
||||
const struct cred *cred)
|
||||
{
|
||||
int err;
|
||||
struct sockaddr_in sin = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = htonl(INADDR_ANY),
|
||||
.sin_port = htons(port),
|
||||
};
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
struct sockaddr_in6 sin6 = {
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_addr = IN6ADDR_ANY_INIT,
|
||||
.sin6_port = htons(port),
|
||||
};
|
||||
#endif
|
||||
struct sockaddr *sap;
|
||||
|
||||
err = _svc_xprt_create(serv, xprt_name, net, family, port, flags, cred);
|
||||
if (err == -EPROTONOSUPPORT) {
|
||||
request_module("svc%s", xprt_name);
|
||||
err = _svc_xprt_create(serv, xprt_name, net, family, port, flags, cred);
|
||||
switch (family) {
|
||||
case PF_INET:
|
||||
sap = (struct sockaddr *)&sin;
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
case PF_INET6:
|
||||
sap = (struct sockaddr *)&sin6;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
return err;
|
||||
|
||||
return svc_xprt_create_from_sa(serv, xprt_name, net, sap, flags, cred);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(svc_xprt_create);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user