Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 81c098af authored by \"Talpey, Thomas\'s avatar \"Talpey, Thomas\ Committed by Trond Myklebust
Browse files

SUNRPC: Provide a new API for registering transport implementations



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: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTom Talpey <tmt@netapp.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 12444809
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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
 */
@@ -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);
+75 −0
Original line number Diff line number Diff line
@@ -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
@@ -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