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