~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/nfs/nfs2xdr.c

Version: ~ [ linux-5.11 ] ~ [ linux-5.10.17 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.99 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.176 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.221 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.257 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.257 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp