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