1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * linux/fs/lockd/svcproc.c |
4 | * |
5 | * Lockd server procedures. We don't implement the NLM_*_RES |
6 | * procedures because we don't use the async procedures. |
7 | * |
8 | * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> |
9 | */ |
10 | |
11 | #include <linux/types.h> |
12 | #include <linux/time.h> |
13 | #include <linux/lockd/lockd.h> |
14 | #include <linux/lockd/share.h> |
15 | #include <linux/sunrpc/svc_xprt.h> |
16 | |
17 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
18 | |
19 | #ifdef CONFIG_LOCKD_V4 |
20 | static __be32 |
21 | cast_to_nlm(__be32 status, u32 vers) |
22 | { |
23 | /* Note: status is assumed to be in network byte order !!! */ |
24 | if (vers != 4){ |
25 | switch (status) { |
26 | case nlm_granted: |
27 | case nlm_lck_denied: |
28 | case nlm_lck_denied_nolocks: |
29 | case nlm_lck_blocked: |
30 | case nlm_lck_denied_grace_period: |
31 | case nlm_drop_reply: |
32 | break; |
33 | case nlm4_deadlock: |
34 | status = nlm_lck_denied; |
35 | break; |
36 | default: |
37 | status = nlm_lck_denied_nolocks; |
38 | } |
39 | } |
40 | |
41 | return (status); |
42 | } |
43 | #define cast_status(status) (cast_to_nlm(status, rqstp->rq_vers)) |
44 | #else |
45 | #define cast_status(status) (status) |
46 | #endif |
47 | |
48 | /* |
49 | * Obtain client and file from arguments |
50 | */ |
51 | static __be32 |
52 | nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, |
53 | struct nlm_host **hostp, struct nlm_file **filp) |
54 | { |
55 | struct nlm_host *host = NULL; |
56 | struct nlm_file *file = NULL; |
57 | struct nlm_lock *lock = &argp->lock; |
58 | int mode; |
59 | __be32 error = 0; |
60 | |
61 | /* nfsd callbacks must have been installed for this procedure */ |
62 | if (!nlmsvc_ops) |
63 | return nlm_lck_denied_nolocks; |
64 | |
65 | /* Obtain host handle */ |
66 | if (!(host = nlmsvc_lookup_host(rqstp, hostname: lock->caller, hostname_len: lock->len)) |
67 | || (argp->monitor && nsm_monitor(host) < 0)) |
68 | goto no_locks; |
69 | *hostp = host; |
70 | |
71 | /* Obtain file pointer. Not used by FREE_ALL call. */ |
72 | if (filp != NULL) { |
73 | error = cast_status(nlm_lookup_file(rqstp, &file, lock)); |
74 | if (error != 0) |
75 | goto no_locks; |
76 | *filp = file; |
77 | |
78 | /* Set up the missing parts of the file_lock structure */ |
79 | mode = lock_to_openmode(&lock->fl); |
80 | lock->fl.c.flc_flags = FL_POSIX; |
81 | lock->fl.c.flc_file = file->f_file[mode]; |
82 | lock->fl.c.flc_pid = current->tgid; |
83 | lock->fl.fl_lmops = &nlmsvc_lock_operations; |
84 | nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid); |
85 | if (!lock->fl.c.flc_owner) { |
86 | /* lockowner allocation has failed */ |
87 | nlmsvc_release_host(host); |
88 | return nlm_lck_denied_nolocks; |
89 | } |
90 | } |
91 | |
92 | return 0; |
93 | |
94 | no_locks: |
95 | nlmsvc_release_host(host); |
96 | if (error) |
97 | return error; |
98 | return nlm_lck_denied_nolocks; |
99 | } |
100 | |
101 | /* |
102 | * NULL: Test for presence of service |
103 | */ |
104 | static __be32 |
105 | nlmsvc_proc_null(struct svc_rqst *rqstp) |
106 | { |
107 | dprintk("lockd: NULL called\n" ); |
108 | return rpc_success; |
109 | } |
110 | |
111 | /* |
112 | * TEST: Check for conflicting lock |
113 | */ |
114 | static __be32 |
115 | __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) |
116 | { |
117 | struct nlm_args *argp = rqstp->rq_argp; |
118 | struct nlm_host *host; |
119 | struct nlm_file *file; |
120 | struct nlm_lockowner *test_owner; |
121 | __be32 rc = rpc_success; |
122 | |
123 | dprintk("lockd: TEST called\n" ); |
124 | resp->cookie = argp->cookie; |
125 | |
126 | /* Obtain client and file */ |
127 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, hostp: &host, filp: &file))) |
128 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
129 | |
130 | test_owner = argp->lock.fl.c.flc_owner; |
131 | |
132 | /* Now check for conflicting locks */ |
133 | resp->status = cast_status(nlmsvc_testlock(rqstp, file, host, &argp->lock, &resp->lock, &resp->cookie)); |
134 | if (resp->status == nlm_drop_reply) |
135 | rc = rpc_drop_reply; |
136 | else |
137 | dprintk("lockd: TEST status %d vers %d\n" , |
138 | ntohl(resp->status), rqstp->rq_vers); |
139 | |
140 | nlmsvc_put_lockowner(test_owner); |
141 | nlmsvc_release_host(host); |
142 | nlm_release_file(file); |
143 | return rc; |
144 | } |
145 | |
146 | static __be32 |
147 | nlmsvc_proc_test(struct svc_rqst *rqstp) |
148 | { |
149 | return __nlmsvc_proc_test(rqstp, resp: rqstp->rq_resp); |
150 | } |
151 | |
152 | static __be32 |
153 | __nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp) |
154 | { |
155 | struct nlm_args *argp = rqstp->rq_argp; |
156 | struct nlm_host *host; |
157 | struct nlm_file *file; |
158 | __be32 rc = rpc_success; |
159 | |
160 | dprintk("lockd: LOCK called\n" ); |
161 | |
162 | resp->cookie = argp->cookie; |
163 | |
164 | /* Obtain client and file */ |
165 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, hostp: &host, filp: &file))) |
166 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
167 | |
168 | #if 0 |
169 | /* If supplied state doesn't match current state, we assume it's |
170 | * an old request that time-warped somehow. Any error return would |
171 | * do in this case because it's irrelevant anyway. |
172 | * |
173 | * NB: We don't retrieve the remote host's state yet. |
174 | */ |
175 | if (host->h_nsmstate && host->h_nsmstate != argp->state) { |
176 | resp->status = nlm_lck_denied_nolocks; |
177 | } else |
178 | #endif |
179 | |
180 | /* Now try to lock the file */ |
181 | resp->status = cast_status(nlmsvc_lock(rqstp, file, host, &argp->lock, |
182 | argp->block, &argp->cookie, |
183 | argp->reclaim)); |
184 | if (resp->status == nlm_drop_reply) |
185 | rc = rpc_drop_reply; |
186 | else |
187 | dprintk("lockd: LOCK status %d\n" , ntohl(resp->status)); |
188 | |
189 | nlmsvc_release_lockowner(&argp->lock); |
190 | nlmsvc_release_host(host); |
191 | nlm_release_file(file); |
192 | return rc; |
193 | } |
194 | |
195 | static __be32 |
196 | nlmsvc_proc_lock(struct svc_rqst *rqstp) |
197 | { |
198 | return __nlmsvc_proc_lock(rqstp, resp: rqstp->rq_resp); |
199 | } |
200 | |
201 | static __be32 |
202 | __nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp) |
203 | { |
204 | struct nlm_args *argp = rqstp->rq_argp; |
205 | struct nlm_host *host; |
206 | struct nlm_file *file; |
207 | struct net *net = SVC_NET(rqstp); |
208 | |
209 | dprintk("lockd: CANCEL called\n" ); |
210 | |
211 | resp->cookie = argp->cookie; |
212 | |
213 | /* Don't accept requests during grace period */ |
214 | if (locks_in_grace(net)) { |
215 | resp->status = nlm_lck_denied_grace_period; |
216 | return rpc_success; |
217 | } |
218 | |
219 | /* Obtain client and file */ |
220 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, hostp: &host, filp: &file))) |
221 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
222 | |
223 | /* Try to cancel request. */ |
224 | resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock)); |
225 | |
226 | dprintk("lockd: CANCEL status %d\n" , ntohl(resp->status)); |
227 | nlmsvc_release_lockowner(&argp->lock); |
228 | nlmsvc_release_host(host); |
229 | nlm_release_file(file); |
230 | return rpc_success; |
231 | } |
232 | |
233 | static __be32 |
234 | nlmsvc_proc_cancel(struct svc_rqst *rqstp) |
235 | { |
236 | return __nlmsvc_proc_cancel(rqstp, resp: rqstp->rq_resp); |
237 | } |
238 | |
239 | /* |
240 | * UNLOCK: release a lock |
241 | */ |
242 | static __be32 |
243 | __nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp) |
244 | { |
245 | struct nlm_args *argp = rqstp->rq_argp; |
246 | struct nlm_host *host; |
247 | struct nlm_file *file; |
248 | struct net *net = SVC_NET(rqstp); |
249 | |
250 | dprintk("lockd: UNLOCK called\n" ); |
251 | |
252 | resp->cookie = argp->cookie; |
253 | |
254 | /* Don't accept new lock requests during grace period */ |
255 | if (locks_in_grace(net)) { |
256 | resp->status = nlm_lck_denied_grace_period; |
257 | return rpc_success; |
258 | } |
259 | |
260 | /* Obtain client and file */ |
261 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, hostp: &host, filp: &file))) |
262 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
263 | |
264 | /* Now try to remove the lock */ |
265 | resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock)); |
266 | |
267 | dprintk("lockd: UNLOCK status %d\n" , ntohl(resp->status)); |
268 | nlmsvc_release_lockowner(&argp->lock); |
269 | nlmsvc_release_host(host); |
270 | nlm_release_file(file); |
271 | return rpc_success; |
272 | } |
273 | |
274 | static __be32 |
275 | nlmsvc_proc_unlock(struct svc_rqst *rqstp) |
276 | { |
277 | return __nlmsvc_proc_unlock(rqstp, resp: rqstp->rq_resp); |
278 | } |
279 | |
280 | /* |
281 | * GRANTED: A server calls us to tell that a process' lock request |
282 | * was granted |
283 | */ |
284 | static __be32 |
285 | __nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp) |
286 | { |
287 | struct nlm_args *argp = rqstp->rq_argp; |
288 | |
289 | resp->cookie = argp->cookie; |
290 | |
291 | dprintk("lockd: GRANTED called\n" ); |
292 | resp->status = nlmclnt_grant(addr: svc_addr(rqst: rqstp), lock: &argp->lock); |
293 | dprintk("lockd: GRANTED status %d\n" , ntohl(resp->status)); |
294 | return rpc_success; |
295 | } |
296 | |
297 | static __be32 |
298 | nlmsvc_proc_granted(struct svc_rqst *rqstp) |
299 | { |
300 | return __nlmsvc_proc_granted(rqstp, resp: rqstp->rq_resp); |
301 | } |
302 | |
303 | /* |
304 | * This is the generic lockd callback for async RPC calls |
305 | */ |
306 | static void nlmsvc_callback_exit(struct rpc_task *task, void *data) |
307 | { |
308 | } |
309 | |
310 | void nlmsvc_release_call(struct nlm_rqst *call) |
311 | { |
312 | if (!refcount_dec_and_test(r: &call->a_count)) |
313 | return; |
314 | nlmsvc_release_host(call->a_host); |
315 | kfree(objp: call); |
316 | } |
317 | |
318 | static void nlmsvc_callback_release(void *data) |
319 | { |
320 | nlmsvc_release_call(call: data); |
321 | } |
322 | |
323 | static const struct rpc_call_ops nlmsvc_callback_ops = { |
324 | .rpc_call_done = nlmsvc_callback_exit, |
325 | .rpc_release = nlmsvc_callback_release, |
326 | }; |
327 | |
328 | /* |
329 | * `Async' versions of the above service routines. They aren't really, |
330 | * because we send the callback before the reply proper. I hope this |
331 | * doesn't break any clients. |
332 | */ |
333 | static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, |
334 | __be32 (*func)(struct svc_rqst *, struct nlm_res *)) |
335 | { |
336 | struct nlm_args *argp = rqstp->rq_argp; |
337 | struct nlm_host *host; |
338 | struct nlm_rqst *call; |
339 | __be32 stat; |
340 | |
341 | host = nlmsvc_lookup_host(rqstp, |
342 | hostname: argp->lock.caller, |
343 | hostname_len: argp->lock.len); |
344 | if (host == NULL) |
345 | return rpc_system_err; |
346 | |
347 | call = nlm_alloc_call(host); |
348 | nlmsvc_release_host(host); |
349 | if (call == NULL) |
350 | return rpc_system_err; |
351 | |
352 | stat = func(rqstp, &call->a_res); |
353 | if (stat != 0) { |
354 | nlmsvc_release_call(call); |
355 | return stat; |
356 | } |
357 | |
358 | call->a_flags = RPC_TASK_ASYNC; |
359 | if (nlm_async_reply(call, proc, &nlmsvc_callback_ops) < 0) |
360 | return rpc_system_err; |
361 | return rpc_success; |
362 | } |
363 | |
364 | static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp) |
365 | { |
366 | dprintk("lockd: TEST_MSG called\n" ); |
367 | return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, func: __nlmsvc_proc_test); |
368 | } |
369 | |
370 | static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp) |
371 | { |
372 | dprintk("lockd: LOCK_MSG called\n" ); |
373 | return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, func: __nlmsvc_proc_lock); |
374 | } |
375 | |
376 | static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp) |
377 | { |
378 | dprintk("lockd: CANCEL_MSG called\n" ); |
379 | return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, func: __nlmsvc_proc_cancel); |
380 | } |
381 | |
382 | static __be32 |
383 | nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp) |
384 | { |
385 | dprintk("lockd: UNLOCK_MSG called\n" ); |
386 | return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, func: __nlmsvc_proc_unlock); |
387 | } |
388 | |
389 | static __be32 |
390 | nlmsvc_proc_granted_msg(struct svc_rqst *rqstp) |
391 | { |
392 | dprintk("lockd: GRANTED_MSG called\n" ); |
393 | return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, func: __nlmsvc_proc_granted); |
394 | } |
395 | |
396 | /* |
397 | * SHARE: create a DOS share or alter existing share. |
398 | */ |
399 | static __be32 |
400 | nlmsvc_proc_share(struct svc_rqst *rqstp) |
401 | { |
402 | struct nlm_args *argp = rqstp->rq_argp; |
403 | struct nlm_res *resp = rqstp->rq_resp; |
404 | struct nlm_host *host; |
405 | struct nlm_file *file; |
406 | |
407 | dprintk("lockd: SHARE called\n" ); |
408 | |
409 | resp->cookie = argp->cookie; |
410 | |
411 | /* Don't accept new lock requests during grace period */ |
412 | if (locks_in_grace(SVC_NET(rqstp)) && !argp->reclaim) { |
413 | resp->status = nlm_lck_denied_grace_period; |
414 | return rpc_success; |
415 | } |
416 | |
417 | /* Obtain client and file */ |
418 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, hostp: &host, filp: &file))) |
419 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
420 | |
421 | /* Now try to create the share */ |
422 | resp->status = cast_status(nlmsvc_share_file(host, file, argp)); |
423 | |
424 | dprintk("lockd: SHARE status %d\n" , ntohl(resp->status)); |
425 | nlmsvc_release_lockowner(&argp->lock); |
426 | nlmsvc_release_host(host); |
427 | nlm_release_file(file); |
428 | return rpc_success; |
429 | } |
430 | |
431 | /* |
432 | * UNSHARE: Release a DOS share. |
433 | */ |
434 | static __be32 |
435 | nlmsvc_proc_unshare(struct svc_rqst *rqstp) |
436 | { |
437 | struct nlm_args *argp = rqstp->rq_argp; |
438 | struct nlm_res *resp = rqstp->rq_resp; |
439 | struct nlm_host *host; |
440 | struct nlm_file *file; |
441 | |
442 | dprintk("lockd: UNSHARE called\n" ); |
443 | |
444 | resp->cookie = argp->cookie; |
445 | |
446 | /* Don't accept requests during grace period */ |
447 | if (locks_in_grace(SVC_NET(rqstp))) { |
448 | resp->status = nlm_lck_denied_grace_period; |
449 | return rpc_success; |
450 | } |
451 | |
452 | /* Obtain client and file */ |
453 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, hostp: &host, filp: &file))) |
454 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
455 | |
456 | /* Now try to unshare the file */ |
457 | resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); |
458 | |
459 | dprintk("lockd: UNSHARE status %d\n" , ntohl(resp->status)); |
460 | nlmsvc_release_lockowner(&argp->lock); |
461 | nlmsvc_release_host(host); |
462 | nlm_release_file(file); |
463 | return rpc_success; |
464 | } |
465 | |
466 | /* |
467 | * NM_LOCK: Create an unmonitored lock |
468 | */ |
469 | static __be32 |
470 | nlmsvc_proc_nm_lock(struct svc_rqst *rqstp) |
471 | { |
472 | struct nlm_args *argp = rqstp->rq_argp; |
473 | |
474 | dprintk("lockd: NM_LOCK called\n" ); |
475 | |
476 | argp->monitor = 0; /* just clean the monitor flag */ |
477 | return nlmsvc_proc_lock(rqstp); |
478 | } |
479 | |
480 | /* |
481 | * FREE_ALL: Release all locks and shares held by client |
482 | */ |
483 | static __be32 |
484 | nlmsvc_proc_free_all(struct svc_rqst *rqstp) |
485 | { |
486 | struct nlm_args *argp = rqstp->rq_argp; |
487 | struct nlm_host *host; |
488 | |
489 | /* Obtain client */ |
490 | if (nlmsvc_retrieve_args(rqstp, argp, hostp: &host, NULL)) |
491 | return rpc_success; |
492 | |
493 | nlmsvc_free_host_resources(host); |
494 | nlmsvc_release_host(host); |
495 | return rpc_success; |
496 | } |
497 | |
498 | /* |
499 | * SM_NOTIFY: private callback from statd (not part of official NLM proto) |
500 | */ |
501 | static __be32 |
502 | nlmsvc_proc_sm_notify(struct svc_rqst *rqstp) |
503 | { |
504 | struct nlm_reboot *argp = rqstp->rq_argp; |
505 | |
506 | dprintk("lockd: SM_NOTIFY called\n" ); |
507 | |
508 | if (!nlm_privileged_requester(rqstp)) { |
509 | char buf[RPC_MAX_ADDRBUFLEN]; |
510 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n" , |
511 | svc_print_addr(rqstp, buf, sizeof(buf))); |
512 | return rpc_system_err; |
513 | } |
514 | |
515 | nlm_host_rebooted(SVC_NET(rqstp), argp); |
516 | return rpc_success; |
517 | } |
518 | |
519 | /* |
520 | * client sent a GRANTED_RES, let's remove the associated block |
521 | */ |
522 | static __be32 |
523 | nlmsvc_proc_granted_res(struct svc_rqst *rqstp) |
524 | { |
525 | struct nlm_res *argp = rqstp->rq_argp; |
526 | |
527 | if (!nlmsvc_ops) |
528 | return rpc_success; |
529 | |
530 | dprintk("lockd: GRANTED_RES called\n" ); |
531 | |
532 | nlmsvc_grant_reply(&argp->cookie, argp->status); |
533 | return rpc_success; |
534 | } |
535 | |
536 | static __be32 |
537 | nlmsvc_proc_unused(struct svc_rqst *rqstp) |
538 | { |
539 | return rpc_proc_unavail; |
540 | } |
541 | |
542 | /* |
543 | * NLM Server procedures. |
544 | */ |
545 | |
546 | struct nlm_void { int dummy; }; |
547 | |
548 | #define Ck (1+XDR_QUADLEN(NLM_MAXCOOKIELEN)) /* cookie */ |
549 | #define St 1 /* status */ |
550 | #define No (1+1024/4) /* Net Obj */ |
551 | #define Rg 2 /* range - offset + size */ |
552 | |
553 | const struct svc_procedure nlmsvc_procedures[24] = { |
554 | [NLMPROC_NULL] = { |
555 | .pc_func = nlmsvc_proc_null, |
556 | .pc_decode = nlmsvc_decode_void, |
557 | .pc_encode = nlmsvc_encode_void, |
558 | .pc_argsize = sizeof(struct nlm_void), |
559 | .pc_argzero = sizeof(struct nlm_void), |
560 | .pc_ressize = sizeof(struct nlm_void), |
561 | .pc_xdrressize = St, |
562 | .pc_name = "NULL" , |
563 | }, |
564 | [NLMPROC_TEST] = { |
565 | .pc_func = nlmsvc_proc_test, |
566 | .pc_decode = nlmsvc_decode_testargs, |
567 | .pc_encode = nlmsvc_encode_testres, |
568 | .pc_argsize = sizeof(struct nlm_args), |
569 | .pc_argzero = sizeof(struct nlm_args), |
570 | .pc_ressize = sizeof(struct nlm_res), |
571 | .pc_xdrressize = Ck+St+2+No+Rg, |
572 | .pc_name = "TEST" , |
573 | }, |
574 | [NLMPROC_LOCK] = { |
575 | .pc_func = nlmsvc_proc_lock, |
576 | .pc_decode = nlmsvc_decode_lockargs, |
577 | .pc_encode = nlmsvc_encode_res, |
578 | .pc_argsize = sizeof(struct nlm_args), |
579 | .pc_argzero = sizeof(struct nlm_args), |
580 | .pc_ressize = sizeof(struct nlm_res), |
581 | .pc_xdrressize = Ck+St, |
582 | .pc_name = "LOCK" , |
583 | }, |
584 | [NLMPROC_CANCEL] = { |
585 | .pc_func = nlmsvc_proc_cancel, |
586 | .pc_decode = nlmsvc_decode_cancargs, |
587 | .pc_encode = nlmsvc_encode_res, |
588 | .pc_argsize = sizeof(struct nlm_args), |
589 | .pc_argzero = sizeof(struct nlm_args), |
590 | .pc_ressize = sizeof(struct nlm_res), |
591 | .pc_xdrressize = Ck+St, |
592 | .pc_name = "CANCEL" , |
593 | }, |
594 | [NLMPROC_UNLOCK] = { |
595 | .pc_func = nlmsvc_proc_unlock, |
596 | .pc_decode = nlmsvc_decode_unlockargs, |
597 | .pc_encode = nlmsvc_encode_res, |
598 | .pc_argsize = sizeof(struct nlm_args), |
599 | .pc_argzero = sizeof(struct nlm_args), |
600 | .pc_ressize = sizeof(struct nlm_res), |
601 | .pc_xdrressize = Ck+St, |
602 | .pc_name = "UNLOCK" , |
603 | }, |
604 | [NLMPROC_GRANTED] = { |
605 | .pc_func = nlmsvc_proc_granted, |
606 | .pc_decode = nlmsvc_decode_testargs, |
607 | .pc_encode = nlmsvc_encode_res, |
608 | .pc_argsize = sizeof(struct nlm_args), |
609 | .pc_argzero = sizeof(struct nlm_args), |
610 | .pc_ressize = sizeof(struct nlm_res), |
611 | .pc_xdrressize = Ck+St, |
612 | .pc_name = "GRANTED" , |
613 | }, |
614 | [NLMPROC_TEST_MSG] = { |
615 | .pc_func = nlmsvc_proc_test_msg, |
616 | .pc_decode = nlmsvc_decode_testargs, |
617 | .pc_encode = nlmsvc_encode_void, |
618 | .pc_argsize = sizeof(struct nlm_args), |
619 | .pc_argzero = sizeof(struct nlm_args), |
620 | .pc_ressize = sizeof(struct nlm_void), |
621 | .pc_xdrressize = St, |
622 | .pc_name = "TEST_MSG" , |
623 | }, |
624 | [NLMPROC_LOCK_MSG] = { |
625 | .pc_func = nlmsvc_proc_lock_msg, |
626 | .pc_decode = nlmsvc_decode_lockargs, |
627 | .pc_encode = nlmsvc_encode_void, |
628 | .pc_argsize = sizeof(struct nlm_args), |
629 | .pc_argzero = sizeof(struct nlm_args), |
630 | .pc_ressize = sizeof(struct nlm_void), |
631 | .pc_xdrressize = St, |
632 | .pc_name = "LOCK_MSG" , |
633 | }, |
634 | [NLMPROC_CANCEL_MSG] = { |
635 | .pc_func = nlmsvc_proc_cancel_msg, |
636 | .pc_decode = nlmsvc_decode_cancargs, |
637 | .pc_encode = nlmsvc_encode_void, |
638 | .pc_argsize = sizeof(struct nlm_args), |
639 | .pc_argzero = sizeof(struct nlm_args), |
640 | .pc_ressize = sizeof(struct nlm_void), |
641 | .pc_xdrressize = St, |
642 | .pc_name = "CANCEL_MSG" , |
643 | }, |
644 | [NLMPROC_UNLOCK_MSG] = { |
645 | .pc_func = nlmsvc_proc_unlock_msg, |
646 | .pc_decode = nlmsvc_decode_unlockargs, |
647 | .pc_encode = nlmsvc_encode_void, |
648 | .pc_argsize = sizeof(struct nlm_args), |
649 | .pc_argzero = sizeof(struct nlm_args), |
650 | .pc_ressize = sizeof(struct nlm_void), |
651 | .pc_xdrressize = St, |
652 | .pc_name = "UNLOCK_MSG" , |
653 | }, |
654 | [NLMPROC_GRANTED_MSG] = { |
655 | .pc_func = nlmsvc_proc_granted_msg, |
656 | .pc_decode = nlmsvc_decode_testargs, |
657 | .pc_encode = nlmsvc_encode_void, |
658 | .pc_argsize = sizeof(struct nlm_args), |
659 | .pc_argzero = sizeof(struct nlm_args), |
660 | .pc_ressize = sizeof(struct nlm_void), |
661 | .pc_xdrressize = St, |
662 | .pc_name = "GRANTED_MSG" , |
663 | }, |
664 | [NLMPROC_TEST_RES] = { |
665 | .pc_func = nlmsvc_proc_null, |
666 | .pc_decode = nlmsvc_decode_void, |
667 | .pc_encode = nlmsvc_encode_void, |
668 | .pc_argsize = sizeof(struct nlm_res), |
669 | .pc_argzero = sizeof(struct nlm_res), |
670 | .pc_ressize = sizeof(struct nlm_void), |
671 | .pc_xdrressize = St, |
672 | .pc_name = "TEST_RES" , |
673 | }, |
674 | [NLMPROC_LOCK_RES] = { |
675 | .pc_func = nlmsvc_proc_null, |
676 | .pc_decode = nlmsvc_decode_void, |
677 | .pc_encode = nlmsvc_encode_void, |
678 | .pc_argsize = sizeof(struct nlm_res), |
679 | .pc_argzero = sizeof(struct nlm_res), |
680 | .pc_ressize = sizeof(struct nlm_void), |
681 | .pc_xdrressize = St, |
682 | .pc_name = "LOCK_RES" , |
683 | }, |
684 | [NLMPROC_CANCEL_RES] = { |
685 | .pc_func = nlmsvc_proc_null, |
686 | .pc_decode = nlmsvc_decode_void, |
687 | .pc_encode = nlmsvc_encode_void, |
688 | .pc_argsize = sizeof(struct nlm_res), |
689 | .pc_argzero = sizeof(struct nlm_res), |
690 | .pc_ressize = sizeof(struct nlm_void), |
691 | .pc_xdrressize = St, |
692 | .pc_name = "CANCEL_RES" , |
693 | }, |
694 | [NLMPROC_UNLOCK_RES] = { |
695 | .pc_func = nlmsvc_proc_null, |
696 | .pc_decode = nlmsvc_decode_void, |
697 | .pc_encode = nlmsvc_encode_void, |
698 | .pc_argsize = sizeof(struct nlm_res), |
699 | .pc_argzero = sizeof(struct nlm_res), |
700 | .pc_ressize = sizeof(struct nlm_void), |
701 | .pc_xdrressize = St, |
702 | .pc_name = "UNLOCK_RES" , |
703 | }, |
704 | [NLMPROC_GRANTED_RES] = { |
705 | .pc_func = nlmsvc_proc_granted_res, |
706 | .pc_decode = nlmsvc_decode_res, |
707 | .pc_encode = nlmsvc_encode_void, |
708 | .pc_argsize = sizeof(struct nlm_res), |
709 | .pc_argzero = sizeof(struct nlm_res), |
710 | .pc_ressize = sizeof(struct nlm_void), |
711 | .pc_xdrressize = St, |
712 | .pc_name = "GRANTED_RES" , |
713 | }, |
714 | [NLMPROC_NSM_NOTIFY] = { |
715 | .pc_func = nlmsvc_proc_sm_notify, |
716 | .pc_decode = nlmsvc_decode_reboot, |
717 | .pc_encode = nlmsvc_encode_void, |
718 | .pc_argsize = sizeof(struct nlm_reboot), |
719 | .pc_argzero = sizeof(struct nlm_reboot), |
720 | .pc_ressize = sizeof(struct nlm_void), |
721 | .pc_xdrressize = St, |
722 | .pc_name = "SM_NOTIFY" , |
723 | }, |
724 | [17] = { |
725 | .pc_func = nlmsvc_proc_unused, |
726 | .pc_decode = nlmsvc_decode_void, |
727 | .pc_encode = nlmsvc_encode_void, |
728 | .pc_argsize = sizeof(struct nlm_void), |
729 | .pc_argzero = sizeof(struct nlm_void), |
730 | .pc_ressize = sizeof(struct nlm_void), |
731 | .pc_xdrressize = St, |
732 | .pc_name = "UNUSED" , |
733 | }, |
734 | [18] = { |
735 | .pc_func = nlmsvc_proc_unused, |
736 | .pc_decode = nlmsvc_decode_void, |
737 | .pc_encode = nlmsvc_encode_void, |
738 | .pc_argsize = sizeof(struct nlm_void), |
739 | .pc_argzero = sizeof(struct nlm_void), |
740 | .pc_ressize = sizeof(struct nlm_void), |
741 | .pc_xdrressize = St, |
742 | .pc_name = "UNUSED" , |
743 | }, |
744 | [19] = { |
745 | .pc_func = nlmsvc_proc_unused, |
746 | .pc_decode = nlmsvc_decode_void, |
747 | .pc_encode = nlmsvc_encode_void, |
748 | .pc_argsize = sizeof(struct nlm_void), |
749 | .pc_argzero = sizeof(struct nlm_void), |
750 | .pc_ressize = sizeof(struct nlm_void), |
751 | .pc_xdrressize = St, |
752 | .pc_name = "UNUSED" , |
753 | }, |
754 | [NLMPROC_SHARE] = { |
755 | .pc_func = nlmsvc_proc_share, |
756 | .pc_decode = nlmsvc_decode_shareargs, |
757 | .pc_encode = nlmsvc_encode_shareres, |
758 | .pc_argsize = sizeof(struct nlm_args), |
759 | .pc_argzero = sizeof(struct nlm_args), |
760 | .pc_ressize = sizeof(struct nlm_res), |
761 | .pc_xdrressize = Ck+St+1, |
762 | .pc_name = "SHARE" , |
763 | }, |
764 | [NLMPROC_UNSHARE] = { |
765 | .pc_func = nlmsvc_proc_unshare, |
766 | .pc_decode = nlmsvc_decode_shareargs, |
767 | .pc_encode = nlmsvc_encode_shareres, |
768 | .pc_argsize = sizeof(struct nlm_args), |
769 | .pc_argzero = sizeof(struct nlm_args), |
770 | .pc_ressize = sizeof(struct nlm_res), |
771 | .pc_xdrressize = Ck+St+1, |
772 | .pc_name = "UNSHARE" , |
773 | }, |
774 | [NLMPROC_NM_LOCK] = { |
775 | .pc_func = nlmsvc_proc_nm_lock, |
776 | .pc_decode = nlmsvc_decode_lockargs, |
777 | .pc_encode = nlmsvc_encode_res, |
778 | .pc_argsize = sizeof(struct nlm_args), |
779 | .pc_argzero = sizeof(struct nlm_args), |
780 | .pc_ressize = sizeof(struct nlm_res), |
781 | .pc_xdrressize = Ck+St, |
782 | .pc_name = "NM_LOCK" , |
783 | }, |
784 | [NLMPROC_FREE_ALL] = { |
785 | .pc_func = nlmsvc_proc_free_all, |
786 | .pc_decode = nlmsvc_decode_notify, |
787 | .pc_encode = nlmsvc_encode_void, |
788 | .pc_argsize = sizeof(struct nlm_args), |
789 | .pc_argzero = sizeof(struct nlm_args), |
790 | .pc_ressize = sizeof(struct nlm_void), |
791 | .pc_xdrressize = 0, |
792 | .pc_name = "FREE_ALL" , |
793 | }, |
794 | }; |
795 | |