aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2012-08-20 10:00:11 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-01 18:25:11 -0400
commitdd018428dce087b72d9e6a0b32e93cb8088b3aaa (patch)
treeffb555c77f9553fe01267ff26b452085c9a11999
parentc8ceb4124b53a439edfe3fe89a646be1e067ef17 (diff)
NFS: callback service creation function introduced
This function creates service if it's not exist, or increase usage counter of the existent, and returns pointer to it. Usage counter will be droppepd by svc_destroy() later in nfs_callback_up(). Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/nfs/callback.c63
1 files changed, 49 insertions, 14 deletions
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 51297b2d0532..18efeb5f005d 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -217,12 +217,50 @@ static inline void nfs_callback_bc_serv(u32 minorversion, struct rpc_xprt *xprt,
217} 217}
218#endif /* CONFIG_NFS_V4_1 */ 218#endif /* CONFIG_NFS_V4_1 */
219 219
220static struct svc_serv *nfs_callback_create_svc(int minorversion)
221{
222 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
223 struct svc_serv *serv;
224
225 /*
226 * Check whether we're already up and running.
227 */
228 if (cb_info->task) {
229 /*
230 * Note: increase service usage, because later in case of error
231 * svc_destroy() will be called.
232 */
233 svc_get(cb_info->serv);
234 return cb_info->serv;
235 }
236
237 /*
238 * Sanity check: if there's no task,
239 * we should be the first user ...
240 */
241 if (cb_info->users)
242 printk(KERN_WARNING "nfs_callback_create_svc: no kthread, %d users??\n",
243 cb_info->users);
244
245 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
246 if (!serv) {
247 printk(KERN_ERR "nfs_callback_create_svc: create service failed\n");
248 return ERR_PTR(-ENOMEM);
249 }
250 /* As there is only one thread we need to over-ride the
251 * default maximum of 80 connections
252 */
253 serv->sv_maxconn = 1024;
254 dprintk("nfs_callback_create_svc: service created\n");
255 return serv;
256}
257
220/* 258/*
221 * Bring up the callback thread if it is not already up. 259 * Bring up the callback thread if it is not already up.
222 */ 260 */
223int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt) 261int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
224{ 262{
225 struct svc_serv *serv = NULL; 263 struct svc_serv *serv;
226 struct svc_rqst *rqstp; 264 struct svc_rqst *rqstp;
227 int (*callback_svc)(void *vrqstp); 265 int (*callback_svc)(void *vrqstp);
228 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion]; 266 struct nfs_callback_data *cb_info = &nfs_callback_info[minorversion];
@@ -232,19 +270,17 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
232 struct net *net = &init_net; 270 struct net *net = &init_net;
233 271
234 mutex_lock(&nfs_callback_mutex); 272 mutex_lock(&nfs_callback_mutex);
273
274 serv = nfs_callback_create_svc(minorversion);
275 if (IS_ERR(serv)) {
276 ret = PTR_ERR(serv);
277 goto err_create;
278 }
279
235 if (cb_info->users++ || cb_info->task != NULL) { 280 if (cb_info->users++ || cb_info->task != NULL) {
236 nfs_callback_bc_serv(minorversion, xprt, cb_info); 281 nfs_callback_bc_serv(minorversion, xprt, cb_info);
237 goto out; 282 goto out;
238 } 283 }
239 serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE, NULL);
240 if (!serv) {
241 ret = -ENOMEM;
242 goto out_err;
243 }
244 /* As there is only one thread we need to over-ride the
245 * default maximum of 80 connections
246 */
247 serv->sv_maxconn = 1024;
248 284
249 ret = svc_bind(serv, net); 285 ret = svc_bind(serv, net);
250 if (ret < 0) { 286 if (ret < 0) {
@@ -285,16 +321,15 @@ out:
285 * on both success and failure so that the refcount is 1 when the 321 * on both success and failure so that the refcount is 1 when the
286 * thread exits. 322 * thread exits.
287 */ 323 */
288 if (serv) 324 svc_destroy(serv);
289 svc_destroy(serv); 325err_create:
290 mutex_unlock(&nfs_callback_mutex); 326 mutex_unlock(&nfs_callback_mutex);
291 return ret; 327 return ret;
292out_err: 328out_err:
293 dprintk("NFS: Couldn't create callback socket or server thread; " 329 dprintk("NFS: Couldn't create callback socket or server thread; "
294 "err = %d\n", ret); 330 "err = %d\n", ret);
295 cb_info->users--; 331 cb_info->users--;
296 if (serv) 332 svc_shutdown_net(serv, net);
297 svc_shutdown_net(serv, net);
298 goto out; 333 goto out;
299} 334}
300 335