LCOV - code coverage report
Current view: top level - fs/nfs - nfs2xdr.c (source / functions) Hit Total Coverage
Test: Real Lines: 0 285 0.0 %
Date: 2020-10-17 15:46:16 Functions: 0 38 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

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

Generated by: LCOV version 1.14