This source file includes following definitions.
- 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 #define NFS_PROC_DEBUG
16
17 #include <linux/param.h>
18 #include <linux/sched.h>
19 #include <linux/mm.h>
20 #include <linux/nfs_fs.h>
21 #include <linux/utsname.h>
22 #include <linux/errno.h>
23 #include <linux/string.h>
24
25 #include <netinet/in.h>
26
27 #ifdef NFS_PROC_DEBUG
28 static int proc_debug = 0;
29 #define PRINTK if (proc_debug) printk
30 #else
31 #define PRINTK (void)
32 #endif
33
34 static int *nfs_rpc_header(int *p, int procedure);
35 static int *nfs_rpc_verify(int *p);
36 static int nfs_stat_to_errno(int stat);
37
38
39
40
41
42
43 static inline int *xdr_encode_fhandle(int *p, struct nfs_fh *fhandle)
44 {
45 *((struct nfs_fh *) p) = *fhandle;
46 p += (sizeof (*fhandle) + 3) >> 2;
47 return p;
48 }
49
50 static inline int *xdr_decode_fhandle(int *p, struct nfs_fh *fhandle)
51 {
52 *fhandle = *((struct nfs_fh *) p);
53 p += (sizeof (*fhandle) + 3) >> 2;
54 return p;
55 }
56
57 static inline int *xdr_encode_string(int *p, char *string)
58 {
59 int len, quadlen;
60
61 len = strlen(string);
62 quadlen = (len + 3) >> 2;
63 *p++ = htonl(len);
64 memcpy((char *) p, string, len);
65 memset(((char *) p) + len, '\0', (quadlen << 2) - len);
66 p += quadlen;
67 return p;
68 }
69
70 static inline int *xdr_decode_string(int *p, char *string)
71 {
72 int len;
73
74 len = ntohl(*p++);
75 memcpy(string, (char *) p, len);
76 string[len] = '\0';
77 p += (len + 3) >> 2;
78 return p;
79 }
80
81 static inline int *xdr_encode_data(int *p, char *data, int len)
82 {
83 int quadlen;
84
85 quadlen = (len + 3) >> 2;
86 *p++ = htonl(len);
87 memcpy((char *) p, data, len);
88 memset(((char *) p) + len, '\0', (quadlen << 2) - len);
89 p += quadlen;
90 return p;
91 }
92
93 static inline int *xdr_decode_data(int *p, char *data, int *lenp)
94 {
95 int len;
96
97 len = *lenp = ntohl(*p++);
98 memcpy(data, (char *) p, len);
99 data[len] = '\0';
100 p += (len + 3) >> 2;
101 return p;
102 }
103
104 static int *xdr_decode_fattr(int *p, struct nfs_fattr *fattr)
105 {
106 fattr->type = ntohl(*p++);
107 fattr->mode = ntohl(*p++);
108 fattr->nlink = ntohl(*p++);
109 fattr->uid = ntohl(*p++);
110 fattr->gid = ntohl(*p++);
111 fattr->size = ntohl(*p++);
112 fattr->blocksize = ntohl(*p++);
113 fattr->rdev = ntohl(*p++);
114 fattr->blocks = ntohl(*p++);
115 fattr->fsid = ntohl(*p++);
116 fattr->fileid = ntohl(*p++);
117 fattr->atime.seconds = ntohl(*p++);
118 fattr->atime.useconds = ntohl(*p++);
119 fattr->mtime.seconds = ntohl(*p++);
120 fattr->mtime.useconds = ntohl(*p++);
121 fattr->ctime.seconds = ntohl(*p++);
122 fattr->ctime.useconds = ntohl(*p++);
123 return p;
124 }
125
126 static int *xdr_encode_sattr(int *p, struct nfs_sattr *sattr)
127 {
128 *p++ = htonl(sattr->mode);
129 *p++ = htonl(sattr->uid);
130 *p++ = htonl(sattr->gid);
131 *p++ = htonl(sattr->size);
132 *p++ = htonl(sattr->atime.seconds);
133 *p++ = htonl(sattr->atime.useconds);
134 *p++ = htonl(sattr->mtime.seconds);
135 *p++ = htonl(sattr->mtime.useconds);
136 return p;
137 }
138
139 static int *xdr_decode_entry(int *p, struct nfs_entry *entry)
140 {
141 entry->fileid = ntohl(*p++);
142 p = xdr_decode_string(p, entry->name);
143 entry->cookie = ntohl(*p++);
144 entry->eof = 0;
145 return p;
146 }
147
148 static int *xdr_decode_fsinfo(int *p, struct nfs_fsinfo *res)
149 {
150 res->tsize = ntohl(*p++);
151 res->bsize = ntohl(*p++);
152 res->blocks = ntohl(*p++);
153 res->bfree = ntohl(*p++);
154 res->bavail = ntohl(*p++);
155 return p;
156 }
157
158 int nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
159 struct nfs_fattr *fattr)
160 {
161 int *p, *p0;
162 int status;
163
164 PRINTK("NFS call getattr\n");
165 p = p0 = (int *) get_free_page(GFP_KERNEL);
166 p = nfs_rpc_header(p, NFSPROC_GETATTR);
167 p = xdr_encode_fhandle(p, fhandle);
168 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
169 free_page((long) p0);
170 return status;
171 }
172 if (!(p = nfs_rpc_verify(p0)))
173 status = NFSERR_IO;
174 else if ((status = ntohl(*p++)) == NFS_OK) {
175 p = xdr_decode_fattr(p, fattr);
176 PRINTK("NFS reply getattr\n");
177 }
178 free_page((long) p0);
179 return -nfs_stat_to_errno(status);
180 }
181
182 int nfs_proc_setattr(struct nfs_server *server, struct nfs_fh *fhandle,
183 struct nfs_sattr *sattr, struct nfs_fattr *fattr)
184 {
185 int *p, *p0;
186 int status;
187
188 PRINTK("NFS call setattr\n");
189 p = p0 = (int *) get_free_page(GFP_KERNEL);
190 p = nfs_rpc_header(p, NFSPROC_SETATTR);
191 p = xdr_encode_fhandle(p, fhandle);
192 p = xdr_encode_sattr(p, sattr);
193 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
194 free_page((long) p0);
195 return status;
196 }
197 if (!(p = nfs_rpc_verify(p0)))
198 status = NFSERR_IO;
199 else if ((status = ntohl(*p++)) == NFS_OK) {
200 p = xdr_decode_fattr(p, fattr);
201 PRINTK("NFS reply setattr\n");
202 }
203 free_page((long) p0);
204 return -nfs_stat_to_errno(status);
205 }
206
207 int nfs_proc_lookup(struct nfs_server *server, struct nfs_fh *dir, char *name,
208 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
209 {
210 int *p, *p0;
211 int status;
212
213 PRINTK("NFS call lookup %s\n", name);
214 #ifdef NFS_PROC_DEBUG
215 if (!strcmp(name, "xyzzy"))
216 proc_debug = 1 - proc_debug;
217 #endif
218 p = p0 = (int *) get_free_page(GFP_KERNEL);
219 p = nfs_rpc_header(p, NFSPROC_LOOKUP);
220 p = xdr_encode_fhandle(p, dir);
221 p = xdr_encode_string(p, name);
222 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
223 free_page((long) p0);
224 return status;
225 }
226 if (!(p = nfs_rpc_verify(p0)))
227 status = NFSERR_IO;
228 else if ((status = ntohl(*p++)) == NFS_OK) {
229 p = xdr_decode_fhandle(p, fhandle);
230 p = xdr_decode_fattr(p, fattr);
231 PRINTK("NFS reply lookup\n");
232 }
233 free_page((long) p0);
234 return -nfs_stat_to_errno(status);
235 }
236
237 int nfs_proc_readlink(struct nfs_server *server, struct nfs_fh *fhandle,
238 char *res)
239 {
240 int *p, *p0;
241 int status;
242
243 PRINTK("NFS call readlink\n");
244 p = p0 = (int *) get_free_page(GFP_KERNEL);
245 p = nfs_rpc_header(p, NFSPROC_READLINK);
246 p = xdr_encode_fhandle(p, fhandle);
247 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
248 free_page((long) p0);
249 return status;
250 }
251 if (!(p = nfs_rpc_verify(p0)))
252 status = NFSERR_IO;
253 else if ((status = ntohl(*p++)) == NFS_OK) {
254 p = xdr_decode_string(p, res);
255 PRINTK("NFS reply readlink %s\n", res);
256 }
257 free_page((long) p0);
258 return -nfs_stat_to_errno(status);
259 }
260
261 int nfs_proc_read(struct nfs_server *server, struct nfs_fh *fhandle,
262 int offset, int count, char *data, struct nfs_fattr *fattr)
263 {
264 int *p, *p0;
265 int status;
266 int len = 0;
267
268 PRINTK("NFS call read %d @ %d\n", count, offset);
269 p = p0 = (int *) get_free_page(GFP_KERNEL);
270 p = nfs_rpc_header(p, NFSPROC_READ);
271 p = xdr_encode_fhandle(p, fhandle);
272 *p++ = htonl(offset);
273 *p++ = htonl(count);
274 *p++ = htonl(count);
275 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
276 free_page((long) p0);
277 return status;
278 }
279 if (!(p = nfs_rpc_verify(p0)))
280 status = NFSERR_IO;
281 else if ((status = ntohl(*p++)) == NFS_OK) {
282 p = xdr_decode_fattr(p, fattr);
283 p = xdr_decode_data(p, data, &len);
284 PRINTK("NFS reply read %d\n", len);
285 }
286 free_page((long) p0);
287 return (status == NFS_OK) ? len : -nfs_stat_to_errno(status);
288 }
289
290 int nfs_proc_write(struct nfs_server *server, struct nfs_fh *fhandle,
291 int offset, int count, char *data, struct nfs_fattr *fattr)
292 {
293 int *p, *p0;
294 int status;
295
296 PRINTK("NFS call write %d @ %d\n", count, offset);
297 p = p0 = (int *) get_free_page(GFP_KERNEL);
298 p = nfs_rpc_header(p, NFSPROC_WRITE);
299 p = xdr_encode_fhandle(p, fhandle);
300 *p++ = htonl(offset);
301 *p++ = htonl(offset);
302 *p++ = htonl(count);
303 p = xdr_encode_data(p, data, count);
304 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
305 free_page((long) p0);
306 return status;
307 }
308 if (!(p = nfs_rpc_verify(p0)))
309 status = NFSERR_IO;
310 else if ((status = ntohl(*p++)) == NFS_OK) {
311 p = xdr_decode_fattr(p, fattr);
312 PRINTK("NFS reply write\n");
313 }
314 free_page((long) p0);
315 return -nfs_stat_to_errno(status);
316 }
317
318 int nfs_proc_create(struct nfs_server *server, struct nfs_fh *dir,
319 char *name, struct nfs_sattr *sattr,
320 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
321 {
322 int *p, *p0;
323 int status;
324
325 PRINTK("NFS call create %s\n", name);
326 p = p0 = (int *) get_free_page(GFP_KERNEL);
327 p = nfs_rpc_header(p, NFSPROC_CREATE);
328 p = xdr_encode_fhandle(p, dir);
329 p = xdr_encode_string(p, name);
330 p = xdr_encode_sattr(p, sattr);
331 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
332 free_page((long) p0);
333 return status;
334 }
335 if (!(p = nfs_rpc_verify(p0)))
336 status = NFSERR_IO;
337 else if ((status = ntohl(*p++)) == NFS_OK) {
338 p = xdr_decode_fhandle(p, fhandle);
339 p = xdr_decode_fattr(p, fattr);
340 PRINTK("NFS reply create\n");
341 }
342 free_page((long) p0);
343 return -nfs_stat_to_errno(status);
344 }
345
346 int nfs_proc_remove(struct nfs_server *server, struct nfs_fh *dir, char *name)
347 {
348 int *p, *p0;
349 int status;
350
351 PRINTK("NFS call remove %s\n", name);
352 p = p0 = (int *) get_free_page(GFP_KERNEL);
353 p = nfs_rpc_header(p, NFSPROC_REMOVE);
354 p = xdr_encode_fhandle(p, dir);
355 p = xdr_encode_string(p, name);
356 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
357 free_page((long) p0);
358 return status;
359 }
360 if (!(p = nfs_rpc_verify(p0)))
361 status = NFSERR_IO;
362 else if ((status = ntohl(*p++)) == NFS_OK) {
363 PRINTK("NFS reply remove\n");
364 }
365 free_page((long) p0);
366 return -nfs_stat_to_errno(status);
367 }
368
369 int nfs_proc_rename(struct nfs_server *server,
370 struct nfs_fh *old_dir, char *old_name,
371 struct nfs_fh *new_dir, char *new_name)
372 {
373 int *p, *p0;
374 int status;
375
376 PRINTK("NFS call rename %s -> %s\n", old_name, new_name);
377 p = p0 = (int *) get_free_page(GFP_KERNEL);
378 p = nfs_rpc_header(p, NFSPROC_RENAME);
379 p = xdr_encode_fhandle(p, old_dir);
380 p = xdr_encode_string(p, old_name);
381 p = xdr_encode_fhandle(p, new_dir);
382 p = xdr_encode_string(p, new_name);
383 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
384 free_page((long) p0);
385 return status;
386 }
387 if (!(p = nfs_rpc_verify(p0)))
388 status = NFSERR_IO;
389 else if ((status = ntohl(*p++)) == NFS_OK) {
390 PRINTK("NFS reply rename\n");
391 }
392 free_page((long) p0);
393 return -nfs_stat_to_errno(status);
394 }
395
396 int nfs_proc_link(struct nfs_server *server, struct nfs_fh *fhandle,
397 struct nfs_fh *dir, char *name)
398 {
399 int *p, *p0;
400 int status;
401
402 PRINTK("NFS call link %s\n", name);
403 p = p0 = (int *) get_free_page(GFP_KERNEL);
404 p = nfs_rpc_header(p, NFSPROC_LINK);
405 p = xdr_encode_fhandle(p, fhandle);
406 p = xdr_encode_fhandle(p, dir);
407 p = xdr_encode_string(p, name);
408 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
409 free_page((long) p0);
410 return status;
411 }
412 if (!(p = nfs_rpc_verify(p0)))
413 status = NFSERR_IO;
414 else if ((status = ntohl(*p++)) == NFS_OK) {
415 PRINTK("NFS reply link\n");
416 }
417 free_page((long) p0);
418 return -nfs_stat_to_errno(status);
419 }
420
421 int nfs_proc_symlink(struct nfs_server *server, struct nfs_fh *dir,
422 char *name, char *path, struct nfs_sattr *sattr)
423 {
424 int *p, *p0;
425 int status;
426
427 PRINTK("NFS call symlink %s -> %s\n", name, path);
428 p = p0 = (int *) get_free_page(GFP_KERNEL);
429 p = nfs_rpc_header(p, NFSPROC_SYMLINK);
430 p = xdr_encode_fhandle(p, dir);
431 p = xdr_encode_string(p, name);
432 p = xdr_encode_string(p, path);
433 p = xdr_encode_sattr(p, sattr);
434 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
435 free_page((long) 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 PRINTK("NFS reply symlink\n");
442 }
443 free_page((long) p0);
444 return -nfs_stat_to_errno(status);
445 }
446
447 int nfs_proc_mkdir(struct nfs_server *server, struct nfs_fh *dir,
448 char *name, struct nfs_sattr *sattr,
449 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
450 {
451 int *p, *p0;
452 int status;
453
454 PRINTK("NFS call mkdir %s\n", name);
455 p = p0 = (int *) get_free_page(GFP_KERNEL);
456 p = nfs_rpc_header(p, NFSPROC_MKDIR);
457 p = xdr_encode_fhandle(p, dir);
458 p = xdr_encode_string(p, name);
459 p = xdr_encode_sattr(p, sattr);
460 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
461 free_page((long) p0);
462 return status;
463 }
464 if (!(p = nfs_rpc_verify(p0)))
465 status = NFSERR_IO;
466 else if ((status = ntohl(*p++)) == NFS_OK) {
467 p = xdr_decode_fhandle(p, fhandle);
468 p = xdr_decode_fattr(p, fattr);
469 PRINTK("NFS reply mkdir\n");
470 }
471 free_page((long) p0);
472 return -nfs_stat_to_errno(status);
473 }
474
475 int nfs_proc_rmdir(struct nfs_server *server, struct nfs_fh *dir, char *name)
476 {
477 int *p, *p0;
478 int status;
479
480 PRINTK("NFS call rmdir %s\n", name);
481 p = p0 = (int *) get_free_page(GFP_KERNEL);
482 p = nfs_rpc_header(p, NFSPROC_RMDIR);
483 p = xdr_encode_fhandle(p, dir);
484 p = xdr_encode_string(p, name);
485 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
486 free_page((long) p0);
487 return status;
488 }
489 if (!(p = nfs_rpc_verify(p0)))
490 status = NFSERR_IO;
491 else if ((status = ntohl(*p++)) == NFS_OK) {
492 PRINTK("NFS reply rmdir\n");
493 }
494 free_page((long) p0);
495 return -nfs_stat_to_errno(status);
496 }
497
498 int nfs_proc_readdir(struct nfs_server *server, struct nfs_fh *fhandle,
499 int cookie, int count, struct nfs_entry *entry)
500 {
501 int *p, *p0;
502 int status;
503 int i = 0;
504 int size;
505 int eof;
506
507 PRINTK("NFS call readdir %d @ %d\n", count, cookie);
508 size = server->rsize;
509 p = p0 = (int *) get_free_page(GFP_KERNEL);
510 p = nfs_rpc_header(p, NFSPROC_READDIR);
511 p = xdr_encode_fhandle(p, fhandle);
512 *p++ = htonl(cookie);
513 *p++ = htonl(size);
514 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
515 free_page((long) p0);
516 return status;
517 }
518 if (!(p = nfs_rpc_verify(p0)))
519 status = NFSERR_IO;
520 else if ((status = ntohl(*p++)) == NFS_OK) {
521 for (i = 0; i < count && *p++; i++)
522 p = xdr_decode_entry(p, entry++);
523 eof = (i == count && !*p++ && *p++) || (i < count && *p++);
524 if (eof && i)
525 entry[-1].eof = 1;
526 PRINTK("NFS reply readdir %d %s\n", i, eof ? "eof" : "");
527 }
528 free_page((long) p0);
529 return (status == NFS_OK) ? i : -nfs_stat_to_errno(status);
530 }
531
532 int nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
533 struct nfs_fsinfo *res)
534 {
535 int *p, *p0;
536 int status;
537
538 PRINTK("NFS call statfs\n");
539 p = p0 = (int *) get_free_page(GFP_KERNEL);
540 p = nfs_rpc_header(p, NFSPROC_STATFS);
541 p = xdr_encode_fhandle(p, fhandle);
542 if ((status = nfs_rpc_call(server, p0, p)) < 0) {
543 free_page((long) p0);
544 return status;
545 }
546 if (!(p = nfs_rpc_verify(p0)))
547 status = NFSERR_IO;
548 else if ((status = ntohl(*p++)) == NFS_OK) {
549 p = xdr_decode_fsinfo(p, res);
550 PRINTK("NFS reply statfs\n");
551 }
552 free_page((long) p0);
553 return -nfs_stat_to_errno(status);
554 }
555
556
557
558
559
560 static int *nfs_rpc_header(int *p, int procedure)
561 {
562 int *p1, *p2;
563 int i;
564 static int xid = 0;
565 unsigned char *sys = system_utsname.nodename;
566
567 if (xid == 0) {
568 xid = CURRENT_TIME;
569 xid ^= (sys[3]<<24) | (sys[2]<<16) | (sys[1]<<8) | sys[0];
570 }
571 *p++ = htonl(++xid);
572 *p++ = htonl(RPC_CALL);
573 *p++ = htonl(RPC_VERSION);
574 *p++ = htonl(NFS_PROGRAM);
575 *p++ = htonl(NFS_VERSION);
576 *p++ = htonl(procedure);
577 *p++ = htonl(RPC_AUTH_UNIX);
578 p1 = p++;
579 *p++ = htonl(CURRENT_TIME);
580 p = xdr_encode_string(p, sys);
581 *p++ = htonl(current->euid);
582 *p++ = htonl(current->egid);
583 p2 = p++;
584 for (i = 0; i < 16 && i < NGROUPS && current->groups[i] != NOGROUP; i++)
585 *p++ = htonl(current->groups[i]);
586 *p2 = htonl(i);
587 *p1 = htonl((p - (p1 + 1)) << 2);
588 *p++ = htonl(RPC_AUTH_NULL);
589 *p++ = htonl(0);
590 return p;
591 }
592
593 static int *nfs_rpc_verify(int *p)
594 {
595 int n;
596
597 p++;
598 if (ntohl(*p++) != RPC_REPLY) {
599 printk("not an RPC reply\n");
600 return 0;
601 }
602 if (ntohl(*p++) != RPC_MSG_ACCEPTED) {
603 printk("RPC call rejected\n");
604 return 0;
605 }
606 if ((n = ntohl(*p++)) != RPC_AUTH_NULL && n != RPC_AUTH_UNIX) {
607 printk("reply with unknown RPC authentication type\n");
608 return 0;
609 }
610 n = ntohl(*p++);
611 p += (n + 3) >> 2;
612 if (ntohl(*p++) != RPC_SUCCESS) {
613 printk("RPC call failed\n");
614 return 0;
615 }
616 return p;
617 }
618
619
620
621
622
623
624 #ifndef EDQUOT
625 #define EDQUOT ENOSPC
626 #endif
627
628 static struct {
629 enum nfs_stat stat;
630 int errno;
631 } nfs_errtbl[] = {
632 { NFS_OK, 0 },
633 { NFSERR_PERM, EPERM },
634 { NFSERR_NOENT, ENOENT },
635 { NFSERR_IO, EIO },
636 { NFSERR_NXIO, ENXIO },
637 { NFSERR_ACCES, EACCES },
638 { NFSERR_EXIST, EEXIST },
639 { NFSERR_NODEV, ENODEV },
640 { NFSERR_NOTDIR, ENOTDIR },
641 { NFSERR_ISDIR, EISDIR },
642 { NFSERR_FBIG, EFBIG },
643 { NFSERR_NOSPC, ENOSPC },
644 { NFSERR_ROFS, EROFS },
645 { NFSERR_NAMETOOLONG, ENAMETOOLONG },
646 { NFSERR_NOTEMPTY, ENOTEMPTY },
647 { NFSERR_DQUOT, EDQUOT },
648 { NFSERR_STALE, ESTALE },
649 { NFSERR_WFLUSH, EIO },
650 { -1, EIO }
651 };
652
653 static int nfs_stat_to_errno(int stat)
654 {
655 int errno;
656 int i;
657
658 errno = EIO;
659 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
660 if (nfs_errtbl[i].stat == stat) {
661 errno = nfs_errtbl[i].errno;
662 break;
663 }
664 }
665 return errno;
666 }
667