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