Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=81c098af3da7981902e9f8163aeccc2467c4ba6d
Commit:     81c098af3da7981902e9f8163aeccc2467c4ba6d
Parent:     1244480976d357447aeddd3f44977586bfa0462b
Author:     \"Talpey, Thomas\ <[EMAIL PROTECTED]>
AuthorDate: Mon Sep 10 13:46:00 2007 -0400
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Tue Oct 9 17:17:40 2007 -0400

    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: Chuck Lever <[EMAIL PROTECTED]>
    Signed-off-by: Tom Talpey <[EMAIL PROTECTED]>
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 include/linux/sunrpc/xprt.h |   11 ++++++
 net/sunrpc/xprt.c           |   75 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index 513b065..7b6b137 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -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);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index bc13616..5208596 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -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
@@ -81,6 +84,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
  *
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to