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