usb: gadget: udc: reduce indentation
[linux-2.6-block.git] / fs / nfs / nfs2xdr.c
CommitLineData
b2441318 1// SPDX-License-Identifier: GPL-2.0
1da177e4
LT
2/*
3 * linux/fs/nfs/nfs2xdr.c
4 *
5 * XDR functions to encode/decode NFS RPC arguments and results.
6 *
7 * Copyright (C) 1992, 1993, 1994 Rick Sladkey
8 * Copyright (C) 1996 Olaf Kirch
9 * 04 Aug 1998 Ion Badulescu <ionut@cs.columbia.edu>
10 * FIFO's need special handling in NFSv2
11 */
12
13#include <linux/param.h>
14#include <linux/time.h>
15#include <linux/mm.h>
1da177e4
LT
16#include <linux/errno.h>
17#include <linux/string.h>
18#include <linux/in.h>
19#include <linux/pagemap.h>
20#include <linux/proc_fs.h>
21#include <linux/sunrpc/clnt.h>
22#include <linux/nfs.h>
23#include <linux/nfs2.h>
24#include <linux/nfs_fs.h>
816724e6 25#include "internal.h"
1da177e4
LT
26
27#define NFSDBG_FACILITY NFSDBG_XDR
1da177e4 28
1da177e4
LT
29/* Mapping from NFS error code to "errno" error code. */
30#define errno_NFSERR_IO EIO
31
32/*
33 * Declare the space requirements for NFS arguments and replies as
34 * number of 32bit-words
35 */
36#define NFS_fhandle_sz (8)
37#define NFS_sattr_sz (8)
38#define NFS_filename_sz (1+(NFS2_MAXNAMLEN>>2))
39#define NFS_path_sz (1+(NFS2_MAXPATHLEN>>2))
40#define NFS_fattr_sz (17)
41#define NFS_info_sz (5)
42#define NFS_entry_sz (NFS_filename_sz+3)
43
44#define NFS_diropargs_sz (NFS_fhandle_sz+NFS_filename_sz)
4fdc17b2 45#define NFS_removeargs_sz (NFS_fhandle_sz+NFS_filename_sz)
1da177e4
LT
46#define NFS_sattrargs_sz (NFS_fhandle_sz+NFS_sattr_sz)
47#define NFS_readlinkargs_sz (NFS_fhandle_sz)
48#define NFS_readargs_sz (NFS_fhandle_sz+3)
49#define NFS_writeargs_sz (NFS_fhandle_sz+4)
50#define NFS_createargs_sz (NFS_diropargs_sz+NFS_sattr_sz)
51#define NFS_renameargs_sz (NFS_diropargs_sz+NFS_diropargs_sz)
52#define NFS_linkargs_sz (NFS_fhandle_sz+NFS_diropargs_sz)
94a6d753 53#define NFS_symlinkargs_sz (NFS_diropargs_sz+1+NFS_sattr_sz)
1da177e4
LT
54#define NFS_readdirargs_sz (NFS_fhandle_sz+2)
55
56#define NFS_attrstat_sz (1+NFS_fattr_sz)
57#define NFS_diropres_sz (1+NFS_fhandle_sz+NFS_fattr_sz)
58#define NFS_readlinkres_sz (2)
59#define NFS_readres_sz (1+NFS_fattr_sz+1)
60#define NFS_writeres_sz (NFS_attrstat_sz)
61#define NFS_stat_sz (1)
62#define NFS_readdirres_sz (1)
63#define NFS_statfsres_sz (1+NFS_info_sz)
64
5e7e5a0d 65static int nfs_stat_to_errno(enum nfs_stat);
25a0866c
CL
66
67/*
68 * While encoding arguments, set up the reply buffer in advance to
69 * receive reply data directly into the page cache.
70 */
71static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages,
72 unsigned int base, unsigned int len,
73 unsigned int bufsize)
74{
75 struct rpc_auth *auth = req->rq_cred->cr_auth;
76 unsigned int replen;
77
78 replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize;
79 xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len);
80}
81
f796f8b3
CL
82/*
83 * Handle decode buffer overflows out-of-line.
84 */
85static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
86{
87 dprintk("NFS: %s prematurely hit the end of our receive buffer. "
88 "Remaining buffer length is %tu words.\n",
89 func, xdr->end - xdr->p);
90}
91
25a0866c 92
25a0866c
CL
93/*
94 * Encode/decode NFSv2 basic data types
95 *
96 * Basic NFSv2 data types are defined in section 2.3 of RFC 1094:
97 * "NFS: Network File System Protocol Specification".
98 *
99 * Not all basic data types have their own encoding and decoding
100 * functions. For run-time efficiency, some data types are encoded
101 * or decoded inline.
102 */
103
f796f8b3
CL
104/*
105 * typedef opaque nfsdata<>;
106 */
9137bdf3 107static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_pgio_res *result)
f796f8b3
CL
108{
109 u32 recvd, count;
f796f8b3
CL
110 __be32 *p;
111
112 p = xdr_inline_decode(xdr, 4);
113 if (unlikely(p == NULL))
114 goto out_overflow;
115 count = be32_to_cpup(p);
64bd577e 116 recvd = xdr_read_pages(xdr, count);
f796f8b3
CL
117 if (unlikely(count > recvd))
118 goto out_cheating;
119out:
f796f8b3
CL
120 result->eof = 0; /* NFSv2 does not pass EOF flag on the wire. */
121 result->count = count;
122 return count;
123out_cheating:
124 dprintk("NFS: server cheating in read result: "
125 "count %u > recvd %u\n", count, recvd);
126 count = recvd;
127 goto out;
128out_overflow:
129 print_overflow_msg(__func__, xdr);
130 return -EIO;
131}
132
133/*
134 * enum stat {
135 * NFS_OK = 0,
136 * NFSERR_PERM = 1,
137 * NFSERR_NOENT = 2,
138 * NFSERR_IO = 5,
139 * NFSERR_NXIO = 6,
140 * NFSERR_ACCES = 13,
141 * NFSERR_EXIST = 17,
142 * NFSERR_NODEV = 19,
143 * NFSERR_NOTDIR = 20,
144 * NFSERR_ISDIR = 21,
145 * NFSERR_FBIG = 27,
146 * NFSERR_NOSPC = 28,
147 * NFSERR_ROFS = 30,
148 * NFSERR_NAMETOOLONG = 63,
149 * NFSERR_NOTEMPTY = 66,
150 * NFSERR_DQUOT = 69,
151 * NFSERR_STALE = 70,
152 * NFSERR_WFLUSH = 99
153 * };
154 */
155static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status)
156{
157 __be32 *p;
158
159 p = xdr_inline_decode(xdr, 4);
160 if (unlikely(p == NULL))
161 goto out_overflow;
162 *status = be32_to_cpup(p);
163 return 0;
164out_overflow:
165 print_overflow_msg(__func__, xdr);
166 return -EIO;
167}
168
5f96e5e3
CL
169/*
170 * 2.3.2. ftype
171 *
172 * enum ftype {
173 * NFNON = 0,
174 * NFREG = 1,
175 * NFDIR = 2,
176 * NFBLK = 3,
177 * NFCHR = 4,
178 * NFLNK = 5
179 * };
180 *
181 */
182static __be32 *xdr_decode_ftype(__be32 *p, u32 *type)
183{
184 *type = be32_to_cpup(p++);
185 if (unlikely(*type > NF2FIFO))
186 *type = NFBAD;
187 return p;
188}
189
25a0866c
CL
190/*
191 * 2.3.3. fhandle
192 *
193 * typedef opaque fhandle[FHSIZE];
194 */
195static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh)
196{
197 __be32 *p;
198
25a0866c
CL
199 p = xdr_reserve_space(xdr, NFS2_FHSIZE);
200 memcpy(p, fh->data, NFS2_FHSIZE);
201}
202
f796f8b3
CL
203static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh)
204{
205 __be32 *p;
206
207 p = xdr_inline_decode(xdr, NFS2_FHSIZE);
208 if (unlikely(p == NULL))
209 goto out_overflow;
210 fh->size = NFS2_FHSIZE;
211 memcpy(fh->data, p, NFS2_FHSIZE);
212 return 0;
213out_overflow:
214 print_overflow_msg(__func__, xdr);
215 return -EIO;
216}
217
282ac2a5
CL
218/*
219 * 2.3.4. timeval
220 *
221 * struct timeval {
222 * unsigned int seconds;
223 * unsigned int useconds;
224 * };
225 */
226static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep)
227{
228 *p++ = cpu_to_be32(timep->tv_sec);
229 if (timep->tv_nsec != 0)
230 *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC);
231 else
232 *p++ = cpu_to_be32(0);
233 return p;
234}
235
236/*
237 * Passing the invalid value useconds=1000000 is a Sun convention for
238 * "set to current server time". It's needed to make permissions checks
239 * for the "touch" program across v2 mounts to Solaris and Irix servers
240 * work correctly. See description of sattr in section 6.1 of "NFS
241 * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5.
242 */
243static __be32 *xdr_encode_current_server_time(__be32 *p,
244 const struct timespec *timep)
245{
246 *p++ = cpu_to_be32(timep->tv_sec);
247 *p++ = cpu_to_be32(1000000);
248 return p;
249}
250
5f96e5e3
CL
251static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep)
252{
253 timep->tv_sec = be32_to_cpup(p++);
254 timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC;
255 return p;
256}
257
f796f8b3
CL
258/*
259 * 2.3.5. fattr
260 *
261 * struct fattr {
262 * ftype type;
263 * unsigned int mode;
264 * unsigned int nlink;
265 * unsigned int uid;
266 * unsigned int gid;
267 * unsigned int size;
268 * unsigned int blocksize;
269 * unsigned int rdev;
270 * unsigned int blocks;
271 * unsigned int fsid;
272 * unsigned int fileid;
273 * timeval atime;
274 * timeval mtime;
275 * timeval ctime;
276 * };
277 *
278 */
279static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr)
280{
5f96e5e3 281 u32 rdev, type;
f796f8b3
CL
282 __be32 *p;
283
284 p = xdr_inline_decode(xdr, NFS_fattr_sz << 2);
285 if (unlikely(p == NULL))
286 goto out_overflow;
5f96e5e3
CL
287
288 fattr->valid |= NFS_ATTR_FATTR_V2;
289
290 p = xdr_decode_ftype(p, &type);
291
292 fattr->mode = be32_to_cpup(p++);
293 fattr->nlink = be32_to_cpup(p++);
cfa0898d
EB
294 fattr->uid = make_kuid(&init_user_ns, be32_to_cpup(p++));
295 if (!uid_valid(fattr->uid))
296 goto out_uid;
297 fattr->gid = make_kgid(&init_user_ns, be32_to_cpup(p++));
298 if (!gid_valid(fattr->gid))
299 goto out_gid;
300
5f96e5e3
CL
301 fattr->size = be32_to_cpup(p++);
302 fattr->du.nfs2.blocksize = be32_to_cpup(p++);
303
304 rdev = be32_to_cpup(p++);
305 fattr->rdev = new_decode_dev(rdev);
306 if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) {
307 fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO;
308 fattr->rdev = 0;
309 }
310
311 fattr->du.nfs2.blocks = be32_to_cpup(p++);
312 fattr->fsid.major = be32_to_cpup(p++);
313 fattr->fsid.minor = 0;
314 fattr->fileid = be32_to_cpup(p++);
315
316 p = xdr_decode_time(p, &fattr->atime);
317 p = xdr_decode_time(p, &fattr->mtime);
318 xdr_decode_time(p, &fattr->ctime);
3a1556e8
TM
319 fattr->change_attr = nfs_timespec_to_change_attr(&fattr->ctime);
320
f796f8b3 321 return 0;
cfa0898d
EB
322out_uid:
323 dprintk("NFS: returned invalid uid\n");
324 return -EINVAL;
325out_gid:
326 dprintk("NFS: returned invalid gid\n");
327 return -EINVAL;
f796f8b3
CL
328out_overflow:
329 print_overflow_msg(__func__, xdr);
330 return -EIO;
331}
332
25a0866c
CL
333/*
334 * 2.3.6. sattr
335 *
336 * struct sattr {
337 * unsigned int mode;
338 * unsigned int uid;
339 * unsigned int gid;
340 * unsigned int size;
341 * timeval atime;
342 * timeval mtime;
343 * };
344 */
345
346#define NFS2_SATTR_NOT_SET (0xffffffff)
347
348static __be32 *xdr_time_not_set(__be32 *p)
349{
350 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
351 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
352 return p;
353}
354
355static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr)
356{
95582b00 357 struct timespec ts;
25a0866c
CL
358 __be32 *p;
359
360 p = xdr_reserve_space(xdr, NFS_sattr_sz << 2);
361
362 if (attr->ia_valid & ATTR_MODE)
363 *p++ = cpu_to_be32(attr->ia_mode);
364 else
365 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
366 if (attr->ia_valid & ATTR_UID)
cfa0898d 367 *p++ = cpu_to_be32(from_kuid(&init_user_ns, attr->ia_uid));
25a0866c
CL
368 else
369 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
370 if (attr->ia_valid & ATTR_GID)
cfa0898d 371 *p++ = cpu_to_be32(from_kgid(&init_user_ns, attr->ia_gid));
25a0866c
CL
372 else
373 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
374 if (attr->ia_valid & ATTR_SIZE)
375 *p++ = cpu_to_be32((u32)attr->ia_size);
376 else
377 *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
378
95582b00
DD
379 if (attr->ia_valid & ATTR_ATIME_SET) {
380 ts = timespec64_to_timespec(attr->ia_atime);
381 p = xdr_encode_time(p, &ts);
382 } else if (attr->ia_valid & ATTR_ATIME) {
383 ts = timespec64_to_timespec(attr->ia_atime);
384 p = xdr_encode_current_server_time(p, &ts);
385 } else
25a0866c 386 p = xdr_time_not_set(p);
95582b00
DD
387 if (attr->ia_valid & ATTR_MTIME_SET) {
388 ts = timespec64_to_timespec(attr->ia_atime);
389 xdr_encode_time(p, &ts);
390 } else if (attr->ia_valid & ATTR_MTIME) {
391 ts = timespec64_to_timespec(attr->ia_mtime);
392 xdr_encode_current_server_time(p, &ts);
393 } else
25a0866c
CL
394 xdr_time_not_set(p);
395}
396
397/*
398 * 2.3.7. filename
399 *
400 * typedef string filename<MAXNAMLEN>;
401 */
402static void encode_filename(struct xdr_stream *xdr,
403 const char *name, u32 length)
404{
405 __be32 *p;
406
7fc38846 407 WARN_ON_ONCE(length > NFS2_MAXNAMLEN);
25a0866c
CL
408 p = xdr_reserve_space(xdr, 4 + length);
409 xdr_encode_opaque(p, name, length);
410}
411
f796f8b3
CL
412static int decode_filename_inline(struct xdr_stream *xdr,
413 const char **name, u32 *length)
414{
415 __be32 *p;
416 u32 count;
417
418 p = xdr_inline_decode(xdr, 4);
419 if (unlikely(p == NULL))
420 goto out_overflow;
421 count = be32_to_cpup(p);
422 if (count > NFS3_MAXNAMLEN)
423 goto out_nametoolong;
424 p = xdr_inline_decode(xdr, count);
425 if (unlikely(p == NULL))
426 goto out_overflow;
427 *name = (const char *)p;
428 *length = count;
429 return 0;
430out_nametoolong:
431 dprintk("NFS: returned filename too long: %u\n", count);
432 return -ENAMETOOLONG;
433out_overflow:
434 print_overflow_msg(__func__, xdr);
435 return -EIO;
436}
437
25a0866c
CL
438/*
439 * 2.3.8. path
440 *
441 * typedef string path<MAXPATHLEN>;
442 */
443static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length)
444{
445 __be32 *p;
446
25a0866c
CL
447 p = xdr_reserve_space(xdr, 4);
448 *p = cpu_to_be32(length);
449 xdr_write_pages(xdr, pages, 0, length);
450}
451
f796f8b3
CL
452static int decode_path(struct xdr_stream *xdr)
453{
454 u32 length, recvd;
f796f8b3
CL
455 __be32 *p;
456
457 p = xdr_inline_decode(xdr, 4);
458 if (unlikely(p == NULL))
459 goto out_overflow;
460 length = be32_to_cpup(p);
461 if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN))
462 goto out_size;
64bd577e 463 recvd = xdr_read_pages(xdr, length);
f796f8b3
CL
464 if (unlikely(length > recvd))
465 goto out_cheating;
f796f8b3
CL
466 xdr_terminate_string(xdr->buf, length);
467 return 0;
468out_size:
469 dprintk("NFS: returned pathname too long: %u\n", length);
470 return -ENAMETOOLONG;
471out_cheating:
472 dprintk("NFS: server cheating in pathname result: "
473 "length %u > received %u\n", length, recvd);
474 return -EIO;
475out_overflow:
476 print_overflow_msg(__func__, xdr);
477 return -EIO;
478}
479
480/*
481 * 2.3.9. attrstat
482 *
483 * union attrstat switch (stat status) {
484 * case NFS_OK:
485 * fattr attributes;
486 * default:
487 * void;
488 * };
489 */
aabff4dd
PT
490static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result,
491 __u32 *op_status)
f796f8b3
CL
492{
493 enum nfs_stat status;
494 int error;
495
496 error = decode_stat(xdr, &status);
497 if (unlikely(error))
498 goto out;
aabff4dd
PT
499 if (op_status)
500 *op_status = status;
f796f8b3
CL
501 if (status != NFS_OK)
502 goto out_default;
503 error = decode_fattr(xdr, result);
504out:
505 return error;
506out_default:
507 return nfs_stat_to_errno(status);
508}
509
25a0866c
CL
510/*
511 * 2.3.10. diropargs
512 *
513 * struct diropargs {
514 * fhandle dir;
515 * filename name;
516 * };
517 */
518static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh,
519 const char *name, u32 length)
520{
521 encode_fhandle(xdr, fh);
522 encode_filename(xdr, name, length);
523}
524
f796f8b3
CL
525/*
526 * 2.3.11. diropres
527 *
528 * union diropres switch (stat status) {
529 * case NFS_OK:
530 * struct {
531 * fhandle file;
532 * fattr attributes;
533 * } diropok;
534 * default:
535 * void;
536 * };
537 */
538static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result)
539{
540 int error;
541
542 error = decode_fhandle(xdr, result->fh);
543 if (unlikely(error))
544 goto out;
545 error = decode_fattr(xdr, result->fattr);
546out:
547 return error;
548}
549
550static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result)
551{
552 enum nfs_stat status;
553 int error;
554
555 error = decode_stat(xdr, &status);
556 if (unlikely(error))
557 goto out;
558 if (status != NFS_OK)
559 goto out_default;
560 error = decode_diropok(xdr, result);
561out:
562 return error;
563out_default:
564 return nfs_stat_to_errno(status);
565}
566
25a0866c 567
1da177e4 568/*
2d70f533
CL
569 * NFSv2 XDR encode functions
570 *
571 * NFSv2 argument types are defined in section 2.2 of RFC 1094:
572 * "NFS: Network File System Protocol Specification".
1da177e4 573 */
1da177e4 574
9f06c719
CL
575static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req,
576 struct xdr_stream *xdr,
fcc85819 577 const void *data)
25a0866c 578{
fcc85819
CH
579 const struct nfs_fh *fh = data;
580
9f06c719 581 encode_fhandle(xdr, fh);
25a0866c
CL
582}
583
25a0866c
CL
584/*
585 * 2.2.3. sattrargs
586 *
587 * struct sattrargs {
588 * fhandle file;
589 * sattr attributes;
590 * };
591 */
9f06c719
CL
592static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req,
593 struct xdr_stream *xdr,
fcc85819 594 const void *data)
25a0866c 595{
fcc85819
CH
596 const struct nfs_sattrargs *args = data;
597
9f06c719
CL
598 encode_fhandle(xdr, args->fh);
599 encode_sattr(xdr, args->sattr);
25a0866c
CL
600}
601
9f06c719
CL
602static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req,
603 struct xdr_stream *xdr,
fcc85819 604 const void *data)
25a0866c 605{
fcc85819
CH
606 const struct nfs_diropargs *args = data;
607
9f06c719 608 encode_diropargs(xdr, args->fh, args->name, args->len);
25a0866c
CL
609}
610
9f06c719
CL
611static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req,
612 struct xdr_stream *xdr,
fcc85819 613 const void *data)
25a0866c 614{
fcc85819
CH
615 const struct nfs_readlinkargs *args = data;
616
9f06c719 617 encode_fhandle(xdr, args->fh);
25a0866c
CL
618 prepare_reply_buffer(req, args->pages, args->pgbase,
619 args->pglen, NFS_readlinkres_sz);
25a0866c
CL
620}
621
25a0866c
CL
622/*
623 * 2.2.7. readargs
624 *
625 * struct readargs {
626 * fhandle file;
627 * unsigned offset;
628 * unsigned count;
629 * unsigned totalcount;
630 * };
631 */
632static void encode_readargs(struct xdr_stream *xdr,
3c6b899c 633 const struct nfs_pgio_args *args)
25a0866c
CL
634{
635 u32 offset = args->offset;
636 u32 count = args->count;
637 __be32 *p;
638
639 encode_fhandle(xdr, args->fh);
640
641 p = xdr_reserve_space(xdr, 4 + 4 + 4);
642 *p++ = cpu_to_be32(offset);
643 *p++ = cpu_to_be32(count);
644 *p = cpu_to_be32(count);
645}
646
9f06c719
CL
647static void nfs2_xdr_enc_readargs(struct rpc_rqst *req,
648 struct xdr_stream *xdr,
fcc85819 649 const void *data)
25a0866c 650{
fcc85819
CH
651 const struct nfs_pgio_args *args = data;
652
9f06c719 653 encode_readargs(xdr, args);
25a0866c
CL
654 prepare_reply_buffer(req, args->pages, args->pgbase,
655 args->count, NFS_readres_sz);
656 req->rq_rcv_buf.flags |= XDRBUF_READ;
25a0866c
CL
657}
658
25a0866c
CL
659/*
660 * 2.2.9. writeargs
661 *
662 * struct writeargs {
663 * fhandle file;
664 * unsigned beginoffset;
665 * unsigned offset;
666 * unsigned totalcount;
667 * nfsdata data;
668 * };
669 */
670static void encode_writeargs(struct xdr_stream *xdr,
3c6b899c 671 const struct nfs_pgio_args *args)
25a0866c
CL
672{
673 u32 offset = args->offset;
674 u32 count = args->count;
675 __be32 *p;
676
677 encode_fhandle(xdr, args->fh);
678
679 p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4);
680 *p++ = cpu_to_be32(offset);
681 *p++ = cpu_to_be32(offset);
682 *p++ = cpu_to_be32(count);
683
684 /* nfsdata */
685 *p = cpu_to_be32(count);
686 xdr_write_pages(xdr, args->pages, args->pgbase, count);
687}
688
9f06c719
CL
689static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req,
690 struct xdr_stream *xdr,
fcc85819 691 const void *data)
25a0866c 692{
fcc85819
CH
693 const struct nfs_pgio_args *args = data;
694
9f06c719
CL
695 encode_writeargs(xdr, args);
696 xdr->buf->flags |= XDRBUF_WRITE;
25a0866c
CL
697}
698
25a0866c
CL
699/*
700 * 2.2.10. createargs
701 *
702 * struct createargs {
703 * diropargs where;
704 * sattr attributes;
705 * };
706 */
9f06c719
CL
707static void nfs2_xdr_enc_createargs(struct rpc_rqst *req,
708 struct xdr_stream *xdr,
fcc85819 709 const void *data)
25a0866c 710{
fcc85819
CH
711 const struct nfs_createargs *args = data;
712
9f06c719
CL
713 encode_diropargs(xdr, args->fh, args->name, args->len);
714 encode_sattr(xdr, args->sattr);
25a0866c
CL
715}
716
9f06c719
CL
717static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req,
718 struct xdr_stream *xdr,
fcc85819 719 const void *data)
25a0866c 720{
fcc85819
CH
721 const struct nfs_removeargs *args = data;
722
9f06c719 723 encode_diropargs(xdr, args->fh, args->name.name, args->name.len);
25a0866c
CL
724}
725
25a0866c
CL
726/*
727 * 2.2.12. renameargs
728 *
729 * struct renameargs {
730 * diropargs from;
731 * diropargs to;
732 * };
733 */
9f06c719
CL
734static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req,
735 struct xdr_stream *xdr,
fcc85819 736 const void *data)
25a0866c 737{
fcc85819 738 const struct nfs_renameargs *args = data;
25a0866c
CL
739 const struct qstr *old = args->old_name;
740 const struct qstr *new = args->new_name;
25a0866c 741
9f06c719
CL
742 encode_diropargs(xdr, args->old_dir, old->name, old->len);
743 encode_diropargs(xdr, args->new_dir, new->name, new->len);
25a0866c
CL
744}
745
25a0866c
CL
746/*
747 * 2.2.13. linkargs
748 *
749 * struct linkargs {
750 * fhandle from;
751 * diropargs to;
752 * };
753 */
9f06c719
CL
754static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req,
755 struct xdr_stream *xdr,
fcc85819 756 const void *data)
25a0866c 757{
fcc85819
CH
758 const struct nfs_linkargs *args = data;
759
9f06c719
CL
760 encode_fhandle(xdr, args->fromfh);
761 encode_diropargs(xdr, args->tofh, args->toname, args->tolen);
25a0866c
CL
762}
763
25a0866c
CL
764/*
765 * 2.2.14. symlinkargs
766 *
767 * struct symlinkargs {
768 * diropargs from;
769 * path to;
770 * sattr attributes;
771 * };
772 */
9f06c719
CL
773static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req,
774 struct xdr_stream *xdr,
fcc85819 775 const void *data)
25a0866c 776{
fcc85819
CH
777 const struct nfs_symlinkargs *args = data;
778
9f06c719
CL
779 encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen);
780 encode_path(xdr, args->pages, args->pathlen);
781 encode_sattr(xdr, args->sattr);
25a0866c
CL
782}
783
25a0866c
CL
784/*
785 * 2.2.17. readdirargs
786 *
787 * struct readdirargs {
788 * fhandle dir;
789 * nfscookie cookie;
790 * unsigned count;
791 * };
792 */
793static void encode_readdirargs(struct xdr_stream *xdr,
794 const struct nfs_readdirargs *args)
795{
796 __be32 *p;
797
798 encode_fhandle(xdr, args->fh);
799
800 p = xdr_reserve_space(xdr, 4 + 4);
801 *p++ = cpu_to_be32(args->cookie);
802 *p = cpu_to_be32(args->count);
803}
804
9f06c719
CL
805static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req,
806 struct xdr_stream *xdr,
fcc85819 807 const void *data)
25a0866c 808{
fcc85819
CH
809 const struct nfs_readdirargs *args = data;
810
9f06c719 811 encode_readdirargs(xdr, args);
25a0866c
CL
812 prepare_reply_buffer(req, args->pages, 0,
813 args->count, NFS_readdirres_sz);
25a0866c
CL
814}
815
1da177e4 816/*
661ad423
CL
817 * NFSv2 XDR decode functions
818 *
819 * NFSv2 result types are defined in section 2.2 of RFC 1094:
820 * "NFS: Network File System Protocol Specification".
1da177e4 821 */
1da177e4 822
bf269551 823static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr,
f796f8b3
CL
824 void *__unused)
825{
f796f8b3
CL
826 enum nfs_stat status;
827 int error;
828
bf269551 829 error = decode_stat(xdr, &status);
f796f8b3
CL
830 if (unlikely(error))
831 goto out;
832 if (status != NFS_OK)
833 goto out_default;
834out:
835 return error;
836out_default:
837 return nfs_stat_to_errno(status);
838}
839
bf269551 840static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr,
fc016483 841 void *result)
f796f8b3 842{
aabff4dd 843 return decode_attrstat(xdr, result, NULL);
f796f8b3
CL
844}
845
bf269551 846static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr,
fc016483 847 void *result)
f796f8b3 848{
bf269551 849 return decode_diropres(xdr, result);
f796f8b3
CL
850}
851
f796f8b3
CL
852/*
853 * 2.2.6. readlinkres
854 *
855 * union readlinkres switch (stat status) {
856 * case NFS_OK:
857 * path data;
858 * default:
859 * void;
860 * };
861 */
bf269551
CL
862static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req,
863 struct xdr_stream *xdr, void *__unused)
f796f8b3 864{
f796f8b3
CL
865 enum nfs_stat status;
866 int error;
867
bf269551 868 error = decode_stat(xdr, &status);
f796f8b3
CL
869 if (unlikely(error))
870 goto out;
871 if (status != NFS_OK)
872 goto out_default;
bf269551 873 error = decode_path(xdr);
f796f8b3
CL
874out:
875 return error;
876out_default:
877 return nfs_stat_to_errno(status);
878}
879
880/*
881 * 2.2.7. readres
882 *
883 * union readres switch (stat status) {
884 * case NFS_OK:
885 * fattr attributes;
886 * nfsdata data;
887 * default:
888 * void;
889 * };
890 */
bf269551 891static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr,
fc016483 892 void *data)
f796f8b3 893{
fc016483 894 struct nfs_pgio_res *result = data;
f796f8b3
CL
895 enum nfs_stat status;
896 int error;
897
bf269551 898 error = decode_stat(xdr, &status);
f796f8b3
CL
899 if (unlikely(error))
900 goto out;
aabff4dd 901 result->op_status = status;
f796f8b3
CL
902 if (status != NFS_OK)
903 goto out_default;
bf269551 904 error = decode_fattr(xdr, result->fattr);
f796f8b3
CL
905 if (unlikely(error))
906 goto out;
bf269551 907 error = decode_nfsdata(xdr, result);
f796f8b3
CL
908out:
909 return error;
910out_default:
911 return nfs_stat_to_errno(status);
912}
913
bf269551 914static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr,
fc016483 915 void *data)
f796f8b3 916{
fc016483
CH
917 struct nfs_pgio_res *result = data;
918
f796f8b3
CL
919 /* All NFSv2 writes are "file sync" writes */
920 result->verf->committed = NFS_FILE_SYNC;
aabff4dd 921 return decode_attrstat(xdr, result->fattr, &result->op_status);
f796f8b3
CL
922}
923
924/**
925 * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in
926 * the local page cache.
927 * @xdr: XDR stream where entry resides
928 * @entry: buffer to fill in with entry data
f796f8b3
CL
929 * @plus: boolean indicating whether this should be a readdirplus entry
930 *
573c4e1e
CL
931 * Returns zero if successful, otherwise a negative errno value is
932 * returned.
f796f8b3
CL
933 *
934 * This function is not invoked during READDIR reply decoding, but
935 * rather whenever an application invokes the getdents(2) system call
936 * on a directory already in our cache.
937 *
938 * 2.2.17. entry
939 *
940 * struct entry {
941 * unsigned fileid;
942 * filename name;
943 * nfscookie cookie;
944 * entry *nextentry;
945 * };
946 */
573c4e1e 947int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
a7a3b1e9 948 bool plus)
f796f8b3
CL
949{
950 __be32 *p;
951 int error;
952
953 p = xdr_inline_decode(xdr, 4);
954 if (unlikely(p == NULL))
955 goto out_overflow;
956 if (*p++ == xdr_zero) {
957 p = xdr_inline_decode(xdr, 4);
958 if (unlikely(p == NULL))
959 goto out_overflow;
960 if (*p++ == xdr_zero)
573c4e1e 961 return -EAGAIN;
f796f8b3 962 entry->eof = 1;
573c4e1e 963 return -EBADCOOKIE;
f796f8b3
CL
964 }
965
966 p = xdr_inline_decode(xdr, 4);
967 if (unlikely(p == NULL))
968 goto out_overflow;
969 entry->ino = be32_to_cpup(p);
970
971 error = decode_filename_inline(xdr, &entry->name, &entry->len);
972 if (unlikely(error))
573c4e1e 973 return error;
f796f8b3
CL
974
975 /*
976 * The type (size and byte order) of nfscookie isn't defined in
977 * RFC 1094. This implementation assumes that it's an XDR uint32.
978 */
979 entry->prev_cookie = entry->cookie;
980 p = xdr_inline_decode(xdr, 4);
981 if (unlikely(p == NULL))
982 goto out_overflow;
983 entry->cookie = be32_to_cpup(p);
984
985 entry->d_type = DT_UNKNOWN;
986
573c4e1e 987 return 0;
f796f8b3
CL
988
989out_overflow:
990 print_overflow_msg(__func__, xdr);
573c4e1e 991 return -EAGAIN;
f796f8b3
CL
992}
993
994/*
995 * 2.2.17. readdirres
996 *
997 * union readdirres switch (stat status) {
998 * case NFS_OK:
999 * struct {
1000 * entry *entries;
1001 * bool eof;
1002 * } readdirok;
1003 * default:
1004 * void;
1005 * };
1006 *
1007 * Read the directory contents into the page cache, but don't
1008 * touch them. The actual decoding is done by nfs2_decode_dirent()
1009 * during subsequent nfs_readdir() calls.
1010 */
1011static int decode_readdirok(struct xdr_stream *xdr)
1012{
64bd577e 1013 return xdr_read_pages(xdr, xdr->buf->page_len);
f796f8b3
CL
1014}
1015
bf269551
CL
1016static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req,
1017 struct xdr_stream *xdr, void *__unused)
f796f8b3 1018{
f796f8b3
CL
1019 enum nfs_stat status;
1020 int error;
1021
bf269551 1022 error = decode_stat(xdr, &status);
f796f8b3
CL
1023 if (unlikely(error))
1024 goto out;
1025 if (status != NFS_OK)
1026 goto out_default;
bf269551 1027 error = decode_readdirok(xdr);
f796f8b3
CL
1028out:
1029 return error;
1030out_default:
1031 return nfs_stat_to_errno(status);
1032}
1033
f796f8b3
CL
1034/*
1035 * 2.2.18. statfsres
1036 *
1037 * union statfsres (stat status) {
1038 * case NFS_OK:
1039 * struct {
1040 * unsigned tsize;
1041 * unsigned bsize;
1042 * unsigned blocks;
1043 * unsigned bfree;
1044 * unsigned bavail;
1045 * } info;
1046 * default:
1047 * void;
1048 * };
1049 */
1050static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result)
1051{
1052 __be32 *p;
1053
1054 p = xdr_inline_decode(xdr, NFS_info_sz << 2);
1055 if (unlikely(p == NULL))
1056 goto out_overflow;
1057 result->tsize = be32_to_cpup(p++);
1058 result->bsize = be32_to_cpup(p++);
1059 result->blocks = be32_to_cpup(p++);
1060 result->bfree = be32_to_cpup(p++);
1061 result->bavail = be32_to_cpup(p);
1062 return 0;
1063out_overflow:
1064 print_overflow_msg(__func__, xdr);
1065 return -EIO;
1066}
1067
bf269551 1068static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr,
fc016483 1069 void *result)
f796f8b3 1070{
f796f8b3
CL
1071 enum nfs_stat status;
1072 int error;
1073
bf269551 1074 error = decode_stat(xdr, &status);
f796f8b3
CL
1075 if (unlikely(error))
1076 goto out;
1077 if (status != NFS_OK)
1078 goto out_default;
bf269551 1079 error = decode_info(xdr, result);
f796f8b3
CL
1080out:
1081 return error;
1082out_default:
1083 return nfs_stat_to_errno(status);
1084}
1085
1086
1da177e4
LT
1087/*
1088 * We need to translate between nfs status return values and
1089 * the local errno values which may not be the same.
1090 */
85828493 1091static const struct {
1da177e4
LT
1092 int stat;
1093 int errno;
1094} nfs_errtbl[] = {
1095 { NFS_OK, 0 },
856dff3d
BH
1096 { NFSERR_PERM, -EPERM },
1097 { NFSERR_NOENT, -ENOENT },
1098 { NFSERR_IO, -errno_NFSERR_IO},
1099 { NFSERR_NXIO, -ENXIO },
1100/* { NFSERR_EAGAIN, -EAGAIN }, */
1101 { NFSERR_ACCES, -EACCES },
1102 { NFSERR_EXIST, -EEXIST },
1103 { NFSERR_XDEV, -EXDEV },
1104 { NFSERR_NODEV, -ENODEV },
1105 { NFSERR_NOTDIR, -ENOTDIR },
1106 { NFSERR_ISDIR, -EISDIR },
1107 { NFSERR_INVAL, -EINVAL },
1108 { NFSERR_FBIG, -EFBIG },
1109 { NFSERR_NOSPC, -ENOSPC },
1110 { NFSERR_ROFS, -EROFS },
1111 { NFSERR_MLINK, -EMLINK },
1112 { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
1113 { NFSERR_NOTEMPTY, -ENOTEMPTY },
1114 { NFSERR_DQUOT, -EDQUOT },
1115 { NFSERR_STALE, -ESTALE },
1116 { NFSERR_REMOTE, -EREMOTE },
1da177e4 1117#ifdef EWFLUSH
856dff3d 1118 { NFSERR_WFLUSH, -EWFLUSH },
1da177e4 1119#endif
856dff3d
BH
1120 { NFSERR_BADHANDLE, -EBADHANDLE },
1121 { NFSERR_NOT_SYNC, -ENOTSYNC },
1122 { NFSERR_BAD_COOKIE, -EBADCOOKIE },
1123 { NFSERR_NOTSUPP, -ENOTSUPP },
1124 { NFSERR_TOOSMALL, -ETOOSMALL },
fdcb4577 1125 { NFSERR_SERVERFAULT, -EREMOTEIO },
856dff3d
BH
1126 { NFSERR_BADTYPE, -EBADTYPE },
1127 { NFSERR_JUKEBOX, -EJUKEBOX },
1128 { -1, -EIO }
1da177e4
LT
1129};
1130
85828493
CL
1131/**
1132 * nfs_stat_to_errno - convert an NFS status code to a local errno
1133 * @status: NFS status code to convert
1134 *
1135 * Returns a local errno value, or -EIO if the NFS status code is
1136 * not recognized. This function is used jointly by NFSv2 and NFSv3.
1da177e4 1137 */
5e7e5a0d 1138static int nfs_stat_to_errno(enum nfs_stat status)
1da177e4
LT
1139{
1140 int i;
1141
1142 for (i = 0; nfs_errtbl[i].stat != -1; i++) {
85828493 1143 if (nfs_errtbl[i].stat == (int)status)
1da177e4
LT
1144 return nfs_errtbl[i].errno;
1145 }
85828493 1146 dprintk("NFS: Unrecognized nfs status value: %u\n", status);
1da177e4
LT
1147 return nfs_errtbl[i].errno;
1148}
1149
1da177e4
LT
1150#define PROC(proc, argtype, restype, timer) \
1151[NFSPROC_##proc] = { \
1152 .p_proc = NFSPROC_##proc, \
fcc85819 1153 .p_encode = nfs2_xdr_enc_##argtype, \
fc016483 1154 .p_decode = nfs2_xdr_dec_##restype, \
2bea90d4
CL
1155 .p_arglen = NFS_##argtype##_sz, \
1156 .p_replen = NFS_##restype##_sz, \
cc0175c1
CL
1157 .p_timer = timer, \
1158 .p_statidx = NFSPROC_##proc, \
1159 .p_name = #proc, \
1da177e4 1160 }
511e936b 1161const struct rpc_procinfo nfs_procedures[] = {
7d93bd71
CL
1162 PROC(GETATTR, fhandle, attrstat, 1),
1163 PROC(SETATTR, sattrargs, attrstat, 0),
1164 PROC(LOOKUP, diropargs, diropres, 2),
1165 PROC(READLINK, readlinkargs, readlinkres, 3),
1166 PROC(READ, readargs, readres, 3),
1167 PROC(WRITE, writeargs, writeres, 4),
1168 PROC(CREATE, createargs, diropres, 0),
1169 PROC(REMOVE, removeargs, stat, 0),
1170 PROC(RENAME, renameargs, stat, 0),
1171 PROC(LINK, linkargs, stat, 0),
1172 PROC(SYMLINK, symlinkargs, stat, 0),
1173 PROC(MKDIR, createargs, diropres, 0),
1174 PROC(RMDIR, diropargs, stat, 0),
1175 PROC(READDIR, readdirargs, readdirres, 3),
1176 PROC(STATFS, fhandle, statfsres, 0),
1da177e4
LT
1177};
1178
c551858a 1179static unsigned int nfs_version2_counts[ARRAY_SIZE(nfs_procedures)];
a613fa16 1180const struct rpc_version nfs_version2 = {
1da177e4 1181 .number = 2,
e8c96f8c 1182 .nrprocs = ARRAY_SIZE(nfs_procedures),
c551858a
CH
1183 .procs = nfs_procedures,
1184 .counts = nfs_version2_counts,
1da177e4 1185};