aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/clnt.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pretzel.yyz.us>2005-06-26 23:38:58 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-06-26 23:38:58 -0400
commit5696c1944a33b4434a9a1ebb6383b906afd43a10 (patch)
tree16fbe6ba431bcf949ee8645510b0c2fd39b5810f /net/sunrpc/clnt.c
parent66b04a80eea60cabf9d89fd34deb3234a740052f (diff)
parent020f46a39eb7b99a575b9f4d105fce2b142acdf1 (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'net/sunrpc/clnt.c')
-rw-r--r--net/sunrpc/clnt.c205
1 files changed, 157 insertions, 48 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 02bc029d46fe..f17e6153b688 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -97,12 +97,13 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, char *dir_name)
97 * made to sleep too long. 97 * made to sleep too long.
98 */ 98 */
99struct rpc_clnt * 99struct rpc_clnt *
100rpc_create_client(struct rpc_xprt *xprt, char *servname, 100rpc_new_client(struct rpc_xprt *xprt, char *servname,
101 struct rpc_program *program, u32 vers, 101 struct rpc_program *program, u32 vers,
102 rpc_authflavor_t flavor) 102 rpc_authflavor_t flavor)
103{ 103{
104 struct rpc_version *version; 104 struct rpc_version *version;
105 struct rpc_clnt *clnt = NULL; 105 struct rpc_clnt *clnt = NULL;
106 struct rpc_auth *auth;
106 int err; 107 int err;
107 int len; 108 int len;
108 109
@@ -157,10 +158,11 @@ rpc_create_client(struct rpc_xprt *xprt, char *servname,
157 if (err < 0) 158 if (err < 0)
158 goto out_no_path; 159 goto out_no_path;
159 160
160 err = -ENOMEM; 161 auth = rpcauth_create(flavor, clnt);
161 if (!rpcauth_create(flavor, clnt)) { 162 if (IS_ERR(auth)) {
162 printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n", 163 printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
163 flavor); 164 flavor);
165 err = PTR_ERR(auth);
164 goto out_no_auth; 166 goto out_no_auth;
165 } 167 }
166 168
@@ -178,6 +180,37 @@ out_no_path:
178 kfree(clnt->cl_server); 180 kfree(clnt->cl_server);
179 kfree(clnt); 181 kfree(clnt);
180out_err: 182out_err:
183 xprt_destroy(xprt);
184 return ERR_PTR(err);
185}
186
187/**
188 * Create an RPC client
189 * @xprt - pointer to xprt struct
190 * @servname - name of server
191 * @info - rpc_program
192 * @version - rpc_program version
193 * @authflavor - rpc_auth flavour to use
194 *
195 * Creates an RPC client structure, then pings the server in order to
196 * determine if it is up, and if it supports this program and version.
197 *
198 * This function should never be called by asynchronous tasks such as
199 * the portmapper.
200 */
201struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
202 struct rpc_program *info, u32 version, rpc_authflavor_t authflavor)
203{
204 struct rpc_clnt *clnt;
205 int err;
206
207 clnt = rpc_new_client(xprt, servname, info, version, authflavor);
208 if (IS_ERR(clnt))
209 return clnt;
210 err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
211 if (err == 0)
212 return clnt;
213 rpc_shutdown_client(clnt);
181 return ERR_PTR(err); 214 return ERR_PTR(err);
182} 215}
183 216
@@ -208,6 +241,8 @@ rpc_clone_client(struct rpc_clnt *clnt)
208 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); 241 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
209 if (new->cl_auth) 242 if (new->cl_auth)
210 atomic_inc(&new->cl_auth->au_count); 243 atomic_inc(&new->cl_auth->au_count);
244 new->cl_pmap = &new->cl_pmap_default;
245 rpc_init_wait_queue(&new->cl_pmap_default.pm_bindwait, "bindwait");
211 return new; 246 return new;
212out_no_clnt: 247out_no_clnt:
213 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); 248 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__);
@@ -296,6 +331,44 @@ rpc_release_client(struct rpc_clnt *clnt)
296 rpc_destroy_client(clnt); 331 rpc_destroy_client(clnt);
297} 332}
298 333
334/**
335 * rpc_bind_new_program - bind a new RPC program to an existing client
336 * @old - old rpc_client
337 * @program - rpc program to set
338 * @vers - rpc program version
339 *
340 * Clones the rpc client and sets up a new RPC program. This is mainly
341 * of use for enabling different RPC programs to share the same transport.
342 * The Sun NFSv2/v3 ACL protocol can do this.
343 */
344struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *old,
345 struct rpc_program *program,
346 int vers)
347{
348 struct rpc_clnt *clnt;
349 struct rpc_version *version;
350 int err;
351
352 BUG_ON(vers >= program->nrvers || !program->version[vers]);
353 version = program->version[vers];
354 clnt = rpc_clone_client(old);
355 if (IS_ERR(clnt))
356 goto out;
357 clnt->cl_procinfo = version->procs;
358 clnt->cl_maxproc = version->nrprocs;
359 clnt->cl_protname = program->name;
360 clnt->cl_prog = program->number;
361 clnt->cl_vers = version->number;
362 clnt->cl_stats = program->stats;
363 err = rpc_ping(clnt, RPC_TASK_SOFT|RPC_TASK_NOINTR);
364 if (err != 0) {
365 rpc_shutdown_client(clnt);
366 clnt = ERR_PTR(err);
367 }
368out:
369 return clnt;
370}
371
299/* 372/*
300 * Default callback for async RPC calls 373 * Default callback for async RPC calls
301 */ 374 */
@@ -305,38 +378,41 @@ rpc_default_callback(struct rpc_task *task)
305} 378}
306 379
307/* 380/*
308 * Export the signal mask handling for aysnchronous code that 381 * Export the signal mask handling for synchronous code that
309 * sleeps on RPC calls 382 * sleeps on RPC calls
310 */ 383 */
384#define RPC_INTR_SIGNALS (sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGKILL))
311 385
386static void rpc_save_sigmask(sigset_t *oldset, int intr)
387{
388 unsigned long sigallow = 0;
389 sigset_t sigmask;
390
391 /* Block all signals except those listed in sigallow */
392 if (intr)
393 sigallow |= RPC_INTR_SIGNALS;
394 siginitsetinv(&sigmask, sigallow);
395 sigprocmask(SIG_BLOCK, &sigmask, oldset);
396}
397
398static inline void rpc_task_sigmask(struct rpc_task *task, sigset_t *oldset)
399{
400 rpc_save_sigmask(oldset, !RPC_TASK_UNINTERRUPTIBLE(task));
401}
402
403static inline void rpc_restore_sigmask(sigset_t *oldset)
404{
405 sigprocmask(SIG_SETMASK, oldset, NULL);
406}
407
312void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset) 408void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset)
313{ 409{
314 unsigned long sigallow = sigmask(SIGKILL); 410 rpc_save_sigmask(oldset, clnt->cl_intr);
315 unsigned long irqflags;
316
317 /* Turn off various signals */
318 if (clnt->cl_intr) {
319 struct k_sigaction *action = current->sighand->action;
320 if (action[SIGINT-1].sa.sa_handler == SIG_DFL)
321 sigallow |= sigmask(SIGINT);
322 if (action[SIGQUIT-1].sa.sa_handler == SIG_DFL)
323 sigallow |= sigmask(SIGQUIT);
324 }
325 spin_lock_irqsave(&current->sighand->siglock, irqflags);
326 *oldset = current->blocked;
327 siginitsetinv(&current->blocked, sigallow & ~oldset->sig[0]);
328 recalc_sigpending();
329 spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
330} 411}
331 412
332void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset) 413void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset)
333{ 414{
334 unsigned long irqflags; 415 rpc_restore_sigmask(oldset);
335
336 spin_lock_irqsave(&current->sighand->siglock, irqflags);
337 current->blocked = *oldset;
338 recalc_sigpending();
339 spin_unlock_irqrestore(&current->sighand->siglock, irqflags);
340} 416}
341 417
342/* 418/*
@@ -354,26 +430,26 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
354 430
355 BUG_ON(flags & RPC_TASK_ASYNC); 431 BUG_ON(flags & RPC_TASK_ASYNC);
356 432
357 rpc_clnt_sigmask(clnt, &oldset);
358
359 status = -ENOMEM; 433 status = -ENOMEM;
360 task = rpc_new_task(clnt, NULL, flags); 434 task = rpc_new_task(clnt, NULL, flags);
361 if (task == NULL) 435 if (task == NULL)
362 goto out; 436 goto out;
363 437
438 /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
439 rpc_task_sigmask(task, &oldset);
440
364 rpc_call_setup(task, msg, 0); 441 rpc_call_setup(task, msg, 0);
365 442
366 /* Set up the call info struct and execute the task */ 443 /* Set up the call info struct and execute the task */
367 if (task->tk_status == 0) 444 if (task->tk_status == 0) {
368 status = rpc_execute(task); 445 status = rpc_execute(task);
369 else { 446 } else {
370 status = task->tk_status; 447 status = task->tk_status;
371 rpc_release_task(task); 448 rpc_release_task(task);
372 } 449 }
373 450
451 rpc_restore_sigmask(&oldset);
374out: 452out:
375 rpc_clnt_sigunmask(clnt, &oldset);
376
377 return status; 453 return status;
378} 454}
379 455
@@ -394,8 +470,6 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
394 470
395 flags |= RPC_TASK_ASYNC; 471 flags |= RPC_TASK_ASYNC;
396 472
397 rpc_clnt_sigmask(clnt, &oldset);
398
399 /* Create/initialize a new RPC task */ 473 /* Create/initialize a new RPC task */
400 if (!callback) 474 if (!callback)
401 callback = rpc_default_callback; 475 callback = rpc_default_callback;
@@ -404,6 +478,9 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
404 goto out; 478 goto out;
405 task->tk_calldata = data; 479 task->tk_calldata = data;
406 480
481 /* Mask signals on GSS_AUTH upcalls */
482 rpc_task_sigmask(task, &oldset);
483
407 rpc_call_setup(task, msg, 0); 484 rpc_call_setup(task, msg, 0);
408 485
409 /* Set up the call info struct and execute the task */ 486 /* Set up the call info struct and execute the task */
@@ -413,9 +490,8 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
413 else 490 else
414 rpc_release_task(task); 491 rpc_release_task(task);
415 492
493 rpc_restore_sigmask(&oldset);
416out: 494out:
417 rpc_clnt_sigunmask(clnt, &oldset);
418
419 return status; 495 return status;
420} 496}
421 497
@@ -593,7 +669,7 @@ call_allocate(struct rpc_task *task)
593 return; 669 return;
594 printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task); 670 printk(KERN_INFO "RPC: buffer allocation failed for task %p\n", task);
595 671
596 if (RPC_IS_ASYNC(task) || !(task->tk_client->cl_intr && signalled())) { 672 if (RPC_IS_ASYNC(task) || !signalled()) {
597 xprt_release(task); 673 xprt_release(task);
598 task->tk_action = call_reserve; 674 task->tk_action = call_reserve;
599 rpc_delay(task, HZ>>4); 675 rpc_delay(task, HZ>>4);
@@ -957,7 +1033,9 @@ call_header(struct rpc_task *task)
957 *p++ = htonl(clnt->cl_prog); /* program number */ 1033 *p++ = htonl(clnt->cl_prog); /* program number */
958 *p++ = htonl(clnt->cl_vers); /* program version */ 1034 *p++ = htonl(clnt->cl_vers); /* program version */
959 *p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */ 1035 *p++ = htonl(task->tk_msg.rpc_proc->p_proc); /* procedure */
960 return rpcauth_marshcred(task, p); 1036 p = rpcauth_marshcred(task, p);
1037 req->rq_slen = xdr_adjust_iovec(&req->rq_svec[0], p);
1038 return p;
961} 1039}
962 1040
963/* 1041/*
@@ -986,10 +1064,11 @@ call_verify(struct rpc_task *task)
986 case RPC_AUTH_ERROR: 1064 case RPC_AUTH_ERROR:
987 break; 1065 break;
988 case RPC_MISMATCH: 1066 case RPC_MISMATCH:
989 printk(KERN_WARNING "%s: RPC call version mismatch!\n", __FUNCTION__); 1067 dprintk("%s: RPC call version mismatch!\n", __FUNCTION__);
990 goto out_eio; 1068 error = -EPROTONOSUPPORT;
1069 goto out_err;
991 default: 1070 default:
992 printk(KERN_WARNING "%s: RPC call rejected, unknown error: %x\n", __FUNCTION__, n); 1071 dprintk("%s: RPC call rejected, unknown error: %x\n", __FUNCTION__, n);
993 goto out_eio; 1072 goto out_eio;
994 } 1073 }
995 if (--len < 0) 1074 if (--len < 0)
@@ -1040,23 +1119,26 @@ call_verify(struct rpc_task *task)
1040 case RPC_SUCCESS: 1119 case RPC_SUCCESS:
1041 return p; 1120 return p;
1042 case RPC_PROG_UNAVAIL: 1121 case RPC_PROG_UNAVAIL:
1043 printk(KERN_WARNING "RPC: call_verify: program %u is unsupported by server %s\n", 1122 dprintk("RPC: call_verify: program %u is unsupported by server %s\n",
1044 (unsigned int)task->tk_client->cl_prog, 1123 (unsigned int)task->tk_client->cl_prog,
1045 task->tk_client->cl_server); 1124 task->tk_client->cl_server);
1046 goto out_eio; 1125 error = -EPFNOSUPPORT;
1126 goto out_err;
1047 case RPC_PROG_MISMATCH: 1127 case RPC_PROG_MISMATCH:
1048 printk(KERN_WARNING "RPC: call_verify: program %u, version %u unsupported by server %s\n", 1128 dprintk("RPC: call_verify: program %u, version %u unsupported by server %s\n",
1049 (unsigned int)task->tk_client->cl_prog, 1129 (unsigned int)task->tk_client->cl_prog,
1050 (unsigned int)task->tk_client->cl_vers, 1130 (unsigned int)task->tk_client->cl_vers,
1051 task->tk_client->cl_server); 1131 task->tk_client->cl_server);
1052 goto out_eio; 1132 error = -EPROTONOSUPPORT;
1133 goto out_err;
1053 case RPC_PROC_UNAVAIL: 1134 case RPC_PROC_UNAVAIL:
1054 printk(KERN_WARNING "RPC: call_verify: proc %p unsupported by program %u, version %u on server %s\n", 1135 dprintk("RPC: call_verify: proc %p unsupported by program %u, version %u on server %s\n",
1055 task->tk_msg.rpc_proc, 1136 task->tk_msg.rpc_proc,
1056 task->tk_client->cl_prog, 1137 task->tk_client->cl_prog,
1057 task->tk_client->cl_vers, 1138 task->tk_client->cl_vers,
1058 task->tk_client->cl_server); 1139 task->tk_client->cl_server);
1059 goto out_eio; 1140 error = -EOPNOTSUPP;
1141 goto out_err;
1060 case RPC_GARBAGE_ARGS: 1142 case RPC_GARBAGE_ARGS:
1061 dprintk("RPC: %4d %s: server saw garbage\n", task->tk_pid, __FUNCTION__); 1143 dprintk("RPC: %4d %s: server saw garbage\n", task->tk_pid, __FUNCTION__);
1062 break; /* retry */ 1144 break; /* retry */
@@ -1069,7 +1151,7 @@ out_retry:
1069 task->tk_client->cl_stats->rpcgarbage++; 1151 task->tk_client->cl_stats->rpcgarbage++;
1070 if (task->tk_garb_retry) { 1152 if (task->tk_garb_retry) {
1071 task->tk_garb_retry--; 1153 task->tk_garb_retry--;
1072 dprintk(KERN_WARNING "RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid); 1154 dprintk("RPC %s: retrying %4d\n", __FUNCTION__, task->tk_pid);
1073 task->tk_action = call_bind; 1155 task->tk_action = call_bind;
1074 return NULL; 1156 return NULL;
1075 } 1157 }
@@ -1083,3 +1165,30 @@ out_overflow:
1083 printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__); 1165 printk(KERN_WARNING "RPC %s: server reply was truncated.\n", __FUNCTION__);
1084 goto out_retry; 1166 goto out_retry;
1085} 1167}
1168
1169static int rpcproc_encode_null(void *rqstp, u32 *data, void *obj)
1170{
1171 return 0;
1172}
1173
1174static int rpcproc_decode_null(void *rqstp, u32 *data, void *obj)
1175{
1176 return 0;
1177}
1178
1179static struct rpc_procinfo rpcproc_null = {
1180 .p_encode = rpcproc_encode_null,
1181 .p_decode = rpcproc_decode_null,
1182};
1183
1184int rpc_ping(struct rpc_clnt *clnt, int flags)
1185{
1186 struct rpc_message msg = {
1187 .rpc_proc = &rpcproc_null,
1188 };
1189 int err;
1190 msg.rpc_cred = authnull_ops.lookup_cred(NULL, NULL, 0);
1191 err = rpc_call_sync(clnt, &msg, flags);
1192 put_rpccred(msg.rpc_cred);
1193 return err;
1194}