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