diff options
Diffstat (limited to 'fs/lockd/xdr.c')
-rw-r--r-- | fs/lockd/xdr.c | 635 |
1 files changed, 635 insertions, 0 deletions
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c new file mode 100644 index 000000000000..f01e9c0d2677 --- /dev/null +++ b/fs/lockd/xdr.c | |||
@@ -0,0 +1,635 @@ | |||
1 | /* | ||
2 | * linux/fs/lockd/xdr.c | ||
3 | * | ||
4 | * XDR support for lockd and the lock client. | ||
5 | * | ||
6 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | ||
7 | */ | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/sched.h> | ||
12 | #include <linux/utsname.h> | ||
13 | #include <linux/nfs.h> | ||
14 | |||
15 | #include <linux/sunrpc/xdr.h> | ||
16 | #include <linux/sunrpc/clnt.h> | ||
17 | #include <linux/sunrpc/svc.h> | ||
18 | #include <linux/sunrpc/stats.h> | ||
19 | #include <linux/lockd/lockd.h> | ||
20 | #include <linux/lockd/sm_inter.h> | ||
21 | |||
22 | #define NLMDBG_FACILITY NLMDBG_XDR | ||
23 | |||
24 | |||
25 | static inline loff_t | ||
26 | s32_to_loff_t(__s32 offset) | ||
27 | { | ||
28 | return (loff_t)offset; | ||
29 | } | ||
30 | |||
31 | static inline __s32 | ||
32 | loff_t_to_s32(loff_t offset) | ||
33 | { | ||
34 | __s32 res; | ||
35 | if (offset >= NLM_OFFSET_MAX) | ||
36 | res = NLM_OFFSET_MAX; | ||
37 | else if (offset <= -NLM_OFFSET_MAX) | ||
38 | res = -NLM_OFFSET_MAX; | ||
39 | else | ||
40 | res = offset; | ||
41 | return res; | ||
42 | } | ||
43 | |||
44 | /* | ||
45 | * XDR functions for basic NLM types | ||
46 | */ | ||
47 | static inline u32 *nlm_decode_cookie(u32 *p, struct nlm_cookie *c) | ||
48 | { | ||
49 | unsigned int len; | ||
50 | |||
51 | len = ntohl(*p++); | ||
52 | |||
53 | if(len==0) | ||
54 | { | ||
55 | c->len=4; | ||
56 | memset(c->data, 0, 4); /* hockeypux brain damage */ | ||
57 | } | ||
58 | else if(len<=NLM_MAXCOOKIELEN) | ||
59 | { | ||
60 | c->len=len; | ||
61 | memcpy(c->data, p, len); | ||
62 | p+=XDR_QUADLEN(len); | ||
63 | } | ||
64 | else | ||
65 | { | ||
66 | printk(KERN_NOTICE | ||
67 | "lockd: bad cookie size %d (only cookies under %d bytes are supported.)\n", len, NLM_MAXCOOKIELEN); | ||
68 | return NULL; | ||
69 | } | ||
70 | return p; | ||
71 | } | ||
72 | |||
73 | static inline u32 * | ||
74 | nlm_encode_cookie(u32 *p, struct nlm_cookie *c) | ||
75 | { | ||
76 | *p++ = htonl(c->len); | ||
77 | memcpy(p, c->data, c->len); | ||
78 | p+=XDR_QUADLEN(c->len); | ||
79 | return p; | ||
80 | } | ||
81 | |||
82 | static inline u32 * | ||
83 | nlm_decode_fh(u32 *p, struct nfs_fh *f) | ||
84 | { | ||
85 | unsigned int len; | ||
86 | |||
87 | if ((len = ntohl(*p++)) != NFS2_FHSIZE) { | ||
88 | printk(KERN_NOTICE | ||
89 | "lockd: bad fhandle size %d (should be %d)\n", | ||
90 | len, NFS2_FHSIZE); | ||
91 | return NULL; | ||
92 | } | ||
93 | f->size = NFS2_FHSIZE; | ||
94 | memset(f->data, 0, sizeof(f->data)); | ||
95 | memcpy(f->data, p, NFS2_FHSIZE); | ||
96 | return p + XDR_QUADLEN(NFS2_FHSIZE); | ||
97 | } | ||
98 | |||
99 | static inline u32 * | ||
100 | nlm_encode_fh(u32 *p, struct nfs_fh *f) | ||
101 | { | ||
102 | *p++ = htonl(NFS2_FHSIZE); | ||
103 | memcpy(p, f->data, NFS2_FHSIZE); | ||
104 | return p + XDR_QUADLEN(NFS2_FHSIZE); | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * Encode and decode owner handle | ||
109 | */ | ||
110 | static inline u32 * | ||
111 | nlm_decode_oh(u32 *p, struct xdr_netobj *oh) | ||
112 | { | ||
113 | return xdr_decode_netobj(p, oh); | ||
114 | } | ||
115 | |||
116 | static inline u32 * | ||
117 | nlm_encode_oh(u32 *p, struct xdr_netobj *oh) | ||
118 | { | ||
119 | return xdr_encode_netobj(p, oh); | ||
120 | } | ||
121 | |||
122 | static inline u32 * | ||
123 | nlm_decode_lock(u32 *p, struct nlm_lock *lock) | ||
124 | { | ||
125 | struct file_lock *fl = &lock->fl; | ||
126 | s32 start, len, end; | ||
127 | |||
128 | if (!(p = xdr_decode_string_inplace(p, &lock->caller, | ||
129 | &lock->len, | ||
130 | NLM_MAXSTRLEN)) | ||
131 | || !(p = nlm_decode_fh(p, &lock->fh)) | ||
132 | || !(p = nlm_decode_oh(p, &lock->oh))) | ||
133 | return NULL; | ||
134 | |||
135 | locks_init_lock(fl); | ||
136 | fl->fl_owner = current->files; | ||
137 | fl->fl_pid = ntohl(*p++); | ||
138 | fl->fl_flags = FL_POSIX; | ||
139 | fl->fl_type = F_RDLCK; /* as good as anything else */ | ||
140 | start = ntohl(*p++); | ||
141 | len = ntohl(*p++); | ||
142 | end = start + len - 1; | ||
143 | |||
144 | fl->fl_start = s32_to_loff_t(start); | ||
145 | |||
146 | if (len == 0 || end < 0) | ||
147 | fl->fl_end = OFFSET_MAX; | ||
148 | else | ||
149 | fl->fl_end = s32_to_loff_t(end); | ||
150 | return p; | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Encode a lock as part of an NLM call | ||
155 | */ | ||
156 | static u32 * | ||
157 | nlm_encode_lock(u32 *p, struct nlm_lock *lock) | ||
158 | { | ||
159 | struct file_lock *fl = &lock->fl; | ||
160 | __s32 start, len; | ||
161 | |||
162 | if (!(p = xdr_encode_string(p, lock->caller)) | ||
163 | || !(p = nlm_encode_fh(p, &lock->fh)) | ||
164 | || !(p = nlm_encode_oh(p, &lock->oh))) | ||
165 | return NULL; | ||
166 | |||
167 | if (fl->fl_start > NLM_OFFSET_MAX | ||
168 | || (fl->fl_end > NLM_OFFSET_MAX && fl->fl_end != OFFSET_MAX)) | ||
169 | return NULL; | ||
170 | |||
171 | start = loff_t_to_s32(fl->fl_start); | ||
172 | if (fl->fl_end == OFFSET_MAX) | ||
173 | len = 0; | ||
174 | else | ||
175 | len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1); | ||
176 | |||
177 | *p++ = htonl(fl->fl_pid); | ||
178 | *p++ = htonl(start); | ||
179 | *p++ = htonl(len); | ||
180 | |||
181 | return p; | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * Encode result of a TEST/TEST_MSG call | ||
186 | */ | ||
187 | static u32 * | ||
188 | nlm_encode_testres(u32 *p, struct nlm_res *resp) | ||
189 | { | ||
190 | s32 start, len; | ||
191 | |||
192 | if (!(p = nlm_encode_cookie(p, &resp->cookie))) | ||
193 | return NULL; | ||
194 | *p++ = resp->status; | ||
195 | |||
196 | if (resp->status == nlm_lck_denied) { | ||
197 | struct file_lock *fl = &resp->lock.fl; | ||
198 | |||
199 | *p++ = (fl->fl_type == F_RDLCK)? xdr_zero : xdr_one; | ||
200 | *p++ = htonl(fl->fl_pid); | ||
201 | |||
202 | /* Encode owner handle. */ | ||
203 | if (!(p = xdr_encode_netobj(p, &resp->lock.oh))) | ||
204 | return NULL; | ||
205 | |||
206 | start = loff_t_to_s32(fl->fl_start); | ||
207 | if (fl->fl_end == OFFSET_MAX) | ||
208 | len = 0; | ||
209 | else | ||
210 | len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1); | ||
211 | |||
212 | *p++ = htonl(start); | ||
213 | *p++ = htonl(len); | ||
214 | } | ||
215 | |||
216 | return p; | ||
217 | } | ||
218 | |||
219 | |||
220 | /* | ||
221 | * First, the server side XDR functions | ||
222 | */ | ||
223 | int | ||
224 | nlmsvc_decode_testargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) | ||
225 | { | ||
226 | u32 exclusive; | ||
227 | |||
228 | if (!(p = nlm_decode_cookie(p, &argp->cookie))) | ||
229 | return 0; | ||
230 | |||
231 | exclusive = ntohl(*p++); | ||
232 | if (!(p = nlm_decode_lock(p, &argp->lock))) | ||
233 | return 0; | ||
234 | if (exclusive) | ||
235 | argp->lock.fl.fl_type = F_WRLCK; | ||
236 | |||
237 | return xdr_argsize_check(rqstp, p); | ||
238 | } | ||
239 | |||
240 | int | ||
241 | nlmsvc_encode_testres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) | ||
242 | { | ||
243 | if (!(p = nlm_encode_testres(p, resp))) | ||
244 | return 0; | ||
245 | return xdr_ressize_check(rqstp, p); | ||
246 | } | ||
247 | |||
248 | int | ||
249 | nlmsvc_decode_lockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) | ||
250 | { | ||
251 | u32 exclusive; | ||
252 | |||
253 | if (!(p = nlm_decode_cookie(p, &argp->cookie))) | ||
254 | return 0; | ||
255 | argp->block = ntohl(*p++); | ||
256 | exclusive = ntohl(*p++); | ||
257 | if (!(p = nlm_decode_lock(p, &argp->lock))) | ||
258 | return 0; | ||
259 | if (exclusive) | ||
260 | argp->lock.fl.fl_type = F_WRLCK; | ||
261 | argp->reclaim = ntohl(*p++); | ||
262 | argp->state = ntohl(*p++); | ||
263 | argp->monitor = 1; /* monitor client by default */ | ||
264 | |||
265 | return xdr_argsize_check(rqstp, p); | ||
266 | } | ||
267 | |||
268 | int | ||
269 | nlmsvc_decode_cancargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) | ||
270 | { | ||
271 | u32 exclusive; | ||
272 | |||
273 | if (!(p = nlm_decode_cookie(p, &argp->cookie))) | ||
274 | return 0; | ||
275 | argp->block = ntohl(*p++); | ||
276 | exclusive = ntohl(*p++); | ||
277 | if (!(p = nlm_decode_lock(p, &argp->lock))) | ||
278 | return 0; | ||
279 | if (exclusive) | ||
280 | argp->lock.fl.fl_type = F_WRLCK; | ||
281 | return xdr_argsize_check(rqstp, p); | ||
282 | } | ||
283 | |||
284 | int | ||
285 | nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) | ||
286 | { | ||
287 | if (!(p = nlm_decode_cookie(p, &argp->cookie)) | ||
288 | || !(p = nlm_decode_lock(p, &argp->lock))) | ||
289 | return 0; | ||
290 | argp->lock.fl.fl_type = F_UNLCK; | ||
291 | return xdr_argsize_check(rqstp, p); | ||
292 | } | ||
293 | |||
294 | int | ||
295 | nlmsvc_decode_shareargs(struct svc_rqst *rqstp, u32 *p, nlm_args *argp) | ||
296 | { | ||
297 | struct nlm_lock *lock = &argp->lock; | ||
298 | |||
299 | memset(lock, 0, sizeof(*lock)); | ||
300 | locks_init_lock(&lock->fl); | ||
301 | lock->fl.fl_pid = ~(u32) 0; | ||
302 | |||
303 | if (!(p = nlm_decode_cookie(p, &argp->cookie)) | ||
304 | || !(p = xdr_decode_string_inplace(p, &lock->caller, | ||
305 | &lock->len, NLM_MAXSTRLEN)) | ||
306 | || !(p = nlm_decode_fh(p, &lock->fh)) | ||
307 | || !(p = nlm_decode_oh(p, &lock->oh))) | ||
308 | return 0; | ||
309 | argp->fsm_mode = ntohl(*p++); | ||
310 | argp->fsm_access = ntohl(*p++); | ||
311 | return xdr_argsize_check(rqstp, p); | ||
312 | } | ||
313 | |||
314 | int | ||
315 | nlmsvc_encode_shareres(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) | ||
316 | { | ||
317 | if (!(p = nlm_encode_cookie(p, &resp->cookie))) | ||
318 | return 0; | ||
319 | *p++ = resp->status; | ||
320 | *p++ = xdr_zero; /* sequence argument */ | ||
321 | return xdr_ressize_check(rqstp, p); | ||
322 | } | ||
323 | |||
324 | int | ||
325 | nlmsvc_encode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) | ||
326 | { | ||
327 | if (!(p = nlm_encode_cookie(p, &resp->cookie))) | ||
328 | return 0; | ||
329 | *p++ = resp->status; | ||
330 | return xdr_ressize_check(rqstp, p); | ||
331 | } | ||
332 | |||
333 | int | ||
334 | nlmsvc_decode_notify(struct svc_rqst *rqstp, u32 *p, struct nlm_args *argp) | ||
335 | { | ||
336 | struct nlm_lock *lock = &argp->lock; | ||
337 | |||
338 | if (!(p = xdr_decode_string_inplace(p, &lock->caller, | ||
339 | &lock->len, NLM_MAXSTRLEN))) | ||
340 | return 0; | ||
341 | argp->state = ntohl(*p++); | ||
342 | return xdr_argsize_check(rqstp, p); | ||
343 | } | ||
344 | |||
345 | int | ||
346 | nlmsvc_decode_reboot(struct svc_rqst *rqstp, u32 *p, struct nlm_reboot *argp) | ||
347 | { | ||
348 | if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN))) | ||
349 | return 0; | ||
350 | argp->state = ntohl(*p++); | ||
351 | /* Preserve the address in network byte order */ | ||
352 | argp->addr = *p++; | ||
353 | argp->vers = *p++; | ||
354 | argp->proto = *p++; | ||
355 | return xdr_argsize_check(rqstp, p); | ||
356 | } | ||
357 | |||
358 | int | ||
359 | nlmsvc_decode_res(struct svc_rqst *rqstp, u32 *p, struct nlm_res *resp) | ||
360 | { | ||
361 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) | ||
362 | return 0; | ||
363 | resp->status = ntohl(*p++); | ||
364 | return xdr_argsize_check(rqstp, p); | ||
365 | } | ||
366 | |||
367 | int | ||
368 | nlmsvc_decode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) | ||
369 | { | ||
370 | return xdr_argsize_check(rqstp, p); | ||
371 | } | ||
372 | |||
373 | int | ||
374 | nlmsvc_encode_void(struct svc_rqst *rqstp, u32 *p, void *dummy) | ||
375 | { | ||
376 | return xdr_ressize_check(rqstp, p); | ||
377 | } | ||
378 | |||
379 | /* | ||
380 | * Now, the client side XDR functions | ||
381 | */ | ||
382 | #ifdef NLMCLNT_SUPPORT_SHARES | ||
383 | static int | ||
384 | nlmclt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr) | ||
385 | { | ||
386 | return 0; | ||
387 | } | ||
388 | #endif | ||
389 | |||
390 | static int | ||
391 | nlmclt_encode_testargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) | ||
392 | { | ||
393 | struct nlm_lock *lock = &argp->lock; | ||
394 | |||
395 | if (!(p = nlm_encode_cookie(p, &argp->cookie))) | ||
396 | return -EIO; | ||
397 | *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; | ||
398 | if (!(p = nlm_encode_lock(p, lock))) | ||
399 | return -EIO; | ||
400 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | ||
401 | return 0; | ||
402 | } | ||
403 | |||
404 | static int | ||
405 | nlmclt_decode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) | ||
406 | { | ||
407 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) | ||
408 | return -EIO; | ||
409 | resp->status = ntohl(*p++); | ||
410 | if (resp->status == NLM_LCK_DENIED) { | ||
411 | struct file_lock *fl = &resp->lock.fl; | ||
412 | u32 excl; | ||
413 | s32 start, len, end; | ||
414 | |||
415 | memset(&resp->lock, 0, sizeof(resp->lock)); | ||
416 | locks_init_lock(fl); | ||
417 | excl = ntohl(*p++); | ||
418 | fl->fl_pid = ntohl(*p++); | ||
419 | if (!(p = nlm_decode_oh(p, &resp->lock.oh))) | ||
420 | return -EIO; | ||
421 | |||
422 | fl->fl_flags = FL_POSIX; | ||
423 | fl->fl_type = excl? F_WRLCK : F_RDLCK; | ||
424 | start = ntohl(*p++); | ||
425 | len = ntohl(*p++); | ||
426 | end = start + len - 1; | ||
427 | |||
428 | fl->fl_start = s32_to_loff_t(start); | ||
429 | if (len == 0 || end < 0) | ||
430 | fl->fl_end = OFFSET_MAX; | ||
431 | else | ||
432 | fl->fl_end = s32_to_loff_t(end); | ||
433 | } | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | |||
438 | static int | ||
439 | nlmclt_encode_lockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) | ||
440 | { | ||
441 | struct nlm_lock *lock = &argp->lock; | ||
442 | |||
443 | if (!(p = nlm_encode_cookie(p, &argp->cookie))) | ||
444 | return -EIO; | ||
445 | *p++ = argp->block? xdr_one : xdr_zero; | ||
446 | *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; | ||
447 | if (!(p = nlm_encode_lock(p, lock))) | ||
448 | return -EIO; | ||
449 | *p++ = argp->reclaim? xdr_one : xdr_zero; | ||
450 | *p++ = htonl(argp->state); | ||
451 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static int | ||
456 | nlmclt_encode_cancargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) | ||
457 | { | ||
458 | struct nlm_lock *lock = &argp->lock; | ||
459 | |||
460 | if (!(p = nlm_encode_cookie(p, &argp->cookie))) | ||
461 | return -EIO; | ||
462 | *p++ = argp->block? xdr_one : xdr_zero; | ||
463 | *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; | ||
464 | if (!(p = nlm_encode_lock(p, lock))) | ||
465 | return -EIO; | ||
466 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | ||
467 | return 0; | ||
468 | } | ||
469 | |||
470 | static int | ||
471 | nlmclt_encode_unlockargs(struct rpc_rqst *req, u32 *p, nlm_args *argp) | ||
472 | { | ||
473 | struct nlm_lock *lock = &argp->lock; | ||
474 | |||
475 | if (!(p = nlm_encode_cookie(p, &argp->cookie))) | ||
476 | return -EIO; | ||
477 | if (!(p = nlm_encode_lock(p, lock))) | ||
478 | return -EIO; | ||
479 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | ||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | static int | ||
484 | nlmclt_encode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) | ||
485 | { | ||
486 | if (!(p = nlm_encode_cookie(p, &resp->cookie))) | ||
487 | return -EIO; | ||
488 | *p++ = resp->status; | ||
489 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | ||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | static int | ||
494 | nlmclt_encode_testres(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) | ||
495 | { | ||
496 | if (!(p = nlm_encode_testres(p, resp))) | ||
497 | return -EIO; | ||
498 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static int | ||
503 | nlmclt_decode_res(struct rpc_rqst *req, u32 *p, struct nlm_res *resp) | ||
504 | { | ||
505 | if (!(p = nlm_decode_cookie(p, &resp->cookie))) | ||
506 | return -EIO; | ||
507 | resp->status = ntohl(*p++); | ||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * Buffer requirements for NLM | ||
513 | */ | ||
514 | #define NLM_void_sz 0 | ||
515 | #define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) | ||
516 | #define NLM_caller_sz 1+XDR_QUADLEN(sizeof(system_utsname.nodename)) | ||
517 | #define NLM_netobj_sz 1+XDR_QUADLEN(XDR_MAX_NETOBJ) | ||
518 | /* #define NLM_owner_sz 1+XDR_QUADLEN(NLM_MAXOWNER) */ | ||
519 | #define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE) | ||
520 | #define NLM_lock_sz 3+NLM_caller_sz+NLM_netobj_sz+NLM_fhandle_sz | ||
521 | #define NLM_holder_sz 4+NLM_netobj_sz | ||
522 | |||
523 | #define NLM_testargs_sz NLM_cookie_sz+1+NLM_lock_sz | ||
524 | #define NLM_lockargs_sz NLM_cookie_sz+4+NLM_lock_sz | ||
525 | #define NLM_cancargs_sz NLM_cookie_sz+2+NLM_lock_sz | ||
526 | #define NLM_unlockargs_sz NLM_cookie_sz+NLM_lock_sz | ||
527 | |||
528 | #define NLM_testres_sz NLM_cookie_sz+1+NLM_holder_sz | ||
529 | #define NLM_res_sz NLM_cookie_sz+1 | ||
530 | #define NLM_norep_sz 0 | ||
531 | |||
532 | #ifndef MAX | ||
533 | # define MAX(a, b) (((a) > (b))? (a) : (b)) | ||
534 | #endif | ||
535 | |||
536 | /* | ||
537 | * For NLM, a void procedure really returns nothing | ||
538 | */ | ||
539 | #define nlmclt_decode_norep NULL | ||
540 | |||
541 | #define PROC(proc, argtype, restype) \ | ||
542 | [NLMPROC_##proc] = { \ | ||
543 | .p_proc = NLMPROC_##proc, \ | ||
544 | .p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \ | ||
545 | .p_decode = (kxdrproc_t) nlmclt_decode_##restype, \ | ||
546 | .p_bufsiz = MAX(NLM_##argtype##_sz, NLM_##restype##_sz) << 2 \ | ||
547 | } | ||
548 | |||
549 | static struct rpc_procinfo nlm_procedures[] = { | ||
550 | PROC(TEST, testargs, testres), | ||
551 | PROC(LOCK, lockargs, res), | ||
552 | PROC(CANCEL, cancargs, res), | ||
553 | PROC(UNLOCK, unlockargs, res), | ||
554 | PROC(GRANTED, testargs, res), | ||
555 | PROC(TEST_MSG, testargs, norep), | ||
556 | PROC(LOCK_MSG, lockargs, norep), | ||
557 | PROC(CANCEL_MSG, cancargs, norep), | ||
558 | PROC(UNLOCK_MSG, unlockargs, norep), | ||
559 | PROC(GRANTED_MSG, testargs, norep), | ||
560 | PROC(TEST_RES, testres, norep), | ||
561 | PROC(LOCK_RES, res, norep), | ||
562 | PROC(CANCEL_RES, res, norep), | ||
563 | PROC(UNLOCK_RES, res, norep), | ||
564 | PROC(GRANTED_RES, res, norep), | ||
565 | #ifdef NLMCLNT_SUPPORT_SHARES | ||
566 | PROC(SHARE, shareargs, shareres), | ||
567 | PROC(UNSHARE, shareargs, shareres), | ||
568 | PROC(NM_LOCK, lockargs, res), | ||
569 | PROC(FREE_ALL, notify, void), | ||
570 | #endif | ||
571 | }; | ||
572 | |||
573 | static struct rpc_version nlm_version1 = { | ||
574 | .number = 1, | ||
575 | .nrprocs = 16, | ||
576 | .procs = nlm_procedures, | ||
577 | }; | ||
578 | |||
579 | static struct rpc_version nlm_version3 = { | ||
580 | .number = 3, | ||
581 | .nrprocs = 24, | ||
582 | .procs = nlm_procedures, | ||
583 | }; | ||
584 | |||
585 | #ifdef CONFIG_LOCKD_V4 | ||
586 | extern struct rpc_version nlm_version4; | ||
587 | #endif | ||
588 | |||
589 | static struct rpc_version * nlm_versions[] = { | ||
590 | [1] = &nlm_version1, | ||
591 | [3] = &nlm_version3, | ||
592 | #ifdef CONFIG_LOCKD_V4 | ||
593 | [4] = &nlm_version4, | ||
594 | #endif | ||
595 | }; | ||
596 | |||
597 | static struct rpc_stat nlm_stats; | ||
598 | |||
599 | struct rpc_program nlm_program = { | ||
600 | .name = "lockd", | ||
601 | .number = NLM_PROGRAM, | ||
602 | .nrvers = sizeof(nlm_versions) / sizeof(nlm_versions[0]), | ||
603 | .version = nlm_versions, | ||
604 | .stats = &nlm_stats, | ||
605 | }; | ||
606 | |||
607 | #ifdef RPC_DEBUG | ||
608 | const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) | ||
609 | { | ||
610 | /* | ||
611 | * We can get away with a static buffer because we're only | ||
612 | * called with BKL held. | ||
613 | */ | ||
614 | static char buf[2*NLM_MAXCOOKIELEN+1]; | ||
615 | int i; | ||
616 | int len = sizeof(buf); | ||
617 | char *p = buf; | ||
618 | |||
619 | len--; /* allow for trailing \0 */ | ||
620 | if (len < 3) | ||
621 | return "???"; | ||
622 | for (i = 0 ; i < cookie->len ; i++) { | ||
623 | if (len < 2) { | ||
624 | strcpy(p-3, "..."); | ||
625 | break; | ||
626 | } | ||
627 | sprintf(p, "%02x", cookie->data[i]); | ||
628 | p += 2; | ||
629 | len -= 2; | ||
630 | } | ||
631 | *p = '\0'; | ||
632 | |||
633 | return buf; | ||
634 | } | ||
635 | #endif | ||