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_read_request
- nfs_proc_read_reply
- 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 1
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
420 nfs_proc_read_request(struct rpc_ioreq *req, struct nfs_server *server,
421 struct nfs_fh *fh, unsigned long offset,
422 unsigned long count, __u32 *buf)
423 {
424 __u32 *p, *p0;
425 int len;
426
427 PRINTK("NFS reqst read %ld @ %ld\n", count, offset);
428 if (!(p0 = nfs_rpc_alloc(NFS_SLACK_SPACE)))
429 return -EIO;
430
431 p = nfs_rpc_header(p0, NFSPROC_READ, 0);
432 p = xdr_encode_fhandle(p, fh);
433 *p++ = htonl(offset);
434 *p++ = htonl(count);
435 *p++ = htonl(count);
436 req->rq_svec[0].iov_base = p0;
437 req->rq_svec[0].iov_len = (p - p0) << 2;
438 req->rq_slen = (p - p0) << 2;
439 req->rq_snr = 1;
440
441 len = (6 + 1 + 17 + 1);
442 req->rq_rvec[0].iov_base = p0;
443 req->rq_rvec[0].iov_len = len << 2;
444 req->rq_rvec[1].iov_base = buf;
445 req->rq_rvec[1].iov_len = count;
446 req->rq_rvec[2].iov_base = p0 + len;
447 req->rq_rvec[2].iov_len = (NFS_SLACK_SPACE - len) << 2;
448 req->rq_rlen = count + NFS_SLACK_SPACE;
449 req->rq_rnr = 3;
450
451 req->rq_addr = &server->toaddr;
452 req->rq_alen = sizeof(server->toaddr);
453
454 return 0;
455 }
456
457 int
458 nfs_proc_read_reply(struct rpc_ioreq *req)
459 {
460 struct nfs_fattr fattr;
461 int status;
462 __u32 *p0, *p;
463 int count;
464
465 p0 = (__u32 *) req->rq_rvec[0].iov_base;
466
467 if (!(p = nfs_rpc_verify(p0))) {
468 status = -errno_NFSERR_IO;
469 } else if ((status = ntohl(*p++)) == NFS_OK) {
470 p = xdr_decode_fattr(p, &fattr);
471 count = ntohl(*p++);
472 if (p != req->rq_rvec[2].iov_base) {
473
474
475
476
477 status = -errno_NFSERR_IO;
478 PRINTK("NFS reply read odd header size %d\n",
479 (p - p0) << 2);
480 } else {
481 status = count;
482 PRINTK("NFS reply read %d\n", count);
483 }
484 }
485 else {
486 PRINTK("NFS reply read failed = %d\n", status);
487 status = -nfs_stat_to_errno(status);
488 }
489 nfs_rpc_free(p0);
490 return status;
491 }
492
493 int nfs_proc_write(struct inode * inode, int offset,
494 int count, const char *data, struct nfs_fattr *fattr)
495 {
496 int *p, *p0;
497 int status;
498 int ruid = 0;
499 void * kdata;
500 struct nfs_server * server = NFS_SERVER(inode);
501 struct nfs_fh *fhandle = NFS_FH(inode);
502
503 PRINTK("NFS call write %d @ %d\n", count, offset);
504 if (!(p0 = nfs_rpc_alloc(server->wsize)))
505 return -EIO;
506 retry:
507 p = nfs_rpc_header(p0, NFSPROC_WRITE, ruid);
508 p = xdr_encode_fhandle(p, fhandle);
509 *p++ = htonl(offset);
510 *p++ = htonl(offset);
511 *p++ = htonl(count);
512 kdata = (void *) (p+1);
513 p = xdr_encode_data(p, data, count);
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 update_vm_cache(inode, offset, kdata, count);
522 p = xdr_decode_fattr(p, fattr);
523 PRINTK("NFS reply write\n");
524
525 }
526 else {
527 if (!ruid && current->fsuid == 0 && current->uid != 0) {
528 ruid = 1;
529 goto retry;
530 }
531 PRINTK("NFS reply write failed = %d\n", status);
532 status = -nfs_stat_to_errno(status);
533 }
534 nfs_rpc_free(p0);
535 return status;
536 }
537
538 int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
539 const char *name, struct nfs_sattr *sattr,
540 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
541 {
542 int *p, *p0;
543 int status;
544 int ruid = 0;
545
546 PRINTK("NFS call create %s\n", name);
547 if (!(p0 = nfs_rpc_alloc(server->wsize)))
548 return -EIO;
549 retry:
550 p = nfs_rpc_header(p0, NFSPROC_CREATE, ruid);
551 p = xdr_encode_fhandle(p, dir);
552 p = xdr_encode_string(p, name);
553 p = xdr_encode_sattr(p, sattr);
554 if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
555 nfs_rpc_free(p0);
556 return status;
557 }
558 if (!(p = nfs_rpc_verify(p0)))
559 status = -errno_NFSERR_IO;
560 else if ((status = ntohl(*p++)) == NFS_OK) {
561 p = xdr_decode_fhandle(p, fhandle);
562 p = xdr_decode_fattr(p, fattr);
563 PRINTK("NFS reply create\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 create 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_remove(struct nfs_server *server, struct nfs_fh *dir, const char *name)
579 {
580 int *p, *p0;
581 int status;
582 int ruid = 0;
583
584 PRINTK("NFS call remove %s\n", name);
585 if (!(p0 = nfs_rpc_alloc(server->wsize)))
586 return -EIO;
587 retry:
588 p = nfs_rpc_header(p0, NFSPROC_REMOVE, ruid);
589 p = xdr_encode_fhandle(p, dir);
590 p = xdr_encode_string(p, name);
591 if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
592 nfs_rpc_free(p0);
593 return status;
594 }
595 if (!(p = nfs_rpc_verify(p0)))
596 status = -errno_NFSERR_IO;
597 else if ((status = ntohl(*p++)) == NFS_OK) {
598 PRINTK("NFS reply remove\n");
599
600 }
601 else {
602 if (!ruid && current->fsuid == 0 && current->uid != 0) {
603 ruid = 1;
604 goto retry;
605 }
606 PRINTK("NFS reply remove failed = %d\n", status);
607 status = -nfs_stat_to_errno(status);
608 }
609 nfs_rpc_free(p0);
610 return status;
611 }
612
613 int nfs_proc_rename(struct nfs_server *server,
614 struct nfs_fh *old_dir, const char *old_name,
615 struct nfs_fh *new_dir, const char *new_name)
616 {
617 int *p, *p0;
618 int status;
619 int ruid = 0;
620
621 PRINTK("NFS call rename %s -> %s\n", old_name, new_name);
622 if (!(p0 = nfs_rpc_alloc(server->wsize)))
623 return -EIO;
624 retry:
625 p = nfs_rpc_header(p0, NFSPROC_RENAME, ruid);
626 p = xdr_encode_fhandle(p, old_dir);
627 p = xdr_encode_string(p, old_name);
628 p = xdr_encode_fhandle(p, new_dir);
629 p = xdr_encode_string(p, new_name);
630 if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
631 nfs_rpc_free(p0);
632 return status;
633 }
634 if (!(p = nfs_rpc_verify(p0)))
635 status = -errno_NFSERR_IO;
636 else if ((status = ntohl(*p++)) == NFS_OK) {
637 PRINTK("NFS reply rename\n");
638
639 }
640 else {
641 if (!ruid && current->fsuid == 0 && current->uid != 0) {
642 ruid = 1;
643 goto retry;
644 }
645 PRINTK("NFS reply rename failed = %d\n", status);
646 status = -nfs_stat_to_errno(status);
647 }
648 nfs_rpc_free(p0);
649 return status;
650 }
651
652 int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle,
653 struct nfs_fh *dir, const char *name)
654 {
655 int *p, *p0;
656 int status;
657 int ruid = 0;
658
659 PRINTK("NFS call link %s\n", name);
660 if (!(p0 = nfs_rpc_alloc(server->wsize)))
661 return -EIO;
662 retry:
663 p = nfs_rpc_header(p0, NFSPROC_LINK, ruid);
664 p = xdr_encode_fhandle(p, fhandle);
665 p = xdr_encode_fhandle(p, dir);
666 p = xdr_encode_string(p, name);
667 if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
668 nfs_rpc_free(p0);
669 return status;
670 }
671 if (!(p = nfs_rpc_verify(p0)))
672 status = -errno_NFSERR_IO;
673 else if ((status = ntohl(*p++)) == NFS_OK) {
674 PRINTK("NFS reply link\n");
675
676 }
677 else {
678 if (!ruid && current->fsuid == 0 && current->uid != 0) {
679 ruid = 1;
680 goto retry;
681 }
682 PRINTK("NFS reply link failed = %d\n", status);
683 status = -nfs_stat_to_errno(status);
684 }
685 nfs_rpc_free(p0);
686 return status;
687 }
688
689 int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
690 const char *name, const char *path, struct nfs_sattr *sattr)
691 {
692 int *p, *p0;
693 int status;
694 int ruid = 0;
695
696 PRINTK("NFS call symlink %s -> %s\n", name, path);
697 if (!(p0 = nfs_rpc_alloc(server->wsize)))
698 return -EIO;
699 retry:
700 p = nfs_rpc_header(p0, NFSPROC_SYMLINK, ruid);
701 p = xdr_encode_fhandle(p, dir);
702 p = xdr_encode_string(p, name);
703 p = xdr_encode_string(p, path);
704 p = xdr_encode_sattr(p, sattr);
705 if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
706 nfs_rpc_free(p0);
707 return status;
708 }
709 if (!(p = nfs_rpc_verify(p0)))
710 status = -errno_NFSERR_IO;
711 else if ((status = ntohl(*p++)) == NFS_OK) {
712 PRINTK("NFS reply symlink\n");
713
714 }
715 else {
716 if (!ruid && current->fsuid == 0 && current->uid != 0) {
717 ruid = 1;
718 goto retry;
719 }
720 PRINTK("NFS reply symlink failed = %d\n", status);
721 status = -nfs_stat_to_errno(status);
722 }
723 nfs_rpc_free(p0);
724 return status;
725 }
726
727 int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
728 const char *name, struct nfs_sattr *sattr,
729 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
730 {
731 int *p, *p0;
732 int status;
733 int ruid = 0;
734
735 PRINTK("NFS call mkdir %s\n", name);
736 if (!(p0 = nfs_rpc_alloc(server->wsize)))
737 return -EIO;
738 retry:
739 p = nfs_rpc_header(p0, NFSPROC_MKDIR, ruid);
740 p = xdr_encode_fhandle(p, dir);
741 p = xdr_encode_string(p, name);
742 p = xdr_encode_sattr(p, sattr);
743 if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
744 nfs_rpc_free(p0);
745 return status;
746 }
747 if (!(p = nfs_rpc_verify(p0)))
748 status = -errno_NFSERR_IO;
749 else if ((status = ntohl(*p++)) == NFS_OK) {
750 p = xdr_decode_fhandle(p, fhandle);
751 p = xdr_decode_fattr(p, fattr);
752 PRINTK("NFS reply mkdir\n");
753
754 }
755 else {
756 if (!ruid && current->fsuid == 0 && current->uid != 0) {
757 ruid = 1;
758 goto retry;
759 }
760 PRINTK("NFS reply mkdir failed = %d\n", status);
761 status = -nfs_stat_to_errno(status);
762 }
763 nfs_rpc_free(p0);
764 return status;
765 }
766
767 int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir, const char *name)
768 {
769 int *p, *p0;
770 int status;
771 int ruid = 0;
772
773 PRINTK("NFS call rmdir %s\n", name);
774 if (!(p0 = nfs_rpc_alloc(server->wsize)))
775 return -EIO;
776 retry:
777 p = nfs_rpc_header(p0, NFSPROC_RMDIR, ruid);
778 p = xdr_encode_fhandle(p, dir);
779 p = xdr_encode_string(p, name);
780 if ((status = nfs_rpc_call(server, p0, p, server->wsize)) < 0) {
781 nfs_rpc_free(p0);
782 return status;
783 }
784 if (!(p = nfs_rpc_verify(p0)))
785 status = -errno_NFSERR_IO;
786 else if ((status = ntohl(*p++)) == NFS_OK) {
787 PRINTK("NFS reply rmdir\n");
788
789 }
790 else {
791 if (!ruid && current->fsuid == 0 && current->uid != 0) {
792 ruid = 1;
793 goto retry;
794 }
795 PRINTK("NFS reply rmdir failed = %d\n", status);
796 status = -nfs_stat_to_errno(status);
797 }
798 nfs_rpc_free(p0);
799 return status;
800 }
801
802 int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
803 int cookie, int count, struct nfs_entry *entry)
804 {
805 int *p, *p0;
806 int status;
807 int ruid = 0;
808 int i;
809 int size;
810 int eof;
811
812 PRINTK("NFS call readdir %d @ %d\n", count, cookie);
813 size = server->rsize;
814 if (!(p0 = nfs_rpc_alloc(server->rsize)))
815 return -EIO;
816 retry:
817 p = nfs_rpc_header(p0, NFSPROC_READDIR, ruid);
818 p = xdr_encode_fhandle(p, fhandle);
819 *p++ = htonl(cookie);
820 *p++ = htonl(size);
821 if ((status = nfs_rpc_call(server, p0, p, server->rsize)) < 0) {
822 nfs_rpc_free(p0);
823 return status;
824 }
825 if (!(p = nfs_rpc_verify(p0)))
826 status = -errno_NFSERR_IO;
827 else if ((status = ntohl(*p++)) == NFS_OK) {
828 for (i = 0; i < count && *p++; i++) {
829 if (!(p = xdr_decode_entry(p, entry++)))
830 break;
831 }
832 if (!p) {
833 printk("nfs_proc_readdir: giant filename\n");
834 status = -errno_NFSERR_IO;
835 }
836 else {
837 eof = (i == count && !*p++ && *p++)
838 || (i < count && *p++);
839 if (eof && i)
840 entry[-1].eof = 1;
841 PRINTK("NFS reply readdir %d %s\n", i,
842 eof ? "eof" : "");
843 status = i;
844 }
845 }
846 else {
847 if (!ruid && current->fsuid == 0 && current->uid != 0) {
848 ruid = 1;
849 goto retry;
850 }
851 PRINTK("NFS reply readdir failed = %d\n", status);
852 status = -nfs_stat_to_errno(status);
853 }
854 nfs_rpc_free(p0);
855 return status;
856 }
857
858 int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
859 struct nfs_fsinfo *res)
860 {
861 int *p, *p0;
862 int status;
863 int ruid = 0;
864
865 PRINTK("NFS call statfs\n");
866 if (!(p0 = nfs_rpc_alloc(server->rsize)))
867 return -EIO;
868 retry:
869 p = nfs_rpc_header(p0, NFSPROC_STATFS, ruid);
870 p = xdr_encode_fhandle(p, fhandle);
871 if ((status = nfs_rpc_call(server, p0, p, server->rsize)) < 0) {
872 nfs_rpc_free(p0);
873 return status;
874 }
875 if (!(p = nfs_rpc_verify(p0)))
876 status = -errno_NFSERR_IO;
877 else if ((status = ntohl(*p++)) == NFS_OK) {
878 p = xdr_decode_fsinfo(p, res);
879 PRINTK("NFS reply statfs\n");
880
881 }
882 else {
883 if (!ruid && current->fsuid == 0 && current->uid != 0) {
884 ruid = 1;
885 goto retry;
886 }
887 PRINTK("NFS reply statfs failed = %d\n", status);
888 status = -nfs_stat_to_errno(status);
889 }
890 nfs_rpc_free(p0);
891 return status;
892 }
893
894
895
896
897
898 int *rpc_header(int *p, int procedure, int program, int version,
899 int uid, int gid, int *groups)
900 {
901 int *p1, *p2;
902 int i;
903 static int xid = 0;
904 unsigned char *sys = (unsigned char *) system_utsname.nodename;
905
906 if (xid == 0) {
907 xid = CURRENT_TIME;
908 xid ^= (sys[3]<<24) | (sys[2]<<16) | (sys[1]<<8) | sys[0];
909 }
910 *p++ = htonl(++xid);
911 *p++ = htonl(RPC_CALL);
912 *p++ = htonl(RPC_VERSION);
913 *p++ = htonl(program);
914 *p++ = htonl(version);
915 *p++ = htonl(procedure);
916 *p++ = htonl(RPC_AUTH_UNIX);
917 p1 = p++;
918 *p++ = htonl(CURRENT_TIME);
919 p = xdr_encode_string(p, (char *) sys);
920 *p++ = htonl(uid);
921 *p++ = htonl(gid);
922 p2 = p++;
923 for (i = 0; i < 16 && i < NGROUPS && groups[i] != NOGROUP; i++)
924 *p++ = htonl(groups[i]);
925 *p2 = htonl(i);
926 *p1 = htonl((p - (p1 + 1)) << 2);
927 *p++ = htonl(RPC_AUTH_NULL);
928 *p++ = htonl(0);
929 return p;
930 }
931
932
933 static int *nfs_rpc_header(int *p, int procedure, int ruid)
934 {
935 return rpc_header(p, procedure, NFS_PROGRAM, NFS_VERSION,
936 (ruid ? current->uid : current->fsuid),
937 current->egid, current->groups);
938 }
939
940
941 int *rpc_verify(int *p)
942 {
943 unsigned int n;
944
945 p++;
946 if ((n = ntohl(*p++)) != RPC_REPLY) {
947 printk("nfs_rpc_verify: not an RPC reply: %x\n", n);
948 return NULL;
949 }
950 if ((n = ntohl(*p++)) != RPC_MSG_ACCEPTED) {
951 printk("nfs_rpc_verify: RPC call rejected: %d\n", n);
952 return NULL;
953 }
954 switch (n = ntohl(*p++)) {
955 case RPC_AUTH_NULL: case RPC_AUTH_UNIX: case RPC_AUTH_SHORT:
956 break;
957 default:
958 printk("nfs_rpc_verify: bad RPC authentication type: %d\n", n);
959 return NULL;
960 }
961 if ((n = ntohl(*p++)) > 400) {
962 printk("nfs_rpc_verify: giant auth size\n");
963 return NULL;
964 }
965 p += QUADLEN(n);
966 if ((n = ntohl(*p++)) != RPC_SUCCESS) {
967 printk("nfs_rpc_verify: RPC call failed: %d\n", n);
968 return NULL;
969 }
970 return p;
971 }
972
973
974 static int *nfs_rpc_verify(int *p)
975 {
976 return rpc_verify(p);
977 }
978
979
980
981
982
983
984
985 static struct {
986 int stat;
987 int errno;
988 } nfs_errtbl[] = {
989 { NFS_OK, 0 },
990 { NFSERR_PERM, EPERM },
991 { NFSERR_NOENT, ENOENT },
992 { NFSERR_IO, errno_NFSERR_IO },
993 { NFSERR_NXIO, ENXIO },
994 { NFSERR_EAGAIN, EAGAIN },
995 { NFSERR_ACCES, EACCES },
996 { NFSERR_EXIST, EEXIST },
997 { NFSERR_NODEV, ENODEV },
998 { NFSERR_NOTDIR, ENOTDIR },
999 { NFSERR_ISDIR, EISDIR },
1000 { NFSERR_INVAL, EINVAL },
1001 { NFSERR_FBIG, EFBIG },
1002 { NFSERR_NOSPC, ENOSPC },
1003 { NFSERR_ROFS, EROFS },
1004 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
1005 { NFSERR_NOTEMPTY, ENOTEMPTY },
1006 { NFSERR_DQUOT, EDQUOT },
1007 { NFSERR_STALE, ESTALE },
1008 #ifdef EWFLUSH
1009 { NFSERR_WFLUSH, EWFLUSH },
1010 #endif
1011 { -1, EIO }
1012 };
1013
1014 static int nfs_stat_to_errno(int stat)
1015 {
1016 int i;
1017
1018 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
1019 if (nfs_errtbl[i].stat == stat)
1020 return nfs_errtbl[i].errno;
1021 }
1022 printk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
1023 return nfs_errtbl[i].errno;
1024 }
1025