2 * linux/net/sunrpc/svc_xprt.c
4 * Author: Tom Tucker <tom@opengridcomputing.com>
7 #include <linux/sched.h>
8 #include <linux/errno.h>
9 #include <linux/fcntl.h>
10 #include <linux/net.h>
12 #include <linux/inet.h>
13 #include <linux/udp.h>
14 #include <linux/tcp.h>
15 #include <linux/unistd.h>
16 #include <linux/slab.h>
17 #include <linux/netdevice.h>
18 #include <linux/skbuff.h>
19 #include <linux/file.h>
20 #include <linux/freezer.h>
22 #include <net/checksum.h>
25 #include <net/tcp_states.h>
26 #include <linux/uaccess.h>
27 #include <asm/ioctls.h>
29 #include <linux/sunrpc/types.h>
30 #include <linux/sunrpc/clnt.h>
31 #include <linux/sunrpc/xdr.h>
32 #include <linux/sunrpc/svcsock.h>
33 #include <linux/sunrpc/stats.h>
34 #include <linux/sunrpc/svc_xprt.h>
36 #define RPCDBG_FACILITY RPCDBG_SVCXPRT
38 /* List of registered transport classes */
39 static DEFINE_SPINLOCK(svc_xprt_class_lock
);
40 static LIST_HEAD(svc_xprt_class_list
);
42 int svc_reg_xprt_class(struct svc_xprt_class
*xcl
)
44 struct svc_xprt_class
*cl
;
47 dprintk("svc: Adding svc transport class '%s'\n", xcl
->xcl_name
);
49 INIT_LIST_HEAD(&xcl
->xcl_list
);
50 spin_lock(&svc_xprt_class_lock
);
51 /* Make sure there isn't already a class with the same name */
52 list_for_each_entry(cl
, &svc_xprt_class_list
, xcl_list
) {
53 if (strcmp(xcl
->xcl_name
, cl
->xcl_name
) == 0)
56 list_add_tail(&xcl
->xcl_list
, &svc_xprt_class_list
);
59 spin_unlock(&svc_xprt_class_lock
);
62 EXPORT_SYMBOL_GPL(svc_reg_xprt_class
);
64 void svc_unreg_xprt_class(struct svc_xprt_class
*xcl
)
66 dprintk("svc: Removing svc transport class '%s'\n", xcl
->xcl_name
);
67 spin_lock(&svc_xprt_class_lock
);
68 list_del_init(&xcl
->xcl_list
);
69 spin_unlock(&svc_xprt_class_lock
);
71 EXPORT_SYMBOL_GPL(svc_unreg_xprt_class
);
73 static void svc_xprt_free(struct kref
*kref
)
75 struct svc_xprt
*xprt
=
76 container_of(kref
, struct svc_xprt
, xpt_ref
);
77 struct module
*owner
= xprt
->xpt_class
->xcl_owner
;
78 if (test_bit(XPT_CACHE_AUTH
, &xprt
->xpt_flags
)
79 && xprt
->xpt_auth_cache
!= NULL
)
80 svcauth_unix_info_release(xprt
->xpt_auth_cache
);
81 xprt
->xpt_ops
->xpo_free(xprt
);
85 void svc_xprt_put(struct svc_xprt
*xprt
)
87 kref_put(&xprt
->xpt_ref
, svc_xprt_free
);
89 EXPORT_SYMBOL_GPL(svc_xprt_put
);
92 * Called by transport drivers to initialize the transport independent
93 * portion of the transport instance.
95 void svc_xprt_init(struct svc_xprt_class
*xcl
, struct svc_xprt
*xprt
,
96 struct svc_serv
*serv
)
98 memset(xprt
, 0, sizeof(*xprt
));
99 xprt
->xpt_class
= xcl
;
100 xprt
->xpt_ops
= xcl
->xcl_ops
;
101 kref_init(&xprt
->xpt_ref
);
102 xprt
->xpt_server
= serv
;
103 INIT_LIST_HEAD(&xprt
->xpt_list
);
104 INIT_LIST_HEAD(&xprt
->xpt_ready
);
105 INIT_LIST_HEAD(&xprt
->xpt_deferred
);
106 mutex_init(&xprt
->xpt_mutex
);
107 spin_lock_init(&xprt
->xpt_lock
);
109 EXPORT_SYMBOL_GPL(svc_xprt_init
);
111 int svc_create_xprt(struct svc_serv
*serv
, char *xprt_name
, unsigned short port
,
114 struct svc_xprt_class
*xcl
;
116 struct sockaddr_in sin
= {
117 .sin_family
= AF_INET
,
118 .sin_addr
.s_addr
= INADDR_ANY
,
119 .sin_port
= htons(port
),
121 dprintk("svc: creating transport %s[%d]\n", xprt_name
, port
);
122 spin_lock(&svc_xprt_class_lock
);
123 list_for_each_entry(xcl
, &svc_xprt_class_list
, xcl_list
) {
124 if (strcmp(xprt_name
, xcl
->xcl_name
) == 0) {
125 spin_unlock(&svc_xprt_class_lock
);
126 if (try_module_get(xcl
->xcl_owner
)) {
127 struct svc_xprt
*newxprt
;
129 newxprt
= xcl
->xcl_ops
->xpo_create
131 (struct sockaddr
*)&sin
, sizeof(sin
),
133 if (IS_ERR(newxprt
)) {
134 module_put(xcl
->xcl_owner
);
135 ret
= PTR_ERR(newxprt
);
141 spin_unlock(&svc_xprt_class_lock
);
142 dprintk("svc: transport %s not found\n", xprt_name
);
146 EXPORT_SYMBOL_GPL(svc_create_xprt
);
This page took 0.032895 seconds and 5 git commands to generate.