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