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