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