xref: /openbmc/linux/fs/nfs/nfs2xdr.c (revision 22246614)
1 /*
2  * linux/fs/nfs/nfs2xdr.c
3  *
4  * XDR functions to encode/decode NFS RPC arguments and results.
5  *
6  * Copyright (C) 1992, 1993, 1994  Rick Sladkey
7  * Copyright (C) 1996 Olaf Kirch
8  * 04 Aug 1998  Ion Badulescu <ionut@cs.columbia.edu>
9  * 		FIFO's need special handling in NFSv2
10  */
11 
12 #include <linux/param.h>
13 #include <linux/time.h>
14 #include <linux/mm.h>
15 #include <linux/slab.h>
16 #include <linux/utsname.h>
17 #include <linux/errno.h>
18 #include <linux/string.h>
19 #include <linux/in.h>
20 #include <linux/pagemap.h>
21 #include <linux/proc_fs.h>
22 #include <linux/sunrpc/clnt.h>
23 #include <linux/nfs.h>
24 #include <linux/nfs2.h>
25 #include <linux/nfs_fs.h>
26 #include "internal.h"
27 
28 #define NFSDBG_FACILITY		NFSDBG_XDR
29 
30 /* Mapping from NFS error code to "errno" error code. */
31 #define errno_NFSERR_IO		EIO
32 
33 /*
34  * Declare the space requirements for NFS arguments and replies as
35  * number of 32bit-words
36  */
37 #define NFS_fhandle_sz		(8)
38 #define NFS_sattr_sz		(8)
39 #define NFS_filename_sz		(1+(NFS2_MAXNAMLEN>>2))
40 #define NFS_path_sz		(1+(NFS2_MAXPATHLEN>>2))
41 #define NFS_fattr_sz		(17)
42 #define NFS_info_sz		(5)
43 #define NFS_entry_sz		(NFS_filename_sz+3)
44 
45 #define NFS_diropargs_sz	(NFS_fhandle_sz+NFS_filename_sz)
46 #define NFS_removeargs_sz	(NFS_fhandle_sz+NFS_filename_sz)
47 #define NFS_sattrargs_sz	(NFS_fhandle_sz+NFS_sattr_sz)
48 #define NFS_readlinkargs_sz	(NFS_fhandle_sz)
49 #define NFS_readargs_sz		(NFS_fhandle_sz+3)
50 #define NFS_writeargs_sz	(NFS_fhandle_sz+4)
51 #define NFS_createargs_sz	(NFS_diropargs_sz+NFS_sattr_sz)
52 #define NFS_renameargs_sz	(NFS_diropargs_sz+NFS_diropargs_sz)
53 #define NFS_linkargs_sz		(NFS_fhandle_sz+NFS_diropargs_sz)
54 #define NFS_symlinkargs_sz	(NFS_diropargs_sz+1+NFS_sattr_sz)
55 #define NFS_readdirargs_sz	(NFS_fhandle_sz+2)
56 
57 #define NFS_attrstat_sz		(1+NFS_fattr_sz)
58 #define NFS_diropres_sz		(1+NFS_fhandle_sz+NFS_fattr_sz)
59 #define NFS_readlinkres_sz	(2)
60 #define NFS_readres_sz		(1+NFS_fattr_sz+1)
61 #define NFS_writeres_sz         (NFS_attrstat_sz)
62 #define NFS_stat_sz		(1)
63 #define NFS_readdirres_sz	(1)
64 #define NFS_statfsres_sz	(1+NFS_info_sz)
65 
66 /*
67  * Common NFS XDR functions as inlines
68  */
69 static inline __be32 *
70 xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fhandle)
71 {
72 	memcpy(p, fhandle->data, NFS2_FHSIZE);
73 	return p + XDR_QUADLEN(NFS2_FHSIZE);
74 }
75 
76 static inline __be32 *
77 xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle)
78 {
79 	/* NFSv2 handles have a fixed length */
80 	fhandle->size = NFS2_FHSIZE;
81 	memcpy(fhandle->data, p, NFS2_FHSIZE);
82 	return p + XDR_QUADLEN(NFS2_FHSIZE);
83 }
84 
85 static inline __be32*
86 xdr_encode_time(__be32 *p, struct timespec *timep)
87 {
88 	*p++ = htonl(timep->tv_sec);
89 	/* Convert nanoseconds into microseconds */
90 	*p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0);
91 	return p;
92 }
93 
94 static inline __be32*
95 xdr_encode_current_server_time(__be32 *p, struct timespec *timep)
96 {
97 	/*
98 	 * Passing the invalid value useconds=1000000 is a
99 	 * Sun convention for "set to current server time".
100 	 * It's needed to make permissions checks for the
101 	 * "touch" program across v2 mounts to Solaris and
102 	 * Irix boxes work correctly. See description of
103 	 * sattr in section 6.1 of "NFS Illustrated" by
104 	 * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5
105 	 */
106 	*p++ = htonl(timep->tv_sec);
107 	*p++ = htonl(1000000);
108 	return p;
109 }
110 
111 static inline __be32*
112 xdr_decode_time(__be32 *p, struct timespec *timep)
113 {
114 	timep->tv_sec = ntohl(*p++);
115 	/* Convert microseconds into nanoseconds */
116 	timep->tv_nsec = ntohl(*p++) * 1000;
117 	return p;
118 }
119 
120 static __be32 *
121 xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr)
122 {
123 	u32 rdev;
124 	fattr->type = (enum nfs_ftype) ntohl(*p++);
125 	fattr->mode = ntohl(*p++);
126 	fattr->nlink = ntohl(*p++);
127 	fattr->uid = ntohl(*p++);
128 	fattr->gid = ntohl(*p++);
129 	fattr->size = ntohl(*p++);
130 	fattr->du.nfs2.blocksize = ntohl(*p++);
131 	rdev = ntohl(*p++);
132 	fattr->du.nfs2.blocks = ntohl(*p++);
133 	fattr->fsid.major = ntohl(*p++);
134 	fattr->fsid.minor = 0;
135 	fattr->fileid = ntohl(*p++);
136 	p = xdr_decode_time(p, &fattr->atime);
137 	p = xdr_decode_time(p, &fattr->mtime);
138 	p = xdr_decode_time(p, &fattr->ctime);
139 	fattr->valid |= NFS_ATTR_FATTR;
140 	fattr->rdev = new_decode_dev(rdev);
141 	if (fattr->type == NFCHR && rdev == NFS2_FIFO_DEV) {
142 		fattr->type = NFFIFO;
143 		fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
144 		fattr->rdev = 0;
145 	}
146 	return p;
147 }
148 
149 static inline __be32 *
150 xdr_encode_sattr(__be32 *p, struct iattr *attr)
151 {
152 	const __be32 not_set = __constant_htonl(0xFFFFFFFF);
153 
154 	*p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set;
155 	*p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set;
156 	*p++ = (attr->ia_valid & ATTR_GID) ? htonl(attr->ia_gid) : not_set;
157 	*p++ = (attr->ia_valid & ATTR_SIZE) ? htonl(attr->ia_size) : not_set;
158 
159 	if (attr->ia_valid & ATTR_ATIME_SET) {
160 		p = xdr_encode_time(p, &attr->ia_atime);
161 	} else if (attr->ia_valid & ATTR_ATIME) {
162 		p = xdr_encode_current_server_time(p, &attr->ia_atime);
163 	} else {
164 		*p++ = not_set;
165 		*p++ = not_set;
166 	}
167 
168 	if (attr->ia_valid & ATTR_MTIME_SET) {
169 		p = xdr_encode_time(p, &attr->ia_mtime);
170 	} else if (attr->ia_valid & ATTR_MTIME) {
171 		p = xdr_encode_current_server_time(p, &attr->ia_mtime);
172 	} else {
173 		*p++ = not_set;
174 		*p++ = not_set;
175 	}
176   	return p;
177 }
178 
179 /*
180  * NFS encode functions
181  */
182 /*
183  * Encode file handle argument
184  * GETATTR, READLINK, STATFS
185  */
186 static int
187 nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh)
188 {
189 	p = xdr_encode_fhandle(p, fh);
190 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
191 	return 0;
192 }
193 
194 /*
195  * Encode SETATTR arguments
196  */
197 static int
198 nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args)
199 {
200 	p = xdr_encode_fhandle(p, args->fh);
201 	p = xdr_encode_sattr(p, args->sattr);
202 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
203 	return 0;
204 }
205 
206 /*
207  * Encode directory ops argument
208  * LOOKUP, RMDIR
209  */
210 static int
211 nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args)
212 {
213 	p = xdr_encode_fhandle(p, args->fh);
214 	p = xdr_encode_array(p, args->name, args->len);
215 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
216 	return 0;
217 }
218 
219 /*
220  * Encode REMOVE argument
221  */
222 static int
223 nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
224 {
225 	p = xdr_encode_fhandle(p, args->fh);
226 	p = xdr_encode_array(p, args->name.name, args->name.len);
227 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
228 	return 0;
229 }
230 
231 /*
232  * Arguments to a READ call. Since we read data directly into the page
233  * cache, we also set up the reply iovec here so that iov[1] points
234  * exactly to the page we want to fetch.
235  */
236 static int
237 nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
238 {
239 	struct rpc_auth	*auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
240 	unsigned int replen;
241 	u32 offset = (u32)args->offset;
242 	u32 count = args->count;
243 
244 	p = xdr_encode_fhandle(p, args->fh);
245 	*p++ = htonl(offset);
246 	*p++ = htonl(count);
247 	*p++ = htonl(count);
248 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
249 
250 	/* Inline the page array */
251 	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2;
252 	xdr_inline_pages(&req->rq_rcv_buf, replen,
253 			 args->pages, args->pgbase, count);
254 	req->rq_rcv_buf.flags |= XDRBUF_READ;
255 	return 0;
256 }
257 
258 /*
259  * Decode READ reply
260  */
261 static int
262 nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res)
263 {
264 	struct kvec *iov = req->rq_rcv_buf.head;
265 	size_t hdrlen;
266 	u32 count, recvd;
267 	int status;
268 
269 	if ((status = ntohl(*p++)))
270 		return nfs_stat_to_errno(status);
271 	p = xdr_decode_fattr(p, res->fattr);
272 
273 	count = ntohl(*p++);
274 	res->eof = 0;
275 	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
276 	if (iov->iov_len < hdrlen) {
277 		dprintk("NFS: READ reply header overflowed:"
278 				"length %Zu > %Zu\n", hdrlen, iov->iov_len);
279 		return -errno_NFSERR_IO;
280 	} else if (iov->iov_len != hdrlen) {
281 		dprintk("NFS: READ header is short. iovec will be shifted.\n");
282 		xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen);
283 	}
284 
285 	recvd = req->rq_rcv_buf.len - hdrlen;
286 	if (count > recvd) {
287 		dprintk("NFS: server cheating in read reply: "
288 			"count %u > recvd %u\n", count, recvd);
289 		count = recvd;
290 	}
291 
292 	dprintk("RPC:      readres OK count %u\n", count);
293 	if (count < res->count)
294 		res->count = count;
295 
296 	return count;
297 }
298 
299 
300 /*
301  * Write arguments. Splice the buffer to be written into the iovec.
302  */
303 static int
304 nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
305 {
306 	struct xdr_buf *sndbuf = &req->rq_snd_buf;
307 	u32 offset = (u32)args->offset;
308 	u32 count = args->count;
309 
310 	p = xdr_encode_fhandle(p, args->fh);
311 	*p++ = htonl(offset);
312 	*p++ = htonl(offset);
313 	*p++ = htonl(count);
314 	*p++ = htonl(count);
315 	sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
316 
317 	/* Copy the page array */
318 	xdr_encode_pages(sndbuf, args->pages, args->pgbase, count);
319 	sndbuf->flags |= XDRBUF_WRITE;
320 	return 0;
321 }
322 
323 /*
324  * Encode create arguments
325  * CREATE, MKDIR
326  */
327 static int
328 nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args)
329 {
330 	p = xdr_encode_fhandle(p, args->fh);
331 	p = xdr_encode_array(p, args->name, args->len);
332 	p = xdr_encode_sattr(p, args->sattr);
333 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
334 	return 0;
335 }
336 
337 /*
338  * Encode RENAME arguments
339  */
340 static int
341 nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args)
342 {
343 	p = xdr_encode_fhandle(p, args->fromfh);
344 	p = xdr_encode_array(p, args->fromname, args->fromlen);
345 	p = xdr_encode_fhandle(p, args->tofh);
346 	p = xdr_encode_array(p, args->toname, args->tolen);
347 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
348 	return 0;
349 }
350 
351 /*
352  * Encode LINK arguments
353  */
354 static int
355 nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args)
356 {
357 	p = xdr_encode_fhandle(p, args->fromfh);
358 	p = xdr_encode_fhandle(p, args->tofh);
359 	p = xdr_encode_array(p, args->toname, args->tolen);
360 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
361 	return 0;
362 }
363 
364 /*
365  * Encode SYMLINK arguments
366  */
367 static int
368 nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *args)
369 {
370 	struct xdr_buf *sndbuf = &req->rq_snd_buf;
371 	size_t pad;
372 
373 	p = xdr_encode_fhandle(p, args->fromfh);
374 	p = xdr_encode_array(p, args->fromname, args->fromlen);
375 	*p++ = htonl(args->pathlen);
376 	sndbuf->len = xdr_adjust_iovec(sndbuf->head, p);
377 
378 	xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen);
379 
380 	/*
381 	 * xdr_encode_pages may have added a few bytes to ensure the
382 	 * pathname ends on a 4-byte boundary.  Start encoding the
383 	 * attributes after the pad bytes.
384 	 */
385 	pad = sndbuf->tail->iov_len;
386 	if (pad > 0)
387 		p++;
388 	p = xdr_encode_sattr(p, args->sattr);
389 	sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad;
390 	return 0;
391 }
392 
393 /*
394  * Encode arguments to readdir call
395  */
396 static int
397 nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args)
398 {
399 	struct rpc_task	*task = req->rq_task;
400 	struct rpc_auth	*auth = task->tk_msg.rpc_cred->cr_auth;
401 	unsigned int replen;
402 	u32 count = args->count;
403 
404 	p = xdr_encode_fhandle(p, args->fh);
405 	*p++ = htonl(args->cookie);
406 	*p++ = htonl(count); /* see above */
407 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
408 
409 	/* Inline the page array */
410 	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readdirres_sz) << 2;
411 	xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count);
412 	return 0;
413 }
414 
415 /*
416  * Decode the result of a readdir call.
417  * We're not really decoding anymore, we just leave the buffer untouched
418  * and only check that it is syntactically correct.
419  * The real decoding happens in nfs_decode_entry below, called directly
420  * from nfs_readdir for each entry.
421  */
422 static int
423 nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy)
424 {
425 	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
426 	struct kvec *iov = rcvbuf->head;
427 	struct page **page;
428 	size_t hdrlen;
429 	unsigned int pglen, recvd;
430 	u32 len;
431 	int status, nr = 0;
432 	__be32 *end, *entry, *kaddr;
433 
434 	if ((status = ntohl(*p++)))
435 		return nfs_stat_to_errno(status);
436 
437 	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
438 	if (iov->iov_len < hdrlen) {
439 		dprintk("NFS: READDIR reply header overflowed:"
440 				"length %Zu > %Zu\n", hdrlen, iov->iov_len);
441 		return -errno_NFSERR_IO;
442 	} else if (iov->iov_len != hdrlen) {
443 		dprintk("NFS: READDIR header is short. iovec will be shifted.\n");
444 		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
445 	}
446 
447 	pglen = rcvbuf->page_len;
448 	recvd = rcvbuf->len - hdrlen;
449 	if (pglen > recvd)
450 		pglen = recvd;
451 	page = rcvbuf->pages;
452 	kaddr = p = kmap_atomic(*page, KM_USER0);
453 	end = (__be32 *)((char *)p + pglen);
454 	entry = p;
455 
456 	/* Make sure the packet actually has a value_follows and EOF entry */
457 	if ((entry + 1) > end)
458 		goto short_pkt;
459 
460 	for (; *p++; nr++) {
461 		if (p + 2 > end)
462 			goto short_pkt;
463 		p++; /* fileid */
464 		len = ntohl(*p++);
465 		p += XDR_QUADLEN(len) + 1;	/* name plus cookie */
466 		if (len > NFS2_MAXNAMLEN) {
467 			dprintk("NFS: giant filename in readdir (len 0x%x)!\n",
468 						len);
469 			goto err_unmap;
470 		}
471 		if (p + 2 > end)
472 			goto short_pkt;
473 		entry = p;
474 	}
475 
476 	/*
477 	 * Apparently some server sends responses that are a valid size, but
478 	 * contain no entries, and have value_follows==0 and EOF==0. For
479 	 * those, just set the EOF marker.
480 	 */
481 	if (!nr && entry[1] == 0) {
482 		dprintk("NFS: readdir reply truncated!\n");
483 		entry[1] = 1;
484 	}
485  out:
486 	kunmap_atomic(kaddr, KM_USER0);
487 	return nr;
488  short_pkt:
489 	/*
490 	 * When we get a short packet there are 2 possibilities. We can
491 	 * return an error, or fix up the response to look like a valid
492 	 * response and return what we have so far. If there are no
493 	 * entries and the packet was short, then return -EIO. If there
494 	 * are valid entries in the response, return them and pretend that
495 	 * the call was successful, but incomplete. The caller can retry the
496 	 * readdir starting at the last cookie.
497 	 */
498 	entry[0] = entry[1] = 0;
499 	if (!nr)
500 		nr = -errno_NFSERR_IO;
501 	goto out;
502 err_unmap:
503 	nr = -errno_NFSERR_IO;
504 	goto out;
505 }
506 
507 __be32 *
508 nfs_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
509 {
510 	if (!*p++) {
511 		if (!*p)
512 			return ERR_PTR(-EAGAIN);
513 		entry->eof = 1;
514 		return ERR_PTR(-EBADCOOKIE);
515 	}
516 
517 	entry->ino	  = ntohl(*p++);
518 	entry->len	  = ntohl(*p++);
519 	entry->name	  = (const char *) p;
520 	p		 += XDR_QUADLEN(entry->len);
521 	entry->prev_cookie	  = entry->cookie;
522 	entry->cookie	  = ntohl(*p++);
523 	entry->eof	  = !p[0] && p[1];
524 
525 	return p;
526 }
527 
528 /*
529  * NFS XDR decode functions
530  */
531 /*
532  * Decode simple status reply
533  */
534 static int
535 nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy)
536 {
537 	int	status;
538 
539 	if ((status = ntohl(*p++)) != 0)
540 		status = nfs_stat_to_errno(status);
541 	return status;
542 }
543 
544 /*
545  * Decode attrstat reply
546  * GETATTR, SETATTR, WRITE
547  */
548 static int
549 nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr)
550 {
551 	int	status;
552 
553 	if ((status = ntohl(*p++)))
554 		return nfs_stat_to_errno(status);
555 	xdr_decode_fattr(p, fattr);
556 	return 0;
557 }
558 
559 /*
560  * Decode diropres reply
561  * LOOKUP, CREATE, MKDIR
562  */
563 static int
564 nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res)
565 {
566 	int	status;
567 
568 	if ((status = ntohl(*p++)))
569 		return nfs_stat_to_errno(status);
570 	p = xdr_decode_fhandle(p, res->fh);
571 	xdr_decode_fattr(p, res->fattr);
572 	return 0;
573 }
574 
575 /*
576  * Encode READLINK args
577  */
578 static int
579 nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args)
580 {
581 	struct rpc_auth	*auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
582 	unsigned int replen;
583 
584 	p = xdr_encode_fhandle(p, args->fh);
585 	req->rq_slen = xdr_adjust_iovec(req->rq_svec, p);
586 
587 	/* Inline the page array */
588 	replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2;
589 	xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen);
590 	return 0;
591 }
592 
593 /*
594  * Decode READLINK reply
595  */
596 static int
597 nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy)
598 {
599 	struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
600 	struct kvec *iov = rcvbuf->head;
601 	size_t hdrlen;
602 	u32 len, recvd;
603 	char	*kaddr;
604 	int	status;
605 
606 	if ((status = ntohl(*p++)))
607 		return nfs_stat_to_errno(status);
608 	/* Convert length of symlink */
609 	len = ntohl(*p++);
610 	if (len >= rcvbuf->page_len) {
611 		dprintk("nfs: server returned giant symlink!\n");
612 		return -ENAMETOOLONG;
613 	}
614 	hdrlen = (u8 *) p - (u8 *) iov->iov_base;
615 	if (iov->iov_len < hdrlen) {
616 		dprintk("NFS: READLINK reply header overflowed:"
617 				"length %Zu > %Zu\n", hdrlen, iov->iov_len);
618 		return -errno_NFSERR_IO;
619 	} else if (iov->iov_len != hdrlen) {
620 		dprintk("NFS: READLINK header is short. iovec will be shifted.\n");
621 		xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen);
622 	}
623 	recvd = req->rq_rcv_buf.len - hdrlen;
624 	if (recvd < len) {
625 		dprintk("NFS: server cheating in readlink reply: "
626 				"count %u > recvd %u\n", len, recvd);
627 		return -EIO;
628 	}
629 
630 	/* NULL terminate the string we got */
631 	kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0);
632 	kaddr[len+rcvbuf->page_base] = '\0';
633 	kunmap_atomic(kaddr, KM_USER0);
634 	return 0;
635 }
636 
637 /*
638  * Decode WRITE reply
639  */
640 static int
641 nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res)
642 {
643 	res->verf->committed = NFS_FILE_SYNC;
644 	return nfs_xdr_attrstat(req, p, res->fattr);
645 }
646 
647 /*
648  * Decode STATFS reply
649  */
650 static int
651 nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res)
652 {
653 	int	status;
654 
655 	if ((status = ntohl(*p++)))
656 		return nfs_stat_to_errno(status);
657 
658 	res->tsize  = ntohl(*p++);
659 	res->bsize  = ntohl(*p++);
660 	res->blocks = ntohl(*p++);
661 	res->bfree  = ntohl(*p++);
662 	res->bavail = ntohl(*p++);
663 	return 0;
664 }
665 
666 /*
667  * We need to translate between nfs status return values and
668  * the local errno values which may not be the same.
669  */
670 static struct {
671 	int stat;
672 	int errno;
673 } nfs_errtbl[] = {
674 	{ NFS_OK,		0		},
675 	{ NFSERR_PERM,		-EPERM		},
676 	{ NFSERR_NOENT,		-ENOENT		},
677 	{ NFSERR_IO,		-errno_NFSERR_IO},
678 	{ NFSERR_NXIO,		-ENXIO		},
679 /*	{ NFSERR_EAGAIN,	-EAGAIN		}, */
680 	{ NFSERR_ACCES,		-EACCES		},
681 	{ NFSERR_EXIST,		-EEXIST		},
682 	{ NFSERR_XDEV,		-EXDEV		},
683 	{ NFSERR_NODEV,		-ENODEV		},
684 	{ NFSERR_NOTDIR,	-ENOTDIR	},
685 	{ NFSERR_ISDIR,		-EISDIR		},
686 	{ NFSERR_INVAL,		-EINVAL		},
687 	{ NFSERR_FBIG,		-EFBIG		},
688 	{ NFSERR_NOSPC,		-ENOSPC		},
689 	{ NFSERR_ROFS,		-EROFS		},
690 	{ NFSERR_MLINK,		-EMLINK		},
691 	{ NFSERR_NAMETOOLONG,	-ENAMETOOLONG	},
692 	{ NFSERR_NOTEMPTY,	-ENOTEMPTY	},
693 	{ NFSERR_DQUOT,		-EDQUOT		},
694 	{ NFSERR_STALE,		-ESTALE		},
695 	{ NFSERR_REMOTE,	-EREMOTE	},
696 #ifdef EWFLUSH
697 	{ NFSERR_WFLUSH,	-EWFLUSH	},
698 #endif
699 	{ NFSERR_BADHANDLE,	-EBADHANDLE	},
700 	{ NFSERR_NOT_SYNC,	-ENOTSYNC	},
701 	{ NFSERR_BAD_COOKIE,	-EBADCOOKIE	},
702 	{ NFSERR_NOTSUPP,	-ENOTSUPP	},
703 	{ NFSERR_TOOSMALL,	-ETOOSMALL	},
704 	{ NFSERR_SERVERFAULT,	-ESERVERFAULT	},
705 	{ NFSERR_BADTYPE,	-EBADTYPE	},
706 	{ NFSERR_JUKEBOX,	-EJUKEBOX	},
707 	{ -1,			-EIO		}
708 };
709 
710 /*
711  * Convert an NFS error code to a local one.
712  * This one is used jointly by NFSv2 and NFSv3.
713  */
714 int
715 nfs_stat_to_errno(int stat)
716 {
717 	int i;
718 
719 	for (i = 0; nfs_errtbl[i].stat != -1; i++) {
720 		if (nfs_errtbl[i].stat == stat)
721 			return nfs_errtbl[i].errno;
722 	}
723 	dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat);
724 	return nfs_errtbl[i].errno;
725 }
726 
727 #define PROC(proc, argtype, restype, timer)				\
728 [NFSPROC_##proc] = {							\
729 	.p_proc	    =  NFSPROC_##proc,					\
730 	.p_encode   =  (kxdrproc_t) nfs_xdr_##argtype,			\
731 	.p_decode   =  (kxdrproc_t) nfs_xdr_##restype,			\
732 	.p_arglen   =  NFS_##argtype##_sz,				\
733 	.p_replen   =  NFS_##restype##_sz,				\
734 	.p_timer    =  timer,						\
735 	.p_statidx  =  NFSPROC_##proc,					\
736 	.p_name     =  #proc,						\
737 	}
738 struct rpc_procinfo	nfs_procedures[] = {
739     PROC(GETATTR,	fhandle,	attrstat, 1),
740     PROC(SETATTR,	sattrargs,	attrstat, 0),
741     PROC(LOOKUP,	diropargs,	diropres, 2),
742     PROC(READLINK,	readlinkargs,	readlinkres, 3),
743     PROC(READ,		readargs,	readres, 3),
744     PROC(WRITE,		writeargs,	writeres, 4),
745     PROC(CREATE,	createargs,	diropres, 0),
746     PROC(REMOVE,	removeargs,	stat, 0),
747     PROC(RENAME,	renameargs,	stat, 0),
748     PROC(LINK,		linkargs,	stat, 0),
749     PROC(SYMLINK,	symlinkargs,	stat, 0),
750     PROC(MKDIR,		createargs,	diropres, 0),
751     PROC(RMDIR,		diropargs,	stat, 0),
752     PROC(READDIR,	readdirargs,	readdirres, 3),
753     PROC(STATFS,	fhandle,	statfsres, 0),
754 };
755 
756 struct rpc_version		nfs_version2 = {
757 	.number			= 2,
758 	.nrprocs		= ARRAY_SIZE(nfs_procedures),
759 	.procs			= nfs_procedures
760 };
761