This source file includes following definitions.
- nfs_rpc_alloc
- nfs_rpc_free
- xdr_encode_fhandle
- xdr_decode_fhandle
- xdr_encode_string
- xdr_decode_string
- xdr_encode_data
- xdr_decode_data
- xdr_decode_fattr
- xdr_encode_sattr
- xdr_decode_entry
- xdr_decode_fsinfo
- nfs_proc_getattr
- nfs_proc_setattr
- nfs_proc_lookup
- nfs_proc_readlink
- nfs_proc_read
- nfs_proc_write
- nfs_proc_create
- nfs_proc_remove
- nfs_proc_rename
- nfs_proc_link
- nfs_proc_symlink
- nfs_proc_mkdir
- nfs_proc_rmdir
- nfs_proc_readdir
- nfs_proc_statfs
- nfs_rpc_header
- nfs_rpc_verify
- nfs_stat_to_errno
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #if 0
16 #define NFS_PROC_DEBUG
17 #endif
18
19 #include <linux/config.h>
20 #include <linux/param.h>
21 #include <linux/sched.h>
22 #include <linux/mm.h>
23 #include <linux/nfs_fs.h>
24 #include <linux/utsname.h>
25 #include <linux/errno.h>
26 #include <linux/string.h>
27 #include <linux/in.h>
28
29 #ifdef NFS_PROC_DEBUG
30
31 static int proc_debug = 0;
32 #define PRINTK(format, args...) \
33 do { \
34 if (proc_debug) \
35 printk(format , ## args); \
36 } while (0)
37
38 #else
39
40 #define PRINTK(format, args...) do ; while (0)
41
42 #endif
43
44 static int *nfs_rpc_header(int *p, int procedure);
45 static int *nfs_rpc_verify(int *p);
46 static int nfs_stat_to_errno(int stat);
47
48
49
50
51
52 static inline int *nfs_rpc_alloc(void)
53 {
54 return (int *) __get_free_page(GFP_KERNEL);
55 }
56
57 static inline void nfs_rpc_free(int *p)
58 {
59 free_page((long) p);
60 }
61
62
63
64
65
66
67 static inline int *xdr_encode_fhandle(int *p, struct nfs_fh *fhandle)
68 {
69 *((struct nfs_fh *) p) = *fhandle;
70 p += (sizeof (*fhandle) + 3) >> 2;
71 return p;
72 }
73
74 static inline int *xdr_decode_fhandle(int *p, struct nfs_fh *fhandle)
75 {
76 *fhandle = *((struct nfs_fh *) p);
77 p += (sizeof (*fhandle) + 3) >> 2;
78 return p;
79 }
80
81 static inline int *xdr_encode_string(int *p, const char *string)
82 {
83 int len, quadlen;
84
85 len = strlen(string);
86 quadlen = (len + 3) >> 2;
87 *p++ = htonl(len);
88 memcpy((char *) p, string, len);
89 memset(((char *) p) + len, '\0', (quadlen << 2) - len);
90 p += quadlen;
91 return p;
92 }
93
94 static inline int *xdr_decode_string(int *p, char *string, int maxlen)
95 {
96 unsigned int len;
97
98 len = ntohl(*p++);
99 if (len > maxlen)
100 return NULL;
101 memcpy(string, (char *) p, len);
102 string[len] = '\0';
103 p += (len + 3) >> 2;
104 return p;
105 }
106
107 static inline int *xdr_encode_data(int *p, char *data, int len)
108 {
109 int quadlen;
110
111 quadlen = (len + 3) >> 2;
112 *p++ = htonl(len);
113 memcpy((char *) p, data, len);
114 memset(((char *) p) + len, '\0', (quadlen << 2) - len);
115 p += quadlen;
116 return p;
117 }
118
119 static inline int *xdr_decode_data(int *p, char *data, int *lenp, int maxlen)
120 {
121 unsigned int len;
122
123 len = *lenp = ntohl(*p++);
124 if (len > maxlen)
125 return NULL;
126 memcpy(data, (char *) p, len);
127 p += (len + 3) >> 2;
128 return p;
129 }
130
131 static int *xdr_decode_fattr(int *p, struct nfs_fattr *fattr)
132 {
133 fattr->type = (enum nfs_ftype) ntohl(*p++);
134 fattr->mode = ntohl(*p++);
135 fattr->nlink = ntohl(*p++);
136 fattr->uid = ntohl(*p++);
137 fattr->gid = ntohl(*p++);
138 fattr->size = ntohl(*p++);
139 fattr->blocksize = ntohl(*p++);
140 fattr->rdev = ntohl(*p++);
141 fattr->blocks = ntohl(*p++);
142 fattr->fsid = ntohl(*p++);
143 fattr->fileid = ntohl(*p++);
144 fattr->atime.seconds = ntohl(*p++);
145 fattr->atime.useconds = ntohl(*p++);
146 fattr->mtime.seconds = ntohl(*p++);
147 fattr->mtime.useconds = ntohl(*p++);
148 fattr->ctime.seconds = ntohl(*p++);
149 fattr->ctime.useconds = ntohl(*p++);
150 return p;
151 }
152
153 static int *xdr_encode_sattr(int *p, struct nfs_sattr *sattr)
154 {
155 *p++ = htonl(sattr->mode);
156 *p++ = htonl(sattr->uid);
157 *p++ = htonl(sattr->gid);
158 *p++ = htonl(sattr->size);
159 *p++ = htonl(sattr->atime.seconds);
160 *p++ = htonl(sattr->atime.useconds);
161 *p++ = htonl(sattr->mtime.seconds);
162 *p++ = htonl(sattr->mtime.useconds);
163 return p;
164 }
165
166 static int *xdr_decode_entry(int *p, struct nfs_entry *entry)
167 {
168 entry->fileid = ntohl(*p++);
169 if (!(p = xdr_decode_string(p, entry->name, NFS_MAXNAMLEN)))
170 return NULL;
171 entry->cookie = ntohl(*p++);
172 entry->eof = 0;
173 return p;
174 }
175
176 static int *xdr_decode_fsinfo(int *p, struct nfs_fsinfo *res)
177 {
178 res->tsize = ntohl(*p++);
179 res->bsize = ntohl(*p++);
180 res->blocks = ntohl(*p++);
181 res->bfree = ntohl(*p++);
182 res->bavail = ntohl(*p++);
183 return p;
184 }
185
186
187
188
189
190 int nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
191 struct nfs_fattr *fattr)
192 {
193 int *p, *p0;
194 int status;
195
196 PRINTK("NFS call getattr\n");
197 if (!(p0 = nfs_rpc_alloc()))
198 return -EIO;
199 p = nfs_rpc_header(p0, NFSPROC_GETATTR);
200 p = xdr_encode_fhandle(p, fhandle);
201 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
202 nfs_rpc_free(p0);
203 return status;
204 }
205 if (!(p = nfs_rpc_verify(p0)))
206 status = NFSERR_IO;
207 else if ((status = ntohl(*p++)) == NFS_OK) {
208 p = xdr_decode_fattr(p, fattr);
209 PRINTK("NFS reply getattr\n");
210 }
211 else
212 PRINTK("NFS reply getattr failed = %d\n", status);
213 nfs_rpc_free(p0);
214 return -nfs_stat_to_errno(status);
215 }
216
217 int nfs_proc_setattr(struct nfs_server *server, struct nfs_fh *fhandle,
218 struct nfs_sattr *sattr, struct nfs_fattr *fattr)
219 {
220 int *p, *p0;
221 int status;
222
223 PRINTK("NFS call setattr\n");
224 if (!(p0 = nfs_rpc_alloc()))
225 return -EIO;
226 p = nfs_rpc_header(p0, NFSPROC_SETATTR);
227 p = xdr_encode_fhandle(p, fhandle);
228 p = xdr_encode_sattr(p, sattr);
229 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
230 nfs_rpc_free(p0);
231 return status;
232 }
233 if (!(p = nfs_rpc_verify(p0)))
234 status = NFSERR_IO;
235 else if ((status = ntohl(*p++)) == NFS_OK) {
236 p = xdr_decode_fattr(p, fattr);
237 PRINTK("NFS reply setattr\n");
238 }
239 else
240 PRINTK("NFS reply setattr failed = %d\n", status);
241 nfs_rpc_free(p0);
242 return -nfs_stat_to_errno(status);
243 }
244
245 int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir, const char *name,
246 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
247 {
248 int *p, *p0;
249 int status;
250
251 PRINTK("NFS call lookup %s\n", name);
252 #ifdef NFS_PROC_DEBUG
253 if (!strcmp(name, "xyzzy"))
254 proc_debug = 1 - proc_debug;
255 #endif
256 if (!(p0 = nfs_rpc_alloc()))
257 return -EIO;
258 p = nfs_rpc_header(p0, NFSPROC_LOOKUP);
259 p = xdr_encode_fhandle(p, dir);
260 p = xdr_encode_string(p, name);
261 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
262 nfs_rpc_free(p0);
263 return status;
264 }
265 if (!(p = nfs_rpc_verify(p0)))
266 status = NFSERR_IO;
267 else if ((status = ntohl(*p++)) == NFS_OK) {
268 p = xdr_decode_fhandle(p, fhandle);
269 p = xdr_decode_fattr(p, fattr);
270 PRINTK("NFS reply lookup\n");
271 }
272 else
273 PRINTK("NFS reply lookup failed = %d\n", status);
274 nfs_rpc_free(p0);
275 return -nfs_stat_to_errno(status);
276 }
277
278 int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
279 char *res)
280 {
281 int *p, *p0;
282 int status;
283
284 PRINTK("NFS call readlink\n");
285 if (!(p0 = nfs_rpc_alloc()))
286 return -EIO;
287 p = nfs_rpc_header(p0, NFSPROC_READLINK);
288 p = xdr_encode_fhandle(p, fhandle);
289 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
290 nfs_rpc_free(p0);
291 return status;
292 }
293 if (!(p = nfs_rpc_verify(p0)))
294 status = NFSERR_IO;
295 else if ((status = ntohl(*p++)) == NFS_OK) {
296 if (!(p = xdr_decode_string(p, res, NFS_MAXPATHLEN))) {
297 printk("nfs_proc_readlink: giant pathname\n");
298 status = NFSERR_IO;
299 }
300 else
301 PRINTK("NFS reply readlink %s\n", res);
302 }
303 else
304 PRINTK("NFS reply readlink failed = %d\n", status);
305 nfs_rpc_free(p0);
306 return -nfs_stat_to_errno(status);
307 }
308
309 int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
310 int offset, int count, char *data, struct nfs_fattr *fattr)
311 {
312 int *p, *p0;
313 int status;
314 int len = 0;
315
316 PRINTK("NFS call read %d @ %d\n", count, offset);
317 if (!(p0 = nfs_rpc_alloc()))
318 return -EIO;
319 p = nfs_rpc_header(p0, NFSPROC_READ);
320 p = xdr_encode_fhandle(p, fhandle);
321 *p++ = htonl(offset);
322 *p++ = htonl(count);
323 *p++ = htonl(count);
324 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
325 nfs_rpc_free(p0);
326 return status;
327 }
328 if (!(p = nfs_rpc_verify(p0)))
329 status = NFSERR_IO;
330 else if ((status = ntohl(*p++)) == NFS_OK) {
331 p = xdr_decode_fattr(p, fattr);
332 if (!(p = xdr_decode_data(p, data, &len, count))) {
333 printk("nfs_proc_read: giant data size\n");
334 status = NFSERR_IO;
335 }
336 else
337 PRINTK("NFS reply read %d\n", len);
338 }
339 else
340 PRINTK("NFS reply read failed = %d\n", status);
341 nfs_rpc_free(p0);
342 return (status == NFS_OK) ? len : -nfs_stat_to_errno(status);
343 }
344
345 int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
346 int offset, int count, char *data, struct nfs_fattr *fattr)
347 {
348 int *p, *p0;
349 int status;
350
351 PRINTK("NFS call write %d @ %d\n", count, offset);
352 if (!(p0 = nfs_rpc_alloc()))
353 return -EIO;
354 p = nfs_rpc_header(p0, NFSPROC_WRITE);
355 p = xdr_encode_fhandle(p, fhandle);
356 *p++ = htonl(offset);
357 *p++ = htonl(offset);
358 *p++ = htonl(count);
359 p = xdr_encode_data(p, data, count);
360 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
361 nfs_rpc_free(p0);
362 return status;
363 }
364 if (!(p = nfs_rpc_verify(p0)))
365 status = NFSERR_IO;
366 else if ((status = ntohl(*p++)) == NFS_OK) {
367 p = xdr_decode_fattr(p, fattr);
368 PRINTK("NFS reply write\n");
369 }
370 else
371 PRINTK("NFS reply write failed = %d\n", status);
372 nfs_rpc_free(p0);
373 return -nfs_stat_to_errno(status);
374 }
375
376 int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
377 const char *name, struct nfs_sattr *sattr,
378 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
379 {
380 int *p, *p0;
381 int status;
382
383 PRINTK("NFS call create %s\n", name);
384 if (!(p0 = nfs_rpc_alloc()))
385 return -EIO;
386 p = nfs_rpc_header(p0, NFSPROC_CREATE);
387 p = xdr_encode_fhandle(p, dir);
388 p = xdr_encode_string(p, name);
389 p = xdr_encode_sattr(p, sattr);
390 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
391 nfs_rpc_free(p0);
392 return status;
393 }
394 if (!(p = nfs_rpc_verify(p0)))
395 status = NFSERR_IO;
396 else if ((status = ntohl(*p++)) == NFS_OK) {
397 p = xdr_decode_fhandle(p, fhandle);
398 p = xdr_decode_fattr(p, fattr);
399 PRINTK("NFS reply create\n");
400 }
401 else
402 PRINTK("NFS reply create failed = %d\n", status);
403 nfs_rpc_free(p0);
404 return -nfs_stat_to_errno(status);
405 }
406
407 int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, const char *name)
408 {
409 int *p, *p0;
410 int status;
411
412 PRINTK("NFS call remove %s\n", name);
413 if (!(p0 = nfs_rpc_alloc()))
414 return -EIO;
415 p = nfs_rpc_header(p0, NFSPROC_REMOVE);
416 p = xdr_encode_fhandle(p, dir);
417 p = xdr_encode_string(p, name);
418 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
419 nfs_rpc_free(p0);
420 return status;
421 }
422 if (!(p = nfs_rpc_verify(p0)))
423 status = NFSERR_IO;
424 else if ((status = ntohl(*p++)) == NFS_OK) {
425 PRINTK("NFS reply remove\n");
426 }
427 else
428 PRINTK("NFS reply remove failed = %d\n", status);
429 nfs_rpc_free(p0);
430 return -nfs_stat_to_errno(status);
431 }
432
433 int nfs_proc_rename(struct nfs_server *server,
434 struct nfs_fh *old_dir, const char *old_name,
435 struct nfs_fh *new_dir, const char *new_name)
436 {
437 int *p, *p0;
438 int status;
439
440 PRINTK("NFS call rename %s -> %s\n", old_name, new_name);
441 if (!(p0 = nfs_rpc_alloc()))
442 return -EIO;
443 p = nfs_rpc_header(p0, NFSPROC_RENAME);
444 p = xdr_encode_fhandle(p, old_dir);
445 p = xdr_encode_string(p, old_name);
446 p = xdr_encode_fhandle(p, new_dir);
447 p = xdr_encode_string(p, new_name);
448 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
449 nfs_rpc_free(p0);
450 return status;
451 }
452 if (!(p = nfs_rpc_verify(p0)))
453 status = NFSERR_IO;
454 else if ((status = ntohl(*p++)) == NFS_OK) {
455 PRINTK("NFS reply rename\n");
456 }
457 else
458 PRINTK("NFS reply rename failed = %d\n", status);
459 nfs_rpc_free(p0);
460 return -nfs_stat_to_errno(status);
461 }
462
463 int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle,
464 struct nfs_fh *dir, const char *name)
465 {
466 int *p, *p0;
467 int status;
468
469 PRINTK("NFS call link %s\n", name);
470 if (!(p0 = nfs_rpc_alloc()))
471 return -EIO;
472 p = nfs_rpc_header(p0, NFSPROC_LINK);
473 p = xdr_encode_fhandle(p, fhandle);
474 p = xdr_encode_fhandle(p, dir);
475 p = xdr_encode_string(p, name);
476 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
477 nfs_rpc_free(p0);
478 return status;
479 }
480 if (!(p = nfs_rpc_verify(p0)))
481 status = NFSERR_IO;
482 else if ((status = ntohl(*p++)) == NFS_OK) {
483 PRINTK("NFS reply link\n");
484 }
485 else
486 PRINTK("NFS reply link failed = %d\n", status);
487 nfs_rpc_free(p0);
488 return -nfs_stat_to_errno(status);
489 }
490
491 int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
492 const char *name, const char *path, struct nfs_sattr *sattr)
493 {
494 int *p, *p0;
495 int status;
496
497 PRINTK("NFS call symlink %s -> %s\n", name, path);
498 if (!(p0 = nfs_rpc_alloc()))
499 return -EIO;
500 p = nfs_rpc_header(p0, NFSPROC_SYMLINK);
501 p = xdr_encode_fhandle(p, dir);
502 p = xdr_encode_string(p, name);
503 p = xdr_encode_string(p, path);
504 p = xdr_encode_sattr(p, sattr);
505 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
506 nfs_rpc_free(p0);
507 return status;
508 }
509 if (!(p = nfs_rpc_verify(p0)))
510 status = NFSERR_IO;
511 else if ((status = ntohl(*p++)) == NFS_OK) {
512 PRINTK("NFS reply symlink\n");
513 }
514 else
515 PRINTK("NFS reply symlink failed = %d\n", status);
516 nfs_rpc_free(p0);
517 return -nfs_stat_to_errno(status);
518 }
519
520 int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
521 const char *name, struct nfs_sattr *sattr,
522 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
523 {
524 int *p, *p0;
525 int status;
526
527 PRINTK("NFS call mkdir %s\n", name);
528 if (!(p0 = nfs_rpc_alloc()))
529 return -EIO;
530 p = nfs_rpc_header(p0, NFSPROC_MKDIR);
531 p = xdr_encode_fhandle(p, dir);
532 p = xdr_encode_string(p, name);
533 p = xdr_encode_sattr(p, sattr);
534 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
535 nfs_rpc_free(p0);
536 return status;
537 }
538 if (!(p = nfs_rpc_verify(p0)))
539 status = NFSERR_IO;
540 else if ((status = ntohl(*p++)) == NFS_OK) {
541 p = xdr_decode_fhandle(p, fhandle);
542 p = xdr_decode_fattr(p, fattr);
543 PRINTK("NFS reply mkdir\n");
544 }
545 else
546 PRINTK("NFS reply mkdir failed = %d\n", status);
547 nfs_rpc_free(p0);
548 return -nfs_stat_to_errno(status);
549 }
550
551 int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir, const char *name)
552 {
553 int *p, *p0;
554 int status;
555
556 PRINTK("NFS call rmdir %s\n", name);
557 if (!(p0 = nfs_rpc_alloc()))
558 return -EIO;
559 p = nfs_rpc_header(p0, NFSPROC_RMDIR);
560 p = xdr_encode_fhandle(p, dir);
561 p = xdr_encode_string(p, name);
562 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
563 nfs_rpc_free(p0);
564 return status;
565 }
566 if (!(p = nfs_rpc_verify(p0)))
567 status = NFSERR_IO;
568 else if ((status = ntohl(*p++)) == NFS_OK) {
569 PRINTK("NFS reply rmdir\n");
570 }
571 else
572 PRINTK("NFS reply rmdir failed = %d\n", status);
573 nfs_rpc_free(p0);
574 return -nfs_stat_to_errno(status);
575 }
576
577 int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
578 int cookie, int count, struct nfs_entry *entry)
579 {
580 int *p, *p0;
581 int status;
582 int i = 0;
583 int size;
584 int eof;
585
586 PRINTK("NFS call readdir %d @ %d\n", count, cookie);
587 size = server->rsize;
588 if (!(p0 = nfs_rpc_alloc()))
589 return -EIO;
590 p = nfs_rpc_header(p0, NFSPROC_READDIR);
591 p = xdr_encode_fhandle(p, fhandle);
592 *p++ = htonl(cookie);
593 *p++ = htonl(size);
594 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
595 nfs_rpc_free(p0);
596 return status;
597 }
598 if (!(p = nfs_rpc_verify(p0)))
599 status = NFSERR_IO;
600 else if ((status = ntohl(*p++)) == NFS_OK) {
601 for (i = 0; i < count && *p++; i++) {
602 if (!(p = xdr_decode_entry(p, entry++)))
603 break;
604 }
605 if (!p) {
606 printk("nfs_proc_readdir: giant filename\n");
607 status = NFSERR_IO;
608 }
609 else {
610 eof = (i == count && !*p++ && *p++)
611 || (i < count && *p++);
612 if (eof && i)
613 entry[-1].eof = 1;
614 PRINTK("NFS reply readdir %d %s\n", i,
615 eof ? "eof" : "");
616 }
617 }
618 else
619 PRINTK("NFS reply readdir failed = %d\n", status);
620 nfs_rpc_free(p0);
621 return (status == NFS_OK) ? i : -nfs_stat_to_errno(status);
622 }
623
624 int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
625 struct nfs_fsinfo *res)
626 {
627 int *p, *p0;
628 int status;
629
630 PRINTK("NFS call statfs\n");
631 if (!(p0 = nfs_rpc_alloc()))
632 return -EIO;
633 p = nfs_rpc_header(p0, NFSPROC_STATFS);
634 p = xdr_encode_fhandle(p, fhandle);
635 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
636 nfs_rpc_free(p0);
637 return status;
638 }
639 if (!(p = nfs_rpc_verify(p0)))
640 status = NFSERR_IO;
641 else if ((status = ntohl(*p++)) == NFS_OK) {
642 p = xdr_decode_fsinfo(p, res);
643 PRINTK("NFS reply statfs\n");
644 }
645 else
646 PRINTK("NFS reply statfs failed = %d\n", status);
647 nfs_rpc_free(p0);
648 return -nfs_stat_to_errno(status);
649 }
650
651
652
653
654
655 static int *nfs_rpc_header(int *p, int procedure)
656 {
657 int *p1, *p2;
658 int i;
659 static int xid = 0;
660 unsigned char *sys = (unsigned char *) system_utsname.nodename;
661
662 if (xid == 0) {
663 xid = CURRENT_TIME;
664 xid ^= (sys[3]<<24) | (sys[2]<<16) | (sys[1]<<8) | sys[0];
665 }
666 *p++ = htonl(++xid);
667 *p++ = htonl(RPC_CALL);
668 *p++ = htonl(RPC_VERSION);
669 *p++ = htonl(NFS_PROGRAM);
670 *p++ = htonl(NFS_VERSION);
671 *p++ = htonl(procedure);
672 *p++ = htonl(RPC_AUTH_UNIX);
673 p1 = p++;
674 *p++ = htonl(CURRENT_TIME);
675 p = xdr_encode_string(p, (char *) sys);
676 *p++ = htonl(current->euid);
677 *p++ = htonl(current->egid);
678 p2 = p++;
679 for (i = 0; i < 16 && i < NGROUPS && current->groups[i] != NOGROUP; i++)
680 *p++ = htonl(current->groups[i]);
681 *p2 = htonl(i);
682 *p1 = htonl((p - (p1 + 1)) << 2);
683 *p++ = htonl(RPC_AUTH_NULL);
684 *p++ = htonl(0);
685 return p;
686 }
687
688 static int *nfs_rpc_verify(int *p)
689 {
690 unsigned int n;
691
692 p++;
693 if ((n = ntohl(*p++)) != RPC_REPLY) {
694 printk("nfs_rpc_verify: not an RPC reply: %d\n", n);
695 return NULL;
696 }
697 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
698 printk("nfs_rpc_verify: RPC call rejected: %d\n", n);
699 return NULL;
700 }
701 switch (n = ntohl(*p++)) {
702 case RPC_AUTH_NULL: case RPC_AUTH_UNIX: case RPC_AUTH_SHORT:
703 break;
704 default:
705 printk("nfs_rpc_verify: bad RPC authentication type: %d\n", n);
706 return NULL;
707 }
708 if ((n = ntohl(*p++)) > 400) {
709 printk("nfs_rpc_verify: giant auth size\n");
710 return NULL;
711 }
712 p += (n + 3) >> 2;
713 if ((n = ntohl(*p++)) != RPC_SUCCESS) {
714 printk("nfs_rpc_verify: RPC call failed: %d\n", n);
715 return NULL;
716 }
717 return p;
718 }
719
720
721
722
723
724
725 #ifndef EDQUOT
726 #define EDQUOT ENOSPC
727 #endif
728
729 static struct {
730 int stat;
731 int errno;
732 } nfs_errtbl[] = {
733 { NFS_OK, 0 },
734 { NFSERR_PERM, EPERM },
735 { NFSERR_NOENT, ENOENT },
736 { NFSERR_IO, EIO },
737 { NFSERR_NXIO, ENXIO },
738 { NFSERR_ACCES, EACCES },
739 { NFSERR_EXIST, EEXIST },
740 { NFSERR_NODEV, ENODEV },
741 { NFSERR_NOTDIR, ENOTDIR },
742 { NFSERR_ISDIR, EISDIR },
743 { NFSERR_INVAL, EINVAL },
744 { NFSERR_FBIG, EFBIG },
745 { NFSERR_NOSPC, ENOSPC },
746 { NFSERR_ROFS, EROFS },
747 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
748 { NFSERR_NOTEMPTY, ENOTEMPTY },
749 { NFSERR_DQUOT, EDQUOT },
750 { NFSERR_STALE, ESTALE },
751 #ifdef EWFLUSH
752 { NFSERR_WFLUSH, EWFLUSH },
753 #endif
754 { -1, EIO }
755 };
756
757 static int nfs_stat_to_errno(int stat)
758 {
759 int i;
760
761 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
762 if (nfs_errtbl[i].stat == stat)
763 return nfs_errtbl[i].errno;
764 }
765 printk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
766 return nfs_errtbl[i].errno;
767 }
768