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