aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/callback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/callback.c')
-rw-r--r--fs/nfs/callback.c65
1 files changed, 46 insertions, 19 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index a886e692ddd0..4b1313eda6f5 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -59,7 +59,7 @@ module_param_call(callback_tcpport, param_set_port, param_get_int,
59 * This is the callback kernel thread. 59 * This is the callback kernel thread.
60 */ 60 */
61static int 61static int
62nfs_callback_svc(void *vrqstp) 62nfs4_callback_svc(void *vrqstp)
63{ 63{
64 int err, preverr = 0; 64 int err, preverr = 0;
65 struct svc_rqst *rqstp = vrqstp; 65 struct svc_rqst *rqstp = vrqstp;
@@ -97,20 +97,12 @@ nfs_callback_svc(void *vrqstp)
97} 97}
98 98
99/* 99/*
100 * Bring up the callback thread if it is not already up. 100 * Prepare to bring up the NFSv4 callback service
101 */ 101 */
102int nfs_callback_up(void) 102struct svc_rqst *
103nfs4_callback_up(struct svc_serv *serv)
103{ 104{
104 struct svc_serv *serv = NULL; 105 int ret;
105 int ret = 0;
106
107 mutex_lock(&nfs_callback_mutex);
108 if (nfs_callback_info.users++ || nfs_callback_info.task != NULL)
109 goto out;
110 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
111 ret = -ENOMEM;
112 if (!serv)
113 goto out_err;
114 106
115 ret = svc_create_xprt(serv, "tcp", PF_INET, 107 ret = svc_create_xprt(serv, "tcp", PF_INET,
116 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS); 108 nfs_callback_set_tcpport, SVC_SOCK_ANONYMOUS);
@@ -131,18 +123,53 @@ int nfs_callback_up(void)
131 goto out_err; 123 goto out_err;
132#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ 124#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
133 125
134 nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]); 126 return svc_prepare_thread(serv, &serv->sv_pools[0]);
135 if (IS_ERR(nfs_callback_info.rqst)) { 127
136 ret = PTR_ERR(nfs_callback_info.rqst); 128out_err:
137 nfs_callback_info.rqst = NULL; 129 if (ret == 0)
130 ret = -ENOMEM;
131 return ERR_PTR(ret);
132}
133
134/*
135 * Bring up the callback thread if it is not already up.
136 */
137int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
138{
139 struct svc_serv *serv = NULL;
140 struct svc_rqst *rqstp;
141 int (*callback_svc)(void *vrqstp);
142 char svc_name[12];
143 int ret = 0;
144
145 mutex_lock(&nfs_callback_mutex);
146 if (nfs_callback_info.users++ || nfs_callback_info.task != NULL)
147 goto out;
148 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
149 if (!serv) {
150 ret = -ENOMEM;
151 goto out_err;
152 }
153
154 if (!minorversion) {
155 rqstp = nfs4_callback_up(serv);
156 callback_svc = nfs4_callback_svc;
157 } else {
158 BUG(); /* for now */
159 }
160
161 if (IS_ERR(rqstp)) {
162 ret = PTR_ERR(rqstp);
138 goto out_err; 163 goto out_err;
139 } 164 }
140 165
141 svc_sock_update_bufs(serv); 166 svc_sock_update_bufs(serv);
142 167
143 nfs_callback_info.task = kthread_run(nfs_callback_svc, 168 sprintf(svc_name, "nfsv4.%u-svc", minorversion);
169 nfs_callback_info.rqst = rqstp;
170 nfs_callback_info.task = kthread_run(callback_svc,
144 nfs_callback_info.rqst, 171 nfs_callback_info.rqst,
145 "nfsv4-svc"); 172 svc_name);
146 if (IS_ERR(nfs_callback_info.task)) { 173 if (IS_ERR(nfs_callback_info.task)) {
147 ret = PTR_ERR(nfs_callback_info.task); 174 ret = PTR_ERR(nfs_callback_info.task);
148 svc_exit_thread(nfs_callback_info.rqst); 175 svc_exit_thread(nfs_callback_info.rqst);