Skip to content

Commit

Permalink
SUNRPC: Provide a new API for registering transport implementations
Browse files Browse the repository at this point in the history
To allow transport capabilities to be loaded dynamically, provide an API
for registering and unregistering the transports with the RPC client.
Eventually xprt_create_transport() will be changed to search the list of
registered transports when initializing a fresh transport.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Tom Talpey <tmt@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
\"Talpey, Thomas\ authored and Trond Myklebust committed Oct 9, 2007
1 parent 1244480 commit 81c098a
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
11 changes: 11 additions & 0 deletions include/linux/sunrpc/xprt.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ struct rpc_xprtsock_create {
struct rpc_timeout * timeout; /* optional timeout parameters */
};

struct xprt_class {
struct list_head list;
unsigned short family;
int protocol;
struct rpc_xprt * (*setup)(struct rpc_xprtsock_create *);
struct module *owner;
char name[32];
};

/*
* Transport operations used by ULPs
*/
Expand Down Expand Up @@ -239,6 +248,8 @@ static inline __be32 *xprt_skip_transport_header(struct rpc_xprt *xprt, __be32 *
/*
* Transport switch helper functions
*/
int xprt_register_transport(struct xprt_class *type);
int xprt_unregister_transport(struct xprt_class *type);
void xprt_set_retrans_timeout_def(struct rpc_task *task);
void xprt_set_retrans_timeout_rtt(struct rpc_task *task);
void xprt_wake_pending_tasks(struct rpc_xprt *xprt, int status);
Expand Down
75 changes: 75 additions & 0 deletions net/sunrpc/xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ static inline void do_xprt_reserve(struct rpc_task *);
static void xprt_connect_status(struct rpc_task *task);
static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);

static spinlock_t xprt_list_lock = SPIN_LOCK_UNLOCKED;
static LIST_HEAD(xprt_list);

/*
* The transport code maintains an estimate on the maximum number of out-
* standing RPC requests, using a smoothed version of the congestion
Expand All @@ -80,6 +83,78 @@ static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *);

#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)

/**
* xprt_register_transport - register a transport implementation
* @transport: transport to register
*
* If a transport implementation is loaded as a kernel module, it can
* call this interface to make itself known to the RPC client.
*
* Returns:
* 0: transport successfully registered
* -EEXIST: transport already registered
* -EINVAL: transport module being unloaded
*/
int xprt_register_transport(struct xprt_class *transport)
{
struct xprt_class *t;
int result;

result = -EEXIST;
spin_lock(&xprt_list_lock);
list_for_each_entry(t, &xprt_list, list) {
/* don't register the same transport class twice */
if (t == transport)
goto out;
}

result = -EINVAL;
if (try_module_get(THIS_MODULE)) {
list_add_tail(&transport->list, &xprt_list);
printk(KERN_INFO "RPC: Registered %s transport module.\n",
transport->name);
result = 0;
}

out:
spin_unlock(&xprt_list_lock);
return result;
}
EXPORT_SYMBOL_GPL(xprt_register_transport);

/**
* xprt_unregister_transport - unregister a transport implementation
* transport: transport to unregister
*
* Returns:
* 0: transport successfully unregistered
* -ENOENT: transport never registered
*/
int xprt_unregister_transport(struct xprt_class *transport)
{
struct xprt_class *t;
int result;

result = 0;
spin_lock(&xprt_list_lock);
list_for_each_entry(t, &xprt_list, list) {
if (t == transport) {
printk(KERN_INFO
"RPC: Unregistered %s transport module.\n",
transport->name);
list_del_init(&transport->list);
module_put(THIS_MODULE);
goto out;
}
}
result = -ENOENT;

out:
spin_unlock(&xprt_list_lock);
return result;
}
EXPORT_SYMBOL_GPL(xprt_unregister_transport);

/**
* xprt_reserve_xprt - serialize write access to transports
* @task: task that is requesting access to the transport
Expand Down

0 comments on commit 81c098a

Please sign in to comment.