linux/fs/nfs/nfs4xdr.c
<<
>>
Prefs
   1/*
   2 *  fs/nfs/nfs4xdr.c
   3 *
   4 *  Client-side XDR for NFSv4.
   5 *
   6 *  Copyright (c) 2002 The Regents of the University of Michigan.
   7 *  All rights reserved.
   8 *
   9 *  Kendrick Smith <kmsmith@umich.edu>
  10 *  Andy Adamson   <andros@umich.edu>
  11 * 
  12 *  Redistribution and use in source and binary forms, with or without
  13 *  modification, are permitted provided that the following conditions
  14 *  are met:
  15 *
  16 *  1. Redistributions of source code must retain the above copyright
  17 *     notice, this list of conditions and the following disclaimer.
  18 *  2. Redistributions in binary form must reproduce the above copyright
  19 *     notice, this list of conditions and the following disclaimer in the
  20 *     documentation and/or other materials provided with the distribution.
  21 *  3. Neither the name of the University nor the names of its
  22 *     contributors may be used to endorse or promote products derived
  23 *     from this software without specific prior written permission.
  24 *
  25 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  26 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  27 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28 *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29 *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  30 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  32 *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  33 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  34 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36 */
  37
  38#include <linux/param.h>
  39#include <linux/time.h>
  40#include <linux/mm.h>
  41#include <linux/slab.h>
  42#include <linux/utsname.h>
  43#include <linux/errno.h>
  44#include <linux/string.h>
  45#include <linux/in.h>
  46#include <linux/pagemap.h>
  47#include <linux/proc_fs.h>
  48#include <linux/kdev_t.h>
  49#include <linux/sunrpc/clnt.h>
  50#include <linux/nfs.h>
  51#include <linux/nfs4.h>
  52#include <linux/nfs_fs.h>
  53#include <linux/nfs_idmap.h>
  54#include "nfs4_fs.h"
  55
  56#define NFSDBG_FACILITY         NFSDBG_XDR
  57
  58/* Mapping from NFS error code to "errno" error code. */
  59#define errno_NFSERR_IO         EIO
  60
  61static int nfs4_stat_to_errno(int);
  62
  63/* NFSv4 COMPOUND tags are only wanted for debugging purposes */
  64#ifdef DEBUG
  65#define NFS4_MAXTAGLEN          20
  66#else
  67#define NFS4_MAXTAGLEN          0
  68#endif
  69
  70/* lock,open owner id: 
  71 * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT  >> 2)
  72 */
  73#define open_owner_id_maxsz     (1 + 4)
  74#define lock_owner_id_maxsz     (1 + 4)
  75#define decode_lockowner_maxsz  (1 + XDR_QUADLEN(IDMAP_NAMESZ))
  76#define compound_encode_hdr_maxsz       (3 + (NFS4_MAXTAGLEN >> 2))
  77#define compound_decode_hdr_maxsz       (3 + (NFS4_MAXTAGLEN >> 2))
  78#define op_encode_hdr_maxsz     (1)
  79#define op_decode_hdr_maxsz     (2)
  80#define encode_stateid_maxsz    (XDR_QUADLEN(NFS4_STATEID_SIZE))
  81#define decode_stateid_maxsz    (XDR_QUADLEN(NFS4_STATEID_SIZE))
  82#define encode_verifier_maxsz   (XDR_QUADLEN(NFS4_VERIFIER_SIZE))
  83#define decode_verifier_maxsz   (XDR_QUADLEN(NFS4_VERIFIER_SIZE))
  84#define encode_putfh_maxsz      (op_encode_hdr_maxsz + 1 + \
  85                                (NFS4_FHSIZE >> 2))
  86#define decode_putfh_maxsz      (op_decode_hdr_maxsz)
  87#define encode_putrootfh_maxsz  (op_encode_hdr_maxsz)
  88#define decode_putrootfh_maxsz  (op_decode_hdr_maxsz)
  89#define encode_getfh_maxsz      (op_encode_hdr_maxsz)
  90#define decode_getfh_maxsz      (op_decode_hdr_maxsz + 1 + \
  91                                ((3+NFS4_FHSIZE) >> 2))
  92#define nfs4_fattr_bitmap_maxsz 3
  93#define encode_getattr_maxsz    (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz)
  94#define nfs4_name_maxsz         (1 + ((3 + NFS4_MAXNAMLEN) >> 2))
  95#define nfs4_path_maxsz         (1 + ((3 + NFS4_MAXPATHLEN) >> 2))
  96#define nfs4_owner_maxsz        (1 + XDR_QUADLEN(IDMAP_NAMESZ))
  97#define nfs4_group_maxsz        (1 + XDR_QUADLEN(IDMAP_NAMESZ))
  98/* This is based on getfattr, which uses the most attributes: */
  99#define nfs4_fattr_value_maxsz  (1 + (1 + 2 + 2 + 4 + 2 + 1 + 1 + 2 + 2 + \
 100                                3 + 3 + 3 + nfs4_owner_maxsz + nfs4_group_maxsz))
 101#define nfs4_fattr_maxsz        (nfs4_fattr_bitmap_maxsz + \
 102                                nfs4_fattr_value_maxsz)
 103#define decode_getattr_maxsz    (op_decode_hdr_maxsz + nfs4_fattr_maxsz)
 104#define encode_attrs_maxsz      (nfs4_fattr_bitmap_maxsz + \
 105                                 1 + 2 + 1 + \
 106                                nfs4_owner_maxsz + \
 107                                nfs4_group_maxsz + \
 108                                4 + 4)
 109#define encode_savefh_maxsz     (op_encode_hdr_maxsz)
 110#define decode_savefh_maxsz     (op_decode_hdr_maxsz)
 111#define encode_restorefh_maxsz  (op_encode_hdr_maxsz)
 112#define decode_restorefh_maxsz  (op_decode_hdr_maxsz)
 113#define encode_fsinfo_maxsz     (encode_getattr_maxsz)
 114#define decode_fsinfo_maxsz     (op_decode_hdr_maxsz + 11)
 115#define encode_renew_maxsz      (op_encode_hdr_maxsz + 3)
 116#define decode_renew_maxsz      (op_decode_hdr_maxsz)
 117#define encode_setclientid_maxsz \
 118                                (op_encode_hdr_maxsz + \
 119                                XDR_QUADLEN(NFS4_VERIFIER_SIZE) + \
 120                                XDR_QUADLEN(NFS4_SETCLIENTID_NAMELEN) + \
 121                                1 /* sc_prog */ + \
 122                                XDR_QUADLEN(RPCBIND_MAXNETIDLEN) + \
 123                                XDR_QUADLEN(RPCBIND_MAXUADDRLEN) + \
 124                                1) /* sc_cb_ident */
 125#define decode_setclientid_maxsz \
 126                                (op_decode_hdr_maxsz + \
 127                                2 + \
 128                                1024) /* large value for CLID_INUSE */
 129#define encode_setclientid_confirm_maxsz \
 130                                (op_encode_hdr_maxsz + \
 131                                3 + (NFS4_VERIFIER_SIZE >> 2))
 132#define decode_setclientid_confirm_maxsz \
 133                                (op_decode_hdr_maxsz)
 134#define encode_lookup_maxsz     (op_encode_hdr_maxsz + nfs4_name_maxsz)
 135#define decode_lookup_maxsz     (op_decode_hdr_maxsz)
 136#define encode_share_access_maxsz \
 137                                (2)
 138#define encode_createmode_maxsz (1 + encode_attrs_maxsz)
 139#define encode_opentype_maxsz   (1 + encode_createmode_maxsz)
 140#define encode_claim_null_maxsz (1 + nfs4_name_maxsz)
 141#define encode_open_maxsz       (op_encode_hdr_maxsz + \
 142                                2 + encode_share_access_maxsz + 2 + \
 143                                open_owner_id_maxsz + \
 144                                encode_opentype_maxsz + \
 145                                encode_claim_null_maxsz)
 146#define decode_ace_maxsz        (3 + nfs4_owner_maxsz)
 147#define decode_delegation_maxsz (1 + decode_stateid_maxsz + 1 + \
 148                                decode_ace_maxsz)
 149#define decode_change_info_maxsz        (5)
 150#define decode_open_maxsz       (op_decode_hdr_maxsz + \
 151                                decode_stateid_maxsz + \
 152                                decode_change_info_maxsz + 1 + \
 153                                nfs4_fattr_bitmap_maxsz + \
 154                                decode_delegation_maxsz)
 155#define encode_open_confirm_maxsz \
 156                                (op_encode_hdr_maxsz + \
 157                                 encode_stateid_maxsz + 1)
 158#define decode_open_confirm_maxsz \
 159                                (op_decode_hdr_maxsz + \
 160                                 decode_stateid_maxsz)
 161#define encode_open_downgrade_maxsz \
 162                                (op_encode_hdr_maxsz + \
 163                                 encode_stateid_maxsz + 1 + \
 164                                 encode_share_access_maxsz)
 165#define decode_open_downgrade_maxsz \
 166                                (op_decode_hdr_maxsz + \
 167                                 decode_stateid_maxsz)
 168#define encode_close_maxsz      (op_encode_hdr_maxsz + \
 169                                 1 + encode_stateid_maxsz)
 170#define decode_close_maxsz      (op_decode_hdr_maxsz + \
 171                                 decode_stateid_maxsz)
 172#define encode_setattr_maxsz    (op_encode_hdr_maxsz + \
 173                                 encode_stateid_maxsz + \
 174                                 encode_attrs_maxsz)
 175#define decode_setattr_maxsz    (op_decode_hdr_maxsz + \
 176                                 nfs4_fattr_bitmap_maxsz)
 177#define encode_read_maxsz       (op_encode_hdr_maxsz + \
 178                                 encode_stateid_maxsz + 3)
 179#define decode_read_maxsz       (op_decode_hdr_maxsz + 2)
 180#define encode_readdir_maxsz    (op_encode_hdr_maxsz + \
 181                                 2 + encode_verifier_maxsz + 5)
 182#define decode_readdir_maxsz    (op_decode_hdr_maxsz + \
 183                                 decode_verifier_maxsz)
 184#define encode_readlink_maxsz   (op_encode_hdr_maxsz)
 185#define decode_readlink_maxsz   (op_decode_hdr_maxsz + 1)
 186#define encode_write_maxsz      (op_encode_hdr_maxsz + \
 187                                 encode_stateid_maxsz + 4)
 188#define decode_write_maxsz      (op_decode_hdr_maxsz + \
 189                                 2 + decode_verifier_maxsz)
 190#define encode_commit_maxsz     (op_encode_hdr_maxsz + 3)
 191#define decode_commit_maxsz     (op_decode_hdr_maxsz + \
 192                                 decode_verifier_maxsz)
 193#define encode_remove_maxsz     (op_encode_hdr_maxsz + \
 194                                nfs4_name_maxsz)
 195#define encode_rename_maxsz     (op_encode_hdr_maxsz + \
 196                                2 * nfs4_name_maxsz)
 197#define decode_rename_maxsz     (op_decode_hdr_maxsz + 5 + 5)
 198#define encode_link_maxsz       (op_encode_hdr_maxsz + \
 199                                nfs4_name_maxsz)
 200#define decode_link_maxsz       (op_decode_hdr_maxsz + 5)
 201#define encode_lock_maxsz       (op_encode_hdr_maxsz + \
 202                                 7 + \
 203                                 1 + encode_stateid_maxsz + 8)
 204#define decode_lock_denied_maxsz \
 205                                (8 + decode_lockowner_maxsz)
 206#define decode_lock_maxsz       (op_decode_hdr_maxsz + \
 207                                 decode_lock_denied_maxsz)
 208#define encode_lockt_maxsz      (op_encode_hdr_maxsz + 12)
 209#define decode_lockt_maxsz      (op_decode_hdr_maxsz + \
 210                                 decode_lock_denied_maxsz)
 211#define encode_locku_maxsz      (op_encode_hdr_maxsz + 3 + \
 212                                 encode_stateid_maxsz + \
 213                                 4)
 214#define decode_locku_maxsz      (op_decode_hdr_maxsz + \
 215                                 decode_stateid_maxsz)
 216#define encode_access_maxsz     (op_encode_hdr_maxsz + 1)
 217#define decode_access_maxsz     (op_decode_hdr_maxsz + 2)
 218#define encode_symlink_maxsz    (op_encode_hdr_maxsz + \
 219                                1 + nfs4_name_maxsz + \
 220                                1 + \
 221                                nfs4_fattr_maxsz)
 222#define decode_symlink_maxsz    (op_decode_hdr_maxsz + 8)
 223#define encode_create_maxsz     (op_encode_hdr_maxsz + \
 224                                1 + 2 + nfs4_name_maxsz + \
 225                                encode_attrs_maxsz)
 226#define decode_create_maxsz     (op_decode_hdr_maxsz + \
 227                                decode_change_info_maxsz + \
 228                                nfs4_fattr_bitmap_maxsz)
 229#define encode_statfs_maxsz     (encode_getattr_maxsz)
 230#define decode_statfs_maxsz     (decode_getattr_maxsz)
 231#define encode_delegreturn_maxsz (op_encode_hdr_maxsz + 4)
 232#define decode_delegreturn_maxsz (op_decode_hdr_maxsz)
 233#define encode_getacl_maxsz     (encode_getattr_maxsz)
 234#define decode_getacl_maxsz     (op_decode_hdr_maxsz + \
 235                                 nfs4_fattr_bitmap_maxsz + 1)
 236#define encode_setacl_maxsz     (op_encode_hdr_maxsz + \
 237                                 encode_stateid_maxsz + 3)
 238#define decode_setacl_maxsz     (decode_setattr_maxsz)
 239#define encode_fs_locations_maxsz \
 240                                (encode_getattr_maxsz)
 241#define decode_fs_locations_maxsz \
 242                                (0)
 243#define NFS4_enc_compound_sz    (1024)  /* XXX: large enough? */
 244#define NFS4_dec_compound_sz    (1024)  /* XXX: large enough? */
 245#define NFS4_enc_read_sz        (compound_encode_hdr_maxsz + \
 246                                encode_putfh_maxsz + \
 247                                encode_read_maxsz)
 248#define NFS4_dec_read_sz        (compound_decode_hdr_maxsz + \
 249                                decode_putfh_maxsz + \
 250                                decode_read_maxsz)
 251#define NFS4_enc_readlink_sz    (compound_encode_hdr_maxsz + \
 252                                encode_putfh_maxsz + \
 253                                encode_readlink_maxsz)
 254#define NFS4_dec_readlink_sz    (compound_decode_hdr_maxsz + \
 255                                decode_putfh_maxsz + \
 256                                decode_readlink_maxsz)
 257#define NFS4_enc_readdir_sz     (compound_encode_hdr_maxsz + \
 258                                encode_putfh_maxsz + \
 259                                encode_readdir_maxsz)
 260#define NFS4_dec_readdir_sz     (compound_decode_hdr_maxsz + \
 261                                decode_putfh_maxsz + \
 262                                decode_readdir_maxsz)
 263#define NFS4_enc_write_sz       (compound_encode_hdr_maxsz + \
 264                                encode_putfh_maxsz + \
 265                                encode_write_maxsz + \
 266                                encode_getattr_maxsz)
 267#define NFS4_dec_write_sz       (compound_decode_hdr_maxsz + \
 268                                decode_putfh_maxsz + \
 269                                decode_write_maxsz + \
 270                                decode_getattr_maxsz)
 271#define NFS4_enc_commit_sz      (compound_encode_hdr_maxsz + \
 272                                encode_putfh_maxsz + \
 273                                encode_commit_maxsz + \
 274                                encode_getattr_maxsz)
 275#define NFS4_dec_commit_sz      (compound_decode_hdr_maxsz + \
 276                                decode_putfh_maxsz + \
 277                                decode_commit_maxsz + \
 278                                decode_getattr_maxsz)
 279#define NFS4_enc_open_sz        (compound_encode_hdr_maxsz + \
 280                                encode_putfh_maxsz + \
 281                                encode_savefh_maxsz + \
 282                                encode_open_maxsz + \
 283                                encode_getfh_maxsz + \
 284                                encode_getattr_maxsz + \
 285                                encode_restorefh_maxsz + \
 286                                encode_getattr_maxsz)
 287#define NFS4_dec_open_sz        (compound_decode_hdr_maxsz + \
 288                                decode_putfh_maxsz + \
 289                                decode_savefh_maxsz + \
 290                                decode_open_maxsz + \
 291                                decode_getfh_maxsz + \
 292                                decode_getattr_maxsz + \
 293                                decode_restorefh_maxsz + \
 294                                decode_getattr_maxsz)
 295#define NFS4_enc_open_confirm_sz \
 296                                (compound_encode_hdr_maxsz + \
 297                                 encode_putfh_maxsz + \
 298                                 encode_open_confirm_maxsz)
 299#define NFS4_dec_open_confirm_sz \
 300                                (compound_decode_hdr_maxsz + \
 301                                 decode_putfh_maxsz + \
 302                                 decode_open_confirm_maxsz)
 303#define NFS4_enc_open_noattr_sz (compound_encode_hdr_maxsz + \
 304                                        encode_putfh_maxsz + \
 305                                        encode_open_maxsz + \
 306                                        encode_getattr_maxsz)
 307#define NFS4_dec_open_noattr_sz (compound_decode_hdr_maxsz + \
 308                                        decode_putfh_maxsz + \
 309                                        decode_open_maxsz + \
 310                                        decode_getattr_maxsz)
 311#define NFS4_enc_open_downgrade_sz \
 312                                (compound_encode_hdr_maxsz + \
 313                                 encode_putfh_maxsz + \
 314                                 encode_open_downgrade_maxsz + \
 315                                 encode_getattr_maxsz)
 316#define NFS4_dec_open_downgrade_sz \
 317                                (compound_decode_hdr_maxsz + \
 318                                 decode_putfh_maxsz + \
 319                                 decode_open_downgrade_maxsz + \
 320                                 decode_getattr_maxsz)
 321#define NFS4_enc_close_sz       (compound_encode_hdr_maxsz + \
 322                                 encode_putfh_maxsz + \
 323                                 encode_close_maxsz + \
 324                                 encode_getattr_maxsz)
 325#define NFS4_dec_close_sz       (compound_decode_hdr_maxsz + \
 326                                 decode_putfh_maxsz + \
 327                                 decode_close_maxsz + \
 328                                 decode_getattr_maxsz)
 329#define NFS4_enc_setattr_sz     (compound_encode_hdr_maxsz + \
 330                                 encode_putfh_maxsz + \
 331                                 encode_setattr_maxsz + \
 332                                 encode_getattr_maxsz)
 333#define NFS4_dec_setattr_sz     (compound_decode_hdr_maxsz + \
 334                                 decode_putfh_maxsz + \
 335                                 decode_setattr_maxsz + \
 336                                 decode_getattr_maxsz)
 337#define NFS4_enc_fsinfo_sz      (compound_encode_hdr_maxsz + \
 338                                encode_putfh_maxsz + \
 339                                encode_fsinfo_maxsz)
 340#define NFS4_dec_fsinfo_sz      (compound_decode_hdr_maxsz + \
 341                                decode_putfh_maxsz + \
 342                                decode_fsinfo_maxsz)
 343#define NFS4_enc_renew_sz       (compound_encode_hdr_maxsz + \
 344                                encode_renew_maxsz)
 345#define NFS4_dec_renew_sz       (compound_decode_hdr_maxsz + \
 346                                decode_renew_maxsz)
 347#define NFS4_enc_setclientid_sz (compound_encode_hdr_maxsz + \
 348                                encode_setclientid_maxsz)
 349#define NFS4_dec_setclientid_sz (compound_decode_hdr_maxsz + \
 350                                decode_setclientid_maxsz)
 351#define NFS4_enc_setclientid_confirm_sz \
 352                                (compound_encode_hdr_maxsz + \
 353                                encode_setclientid_confirm_maxsz + \
 354                                encode_putrootfh_maxsz + \
 355                                encode_fsinfo_maxsz)
 356#define NFS4_dec_setclientid_confirm_sz \
 357                                (compound_decode_hdr_maxsz + \
 358                                decode_setclientid_confirm_maxsz + \
 359                                decode_putrootfh_maxsz + \
 360                                decode_fsinfo_maxsz)
 361#define NFS4_enc_lock_sz        (compound_encode_hdr_maxsz + \
 362                                encode_putfh_maxsz + \
 363                                encode_lock_maxsz)
 364#define NFS4_dec_lock_sz        (compound_decode_hdr_maxsz + \
 365                                decode_putfh_maxsz + \
 366                                decode_lock_maxsz)
 367#define NFS4_enc_lockt_sz       (compound_encode_hdr_maxsz + \
 368                                encode_putfh_maxsz + \
 369                                encode_lockt_maxsz)
 370#define NFS4_dec_lockt_sz       (compound_decode_hdr_maxsz + \
 371                                 decode_putfh_maxsz + \
 372                                 decode_lockt_maxsz)
 373#define NFS4_enc_locku_sz       (compound_encode_hdr_maxsz + \
 374                                encode_putfh_maxsz + \
 375                                encode_locku_maxsz)
 376#define NFS4_dec_locku_sz       (compound_decode_hdr_maxsz + \
 377                                decode_putfh_maxsz + \
 378                                decode_locku_maxsz)
 379#define NFS4_enc_access_sz      (compound_encode_hdr_maxsz + \
 380                                encode_putfh_maxsz + \
 381                                encode_access_maxsz + \
 382                                encode_getattr_maxsz)
 383#define NFS4_dec_access_sz      (compound_decode_hdr_maxsz + \
 384                                decode_putfh_maxsz + \
 385                                decode_access_maxsz + \
 386                                decode_getattr_maxsz)
 387#define NFS4_enc_getattr_sz     (compound_encode_hdr_maxsz + \
 388                                encode_putfh_maxsz + \
 389                                encode_getattr_maxsz)
 390#define NFS4_dec_getattr_sz     (compound_decode_hdr_maxsz + \
 391                                decode_putfh_maxsz + \
 392                                decode_getattr_maxsz)
 393#define NFS4_enc_lookup_sz      (compound_encode_hdr_maxsz + \
 394                                encode_putfh_maxsz + \
 395                                encode_lookup_maxsz + \
 396                                encode_getattr_maxsz + \
 397                                encode_getfh_maxsz)
 398#define NFS4_dec_lookup_sz      (compound_decode_hdr_maxsz + \
 399                                decode_putfh_maxsz + \
 400                                decode_lookup_maxsz + \
 401                                decode_getattr_maxsz + \
 402                                decode_getfh_maxsz)
 403#define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
 404                                encode_putrootfh_maxsz + \
 405                                encode_getattr_maxsz + \
 406                                encode_getfh_maxsz)
 407#define NFS4_dec_lookup_root_sz (compound_decode_hdr_maxsz + \
 408                                decode_putrootfh_maxsz + \
 409                                decode_getattr_maxsz + \
 410                                decode_getfh_maxsz)
 411#define NFS4_enc_remove_sz      (compound_encode_hdr_maxsz + \
 412                                encode_putfh_maxsz + \
 413                                encode_remove_maxsz + \
 414                                encode_getattr_maxsz)
 415#define NFS4_dec_remove_sz      (compound_decode_hdr_maxsz + \
 416                                decode_putfh_maxsz + \
 417                                op_decode_hdr_maxsz + 5 + \
 418                                decode_getattr_maxsz)
 419#define NFS4_enc_rename_sz      (compound_encode_hdr_maxsz + \
 420                                encode_putfh_maxsz + \
 421                                encode_savefh_maxsz + \
 422                                encode_putfh_maxsz + \
 423                                encode_rename_maxsz + \
 424                                encode_getattr_maxsz + \
 425                                encode_restorefh_maxsz + \
 426                                encode_getattr_maxsz)
 427#define NFS4_dec_rename_sz      (compound_decode_hdr_maxsz + \
 428                                decode_putfh_maxsz + \
 429                                decode_savefh_maxsz + \
 430                                decode_putfh_maxsz + \
 431                                decode_rename_maxsz + \
 432                                decode_getattr_maxsz + \
 433                                decode_restorefh_maxsz + \
 434                                decode_getattr_maxsz)
 435#define NFS4_enc_link_sz        (compound_encode_hdr_maxsz + \
 436                                encode_putfh_maxsz + \
 437                                encode_savefh_maxsz + \
 438                                encode_putfh_maxsz + \
 439                                encode_link_maxsz + \
 440                                decode_getattr_maxsz + \
 441                                encode_restorefh_maxsz + \
 442                                decode_getattr_maxsz)
 443#define NFS4_dec_link_sz        (compound_decode_hdr_maxsz + \
 444                                decode_putfh_maxsz + \
 445                                decode_savefh_maxsz + \
 446                                decode_putfh_maxsz + \
 447                                decode_link_maxsz + \
 448                                decode_getattr_maxsz + \
 449                                decode_restorefh_maxsz + \
 450                                decode_getattr_maxsz)
 451#define NFS4_enc_symlink_sz     (compound_encode_hdr_maxsz + \
 452                                encode_putfh_maxsz + \
 453                                encode_symlink_maxsz + \
 454                                encode_getattr_maxsz + \
 455                                encode_getfh_maxsz)
 456#define NFS4_dec_symlink_sz     (compound_decode_hdr_maxsz + \
 457                                decode_putfh_maxsz + \
 458                                decode_symlink_maxsz + \
 459                                decode_getattr_maxsz + \
 460                                decode_getfh_maxsz)
 461#define NFS4_enc_create_sz      (compound_encode_hdr_maxsz + \
 462                                encode_putfh_maxsz + \
 463                                encode_savefh_maxsz + \
 464                                encode_create_maxsz + \
 465                                encode_getfh_maxsz + \
 466                                encode_getattr_maxsz + \
 467                                encode_restorefh_maxsz + \
 468                                encode_getattr_maxsz)
 469#define NFS4_dec_create_sz      (compound_decode_hdr_maxsz + \
 470                                decode_putfh_maxsz + \
 471                                decode_savefh_maxsz + \
 472                                decode_create_maxsz + \
 473                                decode_getfh_maxsz + \
 474                                decode_getattr_maxsz + \
 475                                decode_restorefh_maxsz + \
 476                                decode_getattr_maxsz)
 477#define NFS4_enc_pathconf_sz    (compound_encode_hdr_maxsz + \
 478                                encode_putfh_maxsz + \
 479                                encode_getattr_maxsz)
 480#define NFS4_dec_pathconf_sz    (compound_decode_hdr_maxsz + \
 481                                decode_putfh_maxsz + \
 482                                decode_getattr_maxsz)
 483#define NFS4_enc_statfs_sz      (compound_encode_hdr_maxsz + \
 484                                encode_putfh_maxsz + \
 485                                encode_statfs_maxsz)
 486#define NFS4_dec_statfs_sz      (compound_decode_hdr_maxsz + \
 487                                decode_putfh_maxsz + \
 488                                decode_statfs_maxsz)
 489#define NFS4_enc_server_caps_sz (compound_encode_hdr_maxsz + \
 490                                encode_putfh_maxsz + \
 491                                encode_getattr_maxsz)
 492#define NFS4_dec_server_caps_sz (compound_decode_hdr_maxsz + \
 493                                decode_putfh_maxsz + \
 494                                decode_getattr_maxsz)
 495#define NFS4_enc_delegreturn_sz (compound_encode_hdr_maxsz + \
 496                                encode_putfh_maxsz + \
 497                                encode_delegreturn_maxsz + \
 498                                encode_getattr_maxsz)
 499#define NFS4_dec_delegreturn_sz (compound_decode_hdr_maxsz + \
 500                                decode_delegreturn_maxsz + \
 501                                decode_getattr_maxsz)
 502#define NFS4_enc_getacl_sz      (compound_encode_hdr_maxsz + \
 503                                encode_putfh_maxsz + \
 504                                encode_getacl_maxsz)
 505#define NFS4_dec_getacl_sz      (compound_decode_hdr_maxsz + \
 506                                decode_putfh_maxsz + \
 507                                decode_getacl_maxsz)
 508#define NFS4_enc_setacl_sz      (compound_encode_hdr_maxsz + \
 509                                encode_putfh_maxsz + \
 510                                encode_setacl_maxsz)
 511#define NFS4_dec_setacl_sz      (compound_decode_hdr_maxsz + \
 512                                decode_putfh_maxsz + \
 513                                decode_setacl_maxsz)
 514#define NFS4_enc_fs_locations_sz \
 515                                (compound_encode_hdr_maxsz + \
 516                                 encode_putfh_maxsz + \
 517                                 encode_lookup_maxsz + \
 518                                 encode_fs_locations_maxsz)
 519#define NFS4_dec_fs_locations_sz \
 520                                (compound_decode_hdr_maxsz + \
 521                                 decode_putfh_maxsz + \
 522                                 decode_lookup_maxsz + \
 523                                 decode_fs_locations_maxsz)
 524
 525static struct {
 526        unsigned int    mode;
 527        unsigned int    nfs2type;
 528} nfs_type2fmt[] = {
 529        { 0,            NFNON        },
 530        { S_IFREG,      NFREG        },
 531        { S_IFDIR,      NFDIR        },
 532        { S_IFBLK,      NFBLK        },
 533        { S_IFCHR,      NFCHR        },
 534        { S_IFLNK,      NFLNK        },
 535        { S_IFSOCK,     NFSOCK       },
 536        { S_IFIFO,      NFFIFO       },
 537        { 0,            NFNON        },
 538        { 0,            NFNON        },
 539};
 540
 541struct compound_hdr {
 542        int32_t         status;
 543        uint32_t        nops;
 544        uint32_t        taglen;
 545        char *          tag;
 546};
 547
 548/*
 549 * START OF "GENERIC" ENCODE ROUTINES.
 550 *   These may look a little ugly since they are imported from a "generic"
 551 * set of XDR encode/decode routines which are intended to be shared by
 552 * all of our NFSv4 implementations (OpenBSD, MacOS X...).
 553 *
 554 * If the pain of reading these is too great, it should be a straightforward
 555 * task to translate them into Linux-specific versions which are more
 556 * consistent with the style used in NFSv2/v3...
 557 */
 558#define WRITE32(n)               *p++ = htonl(n)
 559#define WRITE64(n)               do {                           \
 560        *p++ = htonl((uint32_t)((n) >> 32));                            \
 561        *p++ = htonl((uint32_t)(n));                                    \
 562} while (0)
 563#define WRITEMEM(ptr,nbytes)     do {                           \
 564        p = xdr_encode_opaque_fixed(p, ptr, nbytes);            \
 565} while (0)
 566
 567#define RESERVE_SPACE(nbytes)   do {                            \
 568        p = xdr_reserve_space(xdr, nbytes);                     \
 569        BUG_ON(!p);                                             \
 570} while (0)
 571
 572static void encode_string(struct xdr_stream *xdr, unsigned int len, const char *str)
 573{
 574        __be32 *p;
 575
 576        p = xdr_reserve_space(xdr, 4 + len);
 577        BUG_ON(p == NULL);
 578        xdr_encode_opaque(p, str, len);
 579}
 580
 581static int encode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
 582{
 583        __be32 *p;
 584
 585        dprintk("encode_compound: tag=%.*s\n", (int)hdr->taglen, hdr->tag);
 586        BUG_ON(hdr->taglen > NFS4_MAXTAGLEN);
 587        RESERVE_SPACE(12+(XDR_QUADLEN(hdr->taglen)<<2));
 588        WRITE32(hdr->taglen);
 589        WRITEMEM(hdr->tag, hdr->taglen);
 590        WRITE32(NFS4_MINOR_VERSION);
 591        WRITE32(hdr->nops);
 592        return 0;
 593}
 594
 595static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *verf)
 596{
 597        __be32 *p;
 598
 599        p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
 600        BUG_ON(p == NULL);
 601        xdr_encode_opaque_fixed(p, verf->data, NFS4_VERIFIER_SIZE);
 602}
 603
 604static int encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const struct nfs_server *server)
 605{
 606        char owner_name[IDMAP_NAMESZ];
 607        char owner_group[IDMAP_NAMESZ];
 608        int owner_namelen = 0;
 609        int owner_grouplen = 0;
 610        __be32 *p;
 611        __be32 *q;
 612        int len;
 613        uint32_t bmval0 = 0;
 614        uint32_t bmval1 = 0;
 615        int status;
 616
 617        /*
 618         * We reserve enough space to write the entire attribute buffer at once.
 619         * In the worst-case, this would be
 620         *   12(bitmap) + 4(attrlen) + 8(size) + 4(mode) + 4(atime) + 4(mtime)
 621         *          = 36 bytes, plus any contribution from variable-length fields
 622         *            such as owner/group.
 623         */
 624        len = 16;
 625
 626        /* Sigh */
 627        if (iap->ia_valid & ATTR_SIZE)
 628                len += 8;
 629        if (iap->ia_valid & ATTR_MODE)
 630                len += 4;
 631        if (iap->ia_valid & ATTR_UID) {
 632                owner_namelen = nfs_map_uid_to_name(server->nfs_client, iap->ia_uid, owner_name);
 633                if (owner_namelen < 0) {
 634                        dprintk("nfs: couldn't resolve uid %d to string\n",
 635                                        iap->ia_uid);
 636                        /* XXX */
 637                        strcpy(owner_name, "nobody");
 638                        owner_namelen = sizeof("nobody") - 1;
 639                        /* goto out; */
 640                }
 641                len += 4 + (XDR_QUADLEN(owner_namelen) << 2);
 642        }
 643        if (iap->ia_valid & ATTR_GID) {
 644                owner_grouplen = nfs_map_gid_to_group(server->nfs_client, iap->ia_gid, owner_group);
 645                if (owner_grouplen < 0) {
 646                        dprintk("nfs: couldn't resolve gid %d to string\n",
 647                                        iap->ia_gid);
 648                        strcpy(owner_group, "nobody");
 649                        owner_grouplen = sizeof("nobody") - 1;
 650                        /* goto out; */
 651                }
 652                len += 4 + (XDR_QUADLEN(owner_grouplen) << 2);
 653        }
 654        if (iap->ia_valid & ATTR_ATIME_SET)
 655                len += 16;
 656        else if (iap->ia_valid & ATTR_ATIME)
 657                len += 4;
 658        if (iap->ia_valid & ATTR_MTIME_SET)
 659                len += 16;
 660        else if (iap->ia_valid & ATTR_MTIME)
 661                len += 4;
 662        RESERVE_SPACE(len);
 663
 664        /*
 665         * We write the bitmap length now, but leave the bitmap and the attribute
 666         * buffer length to be backfilled at the end of this routine.
 667         */
 668        WRITE32(2);
 669        q = p;
 670        p += 3;
 671
 672        if (iap->ia_valid & ATTR_SIZE) {
 673                bmval0 |= FATTR4_WORD0_SIZE;
 674                WRITE64(iap->ia_size);
 675        }
 676        if (iap->ia_valid & ATTR_MODE) {
 677                bmval1 |= FATTR4_WORD1_MODE;
 678                WRITE32(iap->ia_mode & S_IALLUGO);
 679        }
 680        if (iap->ia_valid & ATTR_UID) {
 681                bmval1 |= FATTR4_WORD1_OWNER;
 682                WRITE32(owner_namelen);
 683                WRITEMEM(owner_name, owner_namelen);
 684        }
 685        if (iap->ia_valid & ATTR_GID) {
 686                bmval1 |= FATTR4_WORD1_OWNER_GROUP;
 687                WRITE32(owner_grouplen);
 688                WRITEMEM(owner_group, owner_grouplen);
 689        }
 690        if (iap->ia_valid & ATTR_ATIME_SET) {
 691                bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
 692                WRITE32(NFS4_SET_TO_CLIENT_TIME);
 693                WRITE32(0);
 694                WRITE32(iap->ia_mtime.tv_sec);
 695                WRITE32(iap->ia_mtime.tv_nsec);
 696        }
 697        else if (iap->ia_valid & ATTR_ATIME) {
 698                bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET;
 699                WRITE32(NFS4_SET_TO_SERVER_TIME);
 700        }
 701        if (iap->ia_valid & ATTR_MTIME_SET) {
 702                bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
 703                WRITE32(NFS4_SET_TO_CLIENT_TIME);
 704                WRITE32(0);
 705                WRITE32(iap->ia_mtime.tv_sec);
 706                WRITE32(iap->ia_mtime.tv_nsec);
 707        }
 708        else if (iap->ia_valid & ATTR_MTIME) {
 709                bmval1 |= FATTR4_WORD1_TIME_MODIFY_SET;
 710                WRITE32(NFS4_SET_TO_SERVER_TIME);
 711        }
 712        
 713        /*
 714         * Now we backfill the bitmap and the attribute buffer length.
 715         */
 716        if (len != ((char *)p - (char *)q) + 4) {
 717                printk(KERN_ERR "nfs: Attr length error, %u != %Zu\n",
 718                                len, ((char *)p - (char *)q) + 4);
 719                BUG();
 720        }
 721        len = (char *)p - (char *)q - 12;
 722        *q++ = htonl(bmval0);
 723        *q++ = htonl(bmval1);
 724        *q++ = htonl(len);
 725
 726        status = 0;
 727/* out: */
 728        return status;
 729}
 730
 731static int encode_access(struct xdr_stream *xdr, u32 access)
 732{
 733        __be32 *p;
 734
 735        RESERVE_SPACE(8);
 736        WRITE32(OP_ACCESS);
 737        WRITE32(access);
 738        
 739        return 0;
 740}
 741
 742static int encode_close(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
 743{
 744        __be32 *p;
 745
 746        RESERVE_SPACE(8+NFS4_STATEID_SIZE);
 747        WRITE32(OP_CLOSE);
 748        WRITE32(arg->seqid->sequence->counter);
 749        WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
 750        
 751        return 0;
 752}
 753
 754static int encode_commit(struct xdr_stream *xdr, const struct nfs_writeargs *args)
 755{
 756        __be32 *p;
 757        
 758        RESERVE_SPACE(16);
 759        WRITE32(OP_COMMIT);
 760        WRITE64(args->offset);
 761        WRITE32(args->count);
 762
 763        return 0;
 764}
 765
 766static int encode_create(struct xdr_stream *xdr, const struct nfs4_create_arg *create)
 767{
 768        __be32 *p;
 769        
 770        RESERVE_SPACE(8);
 771        WRITE32(OP_CREATE);
 772        WRITE32(create->ftype);
 773
 774        switch (create->ftype) {
 775        case NF4LNK:
 776                RESERVE_SPACE(4);
 777                WRITE32(create->u.symlink.len);
 778                xdr_write_pages(xdr, create->u.symlink.pages, 0, create->u.symlink.len);
 779                break;
 780
 781        case NF4BLK: case NF4CHR:
 782                RESERVE_SPACE(8);
 783                WRITE32(create->u.device.specdata1);
 784                WRITE32(create->u.device.specdata2);
 785                break;
 786
 787        default:
 788                break;
 789        }
 790
 791        RESERVE_SPACE(4 + create->name->len);
 792        WRITE32(create->name->len);
 793        WRITEMEM(create->name->name, create->name->len);
 794
 795        return encode_attrs(xdr, create->attrs, create->server);
 796}
 797
 798static int encode_getattr_one(struct xdr_stream *xdr, uint32_t bitmap)
 799{
 800        __be32 *p;
 801
 802        RESERVE_SPACE(12);
 803        WRITE32(OP_GETATTR);
 804        WRITE32(1);
 805        WRITE32(bitmap);
 806        return 0;
 807}
 808
 809static int encode_getattr_two(struct xdr_stream *xdr, uint32_t bm0, uint32_t bm1)
 810{
 811        __be32 *p;
 812
 813        RESERVE_SPACE(16);
 814        WRITE32(OP_GETATTR);
 815        WRITE32(2);
 816        WRITE32(bm0);
 817        WRITE32(bm1);
 818        return 0;
 819}
 820
 821static int encode_getfattr(struct xdr_stream *xdr, const u32* bitmask)
 822{
 823        return encode_getattr_two(xdr,
 824                        bitmask[0] & nfs4_fattr_bitmap[0],
 825                        bitmask[1] & nfs4_fattr_bitmap[1]);
 826}
 827
 828static int encode_fsinfo(struct xdr_stream *xdr, const u32* bitmask)
 829{
 830        return encode_getattr_two(xdr, bitmask[0] & nfs4_fsinfo_bitmap[0],
 831                        bitmask[1] & nfs4_fsinfo_bitmap[1]);
 832}
 833
 834static int encode_fs_locations(struct xdr_stream *xdr, const u32* bitmask)
 835{
 836        return encode_getattr_two(xdr,
 837                                  bitmask[0] & nfs4_fs_locations_bitmap[0],
 838                                  bitmask[1] & nfs4_fs_locations_bitmap[1]);
 839}
 840
 841static int encode_getfh(struct xdr_stream *xdr)
 842{
 843        __be32 *p;
 844
 845        RESERVE_SPACE(4);
 846        WRITE32(OP_GETFH);
 847
 848        return 0;
 849}
 850
 851static int encode_link(struct xdr_stream *xdr, const struct qstr *name)
 852{
 853        __be32 *p;
 854
 855        RESERVE_SPACE(8 + name->len);
 856        WRITE32(OP_LINK);
 857        WRITE32(name->len);
 858        WRITEMEM(name->name, name->len);
 859        
 860        return 0;
 861}
 862
 863static inline int nfs4_lock_type(struct file_lock *fl, int block)
 864{
 865        if ((fl->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) == F_RDLCK)
 866                return block ? NFS4_READW_LT : NFS4_READ_LT;
 867        return block ? NFS4_WRITEW_LT : NFS4_WRITE_LT;
 868}
 869
 870static inline uint64_t nfs4_lock_length(struct file_lock *fl)
 871{
 872        if (fl->fl_end == OFFSET_MAX)
 873                return ~(uint64_t)0;
 874        return fl->fl_end - fl->fl_start + 1;
 875}
 876
 877/*
 878 * opcode,type,reclaim,offset,length,new_lock_owner = 32
 879 * open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
 880 */
 881static int encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args)
 882{
 883        __be32 *p;
 884
 885        RESERVE_SPACE(32);
 886        WRITE32(OP_LOCK);
 887        WRITE32(nfs4_lock_type(args->fl, args->block));
 888        WRITE32(args->reclaim);
 889        WRITE64(args->fl->fl_start);
 890        WRITE64(nfs4_lock_length(args->fl));
 891        WRITE32(args->new_lock_owner);
 892        if (args->new_lock_owner){
 893                RESERVE_SPACE(4+NFS4_STATEID_SIZE+32);
 894                WRITE32(args->open_seqid->sequence->counter);
 895                WRITEMEM(args->open_stateid->data, NFS4_STATEID_SIZE);
 896                WRITE32(args->lock_seqid->sequence->counter);
 897                WRITE64(args->lock_owner.clientid);
 898                WRITE32(16);
 899                WRITEMEM("lock id:", 8);
 900                WRITE64(args->lock_owner.id);
 901        }
 902        else {
 903                RESERVE_SPACE(NFS4_STATEID_SIZE+4);
 904                WRITEMEM(args->lock_stateid->data, NFS4_STATEID_SIZE);
 905                WRITE32(args->lock_seqid->sequence->counter);
 906        }
 907
 908        return 0;
 909}
 910
 911static int encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *args)
 912{
 913        __be32 *p;
 914
 915        RESERVE_SPACE(52);
 916        WRITE32(OP_LOCKT);
 917        WRITE32(nfs4_lock_type(args->fl, 0));
 918        WRITE64(args->fl->fl_start);
 919        WRITE64(nfs4_lock_length(args->fl));
 920        WRITE64(args->lock_owner.clientid);
 921        WRITE32(16);
 922        WRITEMEM("lock id:", 8);
 923        WRITE64(args->lock_owner.id);
 924
 925        return 0;
 926}
 927
 928static int encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *args)
 929{
 930        __be32 *p;
 931
 932        RESERVE_SPACE(12+NFS4_STATEID_SIZE+16);
 933        WRITE32(OP_LOCKU);
 934        WRITE32(nfs4_lock_type(args->fl, 0));
 935        WRITE32(args->seqid->sequence->counter);
 936        WRITEMEM(args->stateid->data, NFS4_STATEID_SIZE);
 937        WRITE64(args->fl->fl_start);
 938        WRITE64(nfs4_lock_length(args->fl));
 939
 940        return 0;
 941}
 942
 943static int encode_lookup(struct xdr_stream *xdr, const struct qstr *name)
 944{
 945        int len = name->len;
 946        __be32 *p;
 947
 948        RESERVE_SPACE(8 + len);
 949        WRITE32(OP_LOOKUP);
 950        WRITE32(len);
 951        WRITEMEM(name->name, len);
 952
 953        return 0;
 954}
 955
 956static void encode_share_access(struct xdr_stream *xdr, int open_flags)
 957{
 958        __be32 *p;
 959
 960        RESERVE_SPACE(8);
 961        switch (open_flags & (FMODE_READ|FMODE_WRITE)) {
 962                case FMODE_READ:
 963                        WRITE32(NFS4_SHARE_ACCESS_READ);
 964                        break;
 965                case FMODE_WRITE:
 966                        WRITE32(NFS4_SHARE_ACCESS_WRITE);
 967                        break;
 968                case FMODE_READ|FMODE_WRITE:
 969                        WRITE32(NFS4_SHARE_ACCESS_BOTH);
 970                        break;
 971                default:
 972                        BUG();
 973        }
 974        WRITE32(0);             /* for linux, share_deny = 0 always */
 975}
 976
 977static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg)
 978{
 979        __be32 *p;
 980 /*
 981 * opcode 4, seqid 4, share_access 4, share_deny 4, clientid 8, ownerlen 4,
 982 * owner 4 = 32
 983 */
 984        RESERVE_SPACE(8);
 985        WRITE32(OP_OPEN);
 986        WRITE32(arg->seqid->sequence->counter);
 987        encode_share_access(xdr, arg->open_flags);
 988        RESERVE_SPACE(28);
 989        WRITE64(arg->clientid);
 990        WRITE32(16);
 991        WRITEMEM("open id:", 8);
 992        WRITE64(arg->id);
 993}
 994
 995static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg)
 996{
 997        __be32 *p;
 998
 999        RESERVE_SPACE(4);
1000        switch(arg->open_flags & O_EXCL) {
1001                case 0:
1002                        WRITE32(NFS4_CREATE_UNCHECKED);
1003                        encode_attrs(xdr, arg->u.attrs, arg->server);
1004                        break;
1005                default:
1006                        WRITE32(NFS4_CREATE_EXCLUSIVE);
1007                        encode_nfs4_verifier(xdr, &arg->u.verifier);
1008        }
1009}
1010
1011static void encode_opentype(struct xdr_stream *xdr, const struct nfs_openargs *arg)
1012{
1013        __be32 *p;
1014
1015        RESERVE_SPACE(4);
1016        switch (arg->open_flags & O_CREAT) {
1017                case 0:
1018                        WRITE32(NFS4_OPEN_NOCREATE);
1019                        break;
1020                default:
1021                        BUG_ON(arg->claim != NFS4_OPEN_CLAIM_NULL);
1022                        WRITE32(NFS4_OPEN_CREATE);
1023                        encode_createmode(xdr, arg);
1024        }
1025}
1026
1027static inline void encode_delegation_type(struct xdr_stream *xdr, int delegation_type)
1028{
1029        __be32 *p;
1030
1031        RESERVE_SPACE(4);
1032        switch (delegation_type) {
1033                case 0:
1034                        WRITE32(NFS4_OPEN_DELEGATE_NONE);
1035                        break;
1036                case FMODE_READ:
1037                        WRITE32(NFS4_OPEN_DELEGATE_READ);
1038                        break;
1039                case FMODE_WRITE|FMODE_READ:
1040                        WRITE32(NFS4_OPEN_DELEGATE_WRITE);
1041                        break;
1042                default:
1043                        BUG();
1044        }
1045}
1046
1047static inline void encode_claim_null(struct xdr_stream *xdr, const struct qstr *name)
1048{
1049        __be32 *p;
1050
1051        RESERVE_SPACE(4);
1052        WRITE32(NFS4_OPEN_CLAIM_NULL);
1053        encode_string(xdr, name->len, name->name);
1054}
1055
1056static inline void encode_claim_previous(struct xdr_stream *xdr, int type)
1057{
1058        __be32 *p;
1059
1060        RESERVE_SPACE(4);
1061        WRITE32(NFS4_OPEN_CLAIM_PREVIOUS);
1062        encode_delegation_type(xdr, type);
1063}
1064
1065static inline void encode_claim_delegate_cur(struct xdr_stream *xdr, const struct qstr *name, const nfs4_stateid *stateid)
1066{
1067        __be32 *p;
1068
1069        RESERVE_SPACE(4+NFS4_STATEID_SIZE);
1070        WRITE32(NFS4_OPEN_CLAIM_DELEGATE_CUR);
1071        WRITEMEM(stateid->data, NFS4_STATEID_SIZE);
1072        encode_string(xdr, name->len, name->name);
1073}
1074
1075static int encode_open(struct xdr_stream *xdr, const struct nfs_openargs *arg)
1076{
1077        encode_openhdr(xdr, arg);
1078        encode_opentype(xdr, arg);
1079        switch (arg->claim) {
1080                case NFS4_OPEN_CLAIM_NULL:
1081                        encode_claim_null(xdr, arg->name);
1082                        break;
1083                case NFS4_OPEN_CLAIM_PREVIOUS:
1084                        encode_claim_previous(xdr, arg->u.delegation_type);
1085                        break;
1086                case NFS4_OPEN_CLAIM_DELEGATE_CUR:
1087                        encode_claim_delegate_cur(xdr, arg->name, &arg->u.delegation);
1088                        break;
1089                default:
1090                        BUG();
1091        }
1092        return 0;
1093}
1094
1095static int encode_open_confirm(struct xdr_stream *xdr, const struct nfs_open_confirmargs *arg)
1096{
1097        __be32 *p;
1098
1099        RESERVE_SPACE(4+NFS4_STATEID_SIZE+4);
1100        WRITE32(OP_OPEN_CONFIRM);
1101        WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
1102        WRITE32(arg->seqid->sequence->counter);
1103
1104        return 0;
1105}
1106
1107static int encode_open_downgrade(struct xdr_stream *xdr, const struct nfs_closeargs *arg)
1108{
1109        __be32 *p;
1110
1111        RESERVE_SPACE(4+NFS4_STATEID_SIZE+4);
1112        WRITE32(OP_OPEN_DOWNGRADE);
1113        WRITEMEM(arg->stateid->data, NFS4_STATEID_SIZE);
1114        WRITE32(arg->seqid->sequence->counter);
1115        encode_share_access(xdr, arg->open_flags);
1116        return 0;
1117}
1118
1119static int
1120encode_putfh(struct xdr_stream *xdr, const struct nfs_fh *fh)
1121{
1122        int len = fh->size;
1123        __be32 *p;
1124
1125        RESERVE_SPACE(8 + len);
1126        WRITE32(OP_PUTFH);
1127        WRITE32(len);
1128        WRITEMEM(fh->data, len);
1129
1130        return 0;
1131}
1132
1133static int encode_putrootfh(struct xdr_stream *xdr)
1134{
1135        __be32 *p;
1136        
1137        RESERVE_SPACE(4);
1138        WRITE32(OP_PUTROOTFH);
1139
1140        return 0;
1141}
1142
1143static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
1144{
1145        nfs4_stateid stateid;
1146        __be32 *p;
1147
1148        RESERVE_SPACE(NFS4_STATEID_SIZE);
1149        if (ctx->state != NULL) {
1150                nfs4_copy_stateid(&stateid, ctx->state, ctx->lockowner);
1151                WRITEMEM(stateid.data, NFS4_STATEID_SIZE);
1152        } else
1153                WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE);
1154}
1155
1156static int encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args)
1157{
1158        __be32 *p;
1159
1160        RESERVE_SPACE(4);
1161        WRITE32(OP_READ);
1162
1163        encode_stateid(xdr, args->context);
1164
1165        RESERVE_SPACE(12);
1166        WRITE64(args->offset);
1167        WRITE32(args->count);
1168
1169        return 0;
1170}
1171
1172static int encode_readdir(struct xdr_stream *xdr, const struct nfs4_readdir_arg *readdir, struct rpc_rqst *req)
1173{
1174        uint32_t attrs[2] = {
1175                FATTR4_WORD0_RDATTR_ERROR|FATTR4_WORD0_FILEID,
1176                FATTR4_WORD1_MOUNTED_ON_FILEID,
1177        };
1178        __be32 *p;
1179
1180        RESERVE_SPACE(12+NFS4_VERIFIER_SIZE+20);
1181        WRITE32(OP_READDIR);
1182        WRITE64(readdir->cookie);
1183        WRITEMEM(readdir->verifier.data, NFS4_VERIFIER_SIZE);
1184        WRITE32(readdir->count >> 1);  /* We're not doing readdirplus */
1185        WRITE32(readdir->count);
1186        WRITE32(2);
1187        /* Switch to mounted_on_fileid if the server supports it */
1188        if (readdir->bitmask[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)
1189                attrs[0] &= ~FATTR4_WORD0_FILEID;
1190        else
1191                attrs[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
1192        WRITE32(attrs[0] & readdir->bitmask[0]);
1193        WRITE32(attrs[1] & readdir->bitmask[1]);
1194        dprintk("%s: cookie = %Lu, verifier = %08x:%08x, bitmap = %08x:%08x\n",
1195                        __func__,
1196                        (unsigned long long)readdir->cookie,
1197                        ((u32 *)readdir->verifier.data)[0],
1198                        ((u32 *)readdir->verifier.data)[1],
1199                        attrs[0] & readdir->bitmask[0],
1200                        attrs[1] & readdir->bitmask[1]);
1201
1202        return 0;
1203}
1204
1205static int encode_readlink(struct xdr_stream *xdr, const struct nfs4_readlink *readlink, struct rpc_rqst *req)
1206{
1207        __be32 *p;
1208
1209        RESERVE_SPACE(4);
1210        WRITE32(OP_READLINK);
1211
1212        return 0;
1213}
1214
1215static int encode_remove(struct xdr_stream *xdr, const struct qstr *name)
1216{
1217        __be32 *p;
1218
1219        RESERVE_SPACE(8 + name->len);
1220        WRITE32(OP_REMOVE);
1221        WRITE32(name->len);
1222        WRITEMEM(name->name, name->len);
1223
1224        return 0;
1225}
1226
1227static int encode_rename(struct xdr_stream *xdr, const struct qstr *oldname, const struct qstr *newname)
1228{
1229        __be32 *p;
1230
1231        RESERVE_SPACE(8 + oldname->len);
1232        WRITE32(OP_RENAME);
1233        WRITE32(oldname->len);
1234        WRITEMEM(oldname->name, oldname->len);
1235        
1236        RESERVE_SPACE(4 + newname->len);
1237        WRITE32(newname->len);
1238        WRITEMEM(newname->name, newname->len);
1239
1240        return 0;
1241}
1242
1243static int encode_renew(struct xdr_stream *xdr, const struct nfs_client *client_stateid)
1244{
1245        __be32 *p;
1246
1247        RESERVE_SPACE(12);
1248        WRITE32(OP_RENEW);
1249        WRITE64(client_stateid->cl_clientid);
1250
1251        return 0;
1252}
1253
1254static int
1255encode_restorefh(struct xdr_stream *xdr)
1256{
1257        __be32 *p;
1258
1259        RESERVE_SPACE(4);
1260        WRITE32(OP_RESTOREFH);
1261
1262        return 0;
1263}
1264
1265static int
1266encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg)
1267{
1268        __be32 *p;
1269
1270        RESERVE_SPACE(4+NFS4_STATEID_SIZE);
1271        WRITE32(OP_SETATTR);
1272        WRITEMEM(zero_stateid.data, NFS4_STATEID_SIZE);
1273        RESERVE_SPACE(2*4);
1274        WRITE32(1);
1275        WRITE32(FATTR4_WORD0_ACL);
1276        if (arg->acl_len % 4)
1277                return -EINVAL;
1278        RESERVE_SPACE(4);
1279        WRITE32(arg->acl_len);
1280        xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len);
1281        return 0;
1282}
1283
1284static int
1285encode_savefh(struct xdr_stream *xdr)
1286{
1287        __be32 *p;
1288
1289        RESERVE_SPACE(4);
1290        WRITE32(OP_SAVEFH);
1291
1292        return 0;
1293}
1294
1295static int encode_setattr(struct xdr_stream *xdr, const struct nfs_setattrargs *arg, const struct nfs_server *server)
1296{
1297        int status;
1298        __be32 *p;
1299        
1300        RESERVE_SPACE(4+NFS4_STATEID_SIZE);
1301        WRITE32(OP_SETATTR);
1302        WRITEMEM(arg->stateid.data, NFS4_STATEID_SIZE);
1303
1304        if ((status = encode_attrs(xdr, arg->iap, server)))
1305                return status;
1306
1307        return 0;
1308}
1309
1310static int encode_setclientid(struct xdr_stream *xdr, const struct nfs4_setclientid *setclientid)
1311{
1312        __be32 *p;
1313
1314        RESERVE_SPACE(4 + NFS4_VERIFIER_SIZE);
1315        WRITE32(OP_SETCLIENTID);
1316        WRITEMEM(setclientid->sc_verifier->data, NFS4_VERIFIER_SIZE);
1317
1318        encode_string(xdr, setclientid->sc_name_len, setclientid->sc_name);
1319        RESERVE_SPACE(4);
1320        WRITE32(setclientid->sc_prog);
1321        encode_string(xdr, setclientid->sc_netid_len, setclientid->sc_netid);
1322        encode_string(xdr, setclientid->sc_uaddr_len, setclientid->sc_uaddr);
1323        RESERVE_SPACE(4);
1324        WRITE32(setclientid->sc_cb_ident);
1325
1326        return 0;
1327}
1328
1329static int encode_setclientid_confirm(struct xdr_stream *xdr, const struct nfs_client *client_state)
1330{
1331        __be32 *p;
1332
1333        RESERVE_SPACE(12 + NFS4_VERIFIER_SIZE);
1334        WRITE32(OP_SETCLIENTID_CONFIRM);
1335        WRITE64(client_state->cl_clientid);
1336        WRITEMEM(client_state->cl_confirm.data, NFS4_VERIFIER_SIZE);
1337
1338        return 0;
1339}
1340
1341static int encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *args)
1342{
1343        __be32 *p;
1344
1345        RESERVE_SPACE(4);
1346        WRITE32(OP_WRITE);
1347
1348        encode_stateid(xdr, args->context);
1349
1350        RESERVE_SPACE(16);
1351        WRITE64(args->offset);
1352        WRITE32(args->stable);
1353        WRITE32(args->count);
1354
1355        xdr_write_pages(xdr, args->pages, args->pgbase, args->count);
1356
1357        return 0;
1358}
1359
1360static int encode_delegreturn(struct xdr_stream *xdr, const nfs4_stateid *stateid)
1361{
1362        __be32 *p;
1363
1364        RESERVE_SPACE(4+NFS4_STATEID_SIZE);
1365
1366        WRITE32(OP_DELEGRETURN);
1367        WRITEMEM(stateid->data, NFS4_STATEID_SIZE);
1368        return 0;
1369
1370}
1371/*
1372 * END OF "GENERIC" ENCODE ROUTINES.
1373 */
1374
1375/*
1376 * Encode an ACCESS request
1377 */
1378static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs4_accessargs *args)
1379{
1380        struct xdr_stream xdr;
1381        struct compound_hdr hdr = {
1382                .nops = 3,
1383        };
1384        int status;
1385
1386        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1387        encode_compound_hdr(&xdr, &hdr);
1388        status = encode_putfh(&xdr, args->fh);
1389        if (status != 0)
1390                goto out;
1391        status = encode_access(&xdr, args->access);
1392        if (status != 0)
1393                goto out;
1394        status = encode_getfattr(&xdr, args->bitmask);
1395out:
1396        return status;
1397}
1398
1399/*
1400 * Encode LOOKUP request
1401 */
1402static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_arg *args)
1403{
1404        struct xdr_stream xdr;
1405        struct compound_hdr hdr = {
1406                .nops = 4,
1407        };
1408        int status;
1409
1410        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1411        encode_compound_hdr(&xdr, &hdr);
1412        if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
1413                goto out;
1414        if ((status = encode_lookup(&xdr, args->name)) != 0)
1415                goto out;
1416        if ((status = encode_getfh(&xdr)) != 0)
1417                goto out;
1418        status = encode_getfattr(&xdr, args->bitmask);
1419out:
1420        return status;
1421}
1422
1423/*
1424 * Encode LOOKUP_ROOT request
1425 */
1426static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_root_arg *args)
1427{
1428        struct xdr_stream xdr;
1429        struct compound_hdr hdr = {
1430                .nops = 3,
1431        };
1432        int status;
1433
1434        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1435        encode_compound_hdr(&xdr, &hdr);
1436        if ((status = encode_putrootfh(&xdr)) != 0)
1437                goto out;
1438        if ((status = encode_getfh(&xdr)) == 0)
1439                status = encode_getfattr(&xdr, args->bitmask);
1440out:
1441        return status;
1442}
1443
1444/*
1445 * Encode REMOVE request
1446 */
1447static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args)
1448{
1449        struct xdr_stream xdr;
1450        struct compound_hdr hdr = {
1451                .nops = 3,
1452        };
1453        int status;
1454
1455        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1456        encode_compound_hdr(&xdr, &hdr);
1457        if ((status = encode_putfh(&xdr, args->fh)) != 0)
1458                goto out;
1459        if ((status = encode_remove(&xdr, &args->name)) != 0)
1460                goto out;
1461        status = encode_getfattr(&xdr, args->bitmask);
1462out:
1463        return status;
1464}
1465
1466/*
1467 * Encode RENAME request
1468 */
1469static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs4_rename_arg *args)
1470{
1471        struct xdr_stream xdr;
1472        struct compound_hdr hdr = {
1473                .nops = 7,
1474        };
1475        int status;
1476
1477        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1478        encode_compound_hdr(&xdr, &hdr);
1479        if ((status = encode_putfh(&xdr, args->old_dir)) != 0)
1480                goto out;
1481        if ((status = encode_savefh(&xdr)) != 0)
1482                goto out;
1483        if ((status = encode_putfh(&xdr, args->new_dir)) != 0)
1484                goto out;
1485        if ((status = encode_rename(&xdr, args->old_name, args->new_name)) != 0)
1486                goto out;
1487        if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
1488                goto out;
1489        if ((status = encode_restorefh(&xdr)) != 0)
1490                goto out;
1491        status = encode_getfattr(&xdr, args->bitmask);
1492out:
1493        return status;
1494}
1495
1496/*
1497 * Encode LINK request
1498 */
1499static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_link_arg *args)
1500{
1501        struct xdr_stream xdr;
1502        struct compound_hdr hdr = {
1503                .nops = 7,
1504        };
1505        int status;
1506
1507        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1508        encode_compound_hdr(&xdr, &hdr);
1509        if ((status = encode_putfh(&xdr, args->fh)) != 0)
1510                goto out;
1511        if ((status = encode_savefh(&xdr)) != 0)
1512                goto out;
1513        if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
1514                goto out;
1515        if ((status = encode_link(&xdr, args->name)) != 0)
1516                goto out;
1517        if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
1518                goto out;
1519        if ((status = encode_restorefh(&xdr)) != 0)
1520                goto out;
1521        status = encode_getfattr(&xdr, args->bitmask);
1522out:
1523        return status;
1524}
1525
1526/*
1527 * Encode CREATE request
1528 */
1529static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args)
1530{
1531        struct xdr_stream xdr;
1532        struct compound_hdr hdr = {
1533                .nops = 7,
1534        };
1535        int status;
1536
1537        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1538        encode_compound_hdr(&xdr, &hdr);
1539        if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
1540                goto out;
1541        if ((status = encode_savefh(&xdr)) != 0)
1542                goto out;
1543        if ((status = encode_create(&xdr, args)) != 0)
1544                goto out;
1545        if ((status = encode_getfh(&xdr)) != 0)
1546                goto out;
1547        if ((status = encode_getfattr(&xdr, args->bitmask)) != 0)
1548                goto out;
1549        if ((status = encode_restorefh(&xdr)) != 0)
1550                goto out;
1551        status = encode_getfattr(&xdr, args->bitmask);
1552out:
1553        return status;
1554}
1555
1556/*
1557 * Encode SYMLINK request
1558 */
1559static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args)
1560{
1561        return nfs4_xdr_enc_create(req, p, args);
1562}
1563
1564/*
1565 * Encode GETATTR request
1566 */
1567static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nfs4_getattr_arg *args)
1568{
1569        struct xdr_stream xdr;
1570        struct compound_hdr hdr = {
1571                .nops = 2,
1572        };
1573        int status;
1574
1575        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1576        encode_compound_hdr(&xdr, &hdr);
1577        if ((status = encode_putfh(&xdr, args->fh)) == 0)
1578                status = encode_getfattr(&xdr, args->bitmask);
1579        return status;
1580}
1581
1582/*
1583 * Encode a CLOSE request
1584 */
1585static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
1586{
1587        struct xdr_stream xdr;
1588        struct compound_hdr hdr = {
1589                .nops   = 3,
1590        };
1591        int status;
1592
1593        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1594        encode_compound_hdr(&xdr, &hdr);
1595        status = encode_putfh(&xdr, args->fh);
1596        if(status)
1597                goto out;
1598        status = encode_close(&xdr, args);
1599        if (status != 0)
1600                goto out;
1601        status = encode_getfattr(&xdr, args->bitmask);
1602out:
1603        return status;
1604}
1605
1606/*
1607 * Encode an OPEN request
1608 */
1609static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args)
1610{
1611        struct xdr_stream xdr;
1612        struct compound_hdr hdr = {
1613                .nops = 7,
1614        };
1615        int status;
1616
1617        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1618        encode_compound_hdr(&xdr, &hdr);
1619        status = encode_putfh(&xdr, args->fh);
1620        if (status)
1621                goto out;
1622        status = encode_savefh(&xdr);
1623        if (status)
1624                goto out;
1625        status = encode_open(&xdr, args);
1626        if (status)
1627                goto out;
1628        status = encode_getfh(&xdr);
1629        if (status)
1630                goto out;
1631        status = encode_getfattr(&xdr, args->bitmask);
1632        if (status)
1633                goto out;
1634        status = encode_restorefh(&xdr);
1635        if (status)
1636                goto out;
1637        status = encode_getfattr(&xdr, args->bitmask);
1638out:
1639        return status;
1640}
1641
1642/*
1643 * Encode an OPEN_CONFIRM request
1644 */
1645static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_open_confirmargs *args)
1646{
1647        struct xdr_stream xdr;
1648        struct compound_hdr hdr = {
1649                .nops   = 2,
1650        };
1651        int status;
1652
1653        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1654        encode_compound_hdr(&xdr, &hdr);
1655        status = encode_putfh(&xdr, args->fh);
1656        if(status)
1657                goto out;
1658        status = encode_open_confirm(&xdr, args);
1659out:
1660        return status;
1661}
1662
1663/*
1664 * Encode an OPEN request with no attributes.
1665 */
1666static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args)
1667{
1668        struct xdr_stream xdr;
1669        struct compound_hdr hdr = {
1670                .nops   = 3,
1671        };
1672        int status;
1673
1674        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1675        encode_compound_hdr(&xdr, &hdr);
1676        status = encode_putfh(&xdr, args->fh);
1677        if (status)
1678                goto out;
1679        status = encode_open(&xdr, args);
1680        if (status)
1681                goto out;
1682        status = encode_getfattr(&xdr, args->bitmask);
1683out:
1684        return status;
1685}
1686
1687/*
1688 * Encode an OPEN_DOWNGRADE request
1689 */
1690static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args)
1691{
1692        struct xdr_stream xdr;
1693        struct compound_hdr hdr = {
1694                .nops   = 3,
1695        };
1696        int status;
1697
1698        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1699        encode_compound_hdr(&xdr, &hdr);
1700        status = encode_putfh(&xdr, args->fh);
1701        if (status)
1702                goto out;
1703        status = encode_open_downgrade(&xdr, args);
1704        if (status != 0)
1705                goto out;
1706        status = encode_getfattr(&xdr, args->bitmask);
1707out:
1708        return status;
1709}
1710
1711/*
1712 * Encode a LOCK request
1713 */
1714static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_args *args)
1715{
1716        struct xdr_stream xdr;
1717        struct compound_hdr hdr = {
1718                .nops   = 2,
1719        };
1720        int status;
1721
1722        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1723        encode_compound_hdr(&xdr, &hdr);
1724        status = encode_putfh(&xdr, args->fh);
1725        if(status)
1726                goto out;
1727        status = encode_lock(&xdr, args);
1728out:
1729        return status;
1730}
1731
1732/*
1733 * Encode a LOCKT request
1734 */
1735static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_args *args)
1736{
1737        struct xdr_stream xdr;
1738        struct compound_hdr hdr = {
1739                .nops   = 2,
1740        };
1741        int status;
1742
1743        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1744        encode_compound_hdr(&xdr, &hdr);
1745        status = encode_putfh(&xdr, args->fh);
1746        if(status)
1747                goto out;
1748        status = encode_lockt(&xdr, args);
1749out:
1750        return status;
1751}
1752
1753/*
1754 * Encode a LOCKU request
1755 */
1756static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_args *args)
1757{
1758        struct xdr_stream xdr;
1759        struct compound_hdr hdr = {
1760                .nops   = 2,
1761        };
1762        int status;
1763
1764        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1765        encode_compound_hdr(&xdr, &hdr);
1766        status = encode_putfh(&xdr, args->fh);
1767        if(status)
1768                goto out;
1769        status = encode_locku(&xdr, args);
1770out:
1771        return status;
1772}
1773
1774/*
1775 * Encode a READLINK request
1776 */
1777static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_readlink *args)
1778{
1779        struct xdr_stream xdr;
1780        struct compound_hdr hdr = {
1781                .nops = 2,
1782        };
1783        struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1784        unsigned int replen;
1785        int status;
1786
1787        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1788        encode_compound_hdr(&xdr, &hdr);
1789        status = encode_putfh(&xdr, args->fh);
1790        if(status)
1791                goto out;
1792        status = encode_readlink(&xdr, args, req);
1793
1794        /* set up reply kvec
1795         *    toplevel_status + taglen + rescount + OP_PUTFH + status
1796         *      + OP_READLINK + status + string length = 8
1797         */
1798        replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readlink_sz) << 2;
1799        xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
1800                        args->pgbase, args->pglen);
1801
1802out:
1803        return status;
1804}
1805
1806/*
1807 * Encode a READDIR request
1808 */
1809static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nfs4_readdir_arg *args)
1810{
1811        struct xdr_stream xdr;
1812        struct compound_hdr hdr = {
1813                .nops = 2,
1814        };
1815        struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1816        int replen;
1817        int status;
1818
1819        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1820        encode_compound_hdr(&xdr, &hdr);
1821        status = encode_putfh(&xdr, args->fh);
1822        if(status)
1823                goto out;
1824        status = encode_readdir(&xdr, args, req);
1825
1826        /* set up reply kvec
1827         *    toplevel_status + taglen + rescount + OP_PUTFH + status
1828         *      + OP_READDIR + status + verifer(2)  = 9
1829         */
1830        replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_readdir_sz) << 2;
1831        xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages,
1832                         args->pgbase, args->count);
1833        dprintk("%s: inlined page args = (%u, %p, %u, %u)\n",
1834                        __func__, replen, args->pages,
1835                        args->pgbase, args->count);
1836
1837out:
1838        return status;
1839}
1840
1841/*
1842 * Encode a READ request
1843 */
1844static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args)
1845{
1846        struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1847        struct xdr_stream xdr;
1848        struct compound_hdr hdr = {
1849                .nops = 2,
1850        };
1851        int replen, status;
1852
1853        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1854        encode_compound_hdr(&xdr, &hdr);
1855        status = encode_putfh(&xdr, args->fh);
1856        if (status)
1857                goto out;
1858        status = encode_read(&xdr, args);
1859        if (status)
1860                goto out;
1861
1862        /* set up reply kvec
1863         *    toplevel status + taglen=0 + rescount + OP_PUTFH + status
1864         *       + OP_READ + status + eof + datalen = 9
1865         */
1866        replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_read_sz) << 2;
1867        xdr_inline_pages(&req->rq_rcv_buf, replen,
1868                         args->pages, args->pgbase, args->count);
1869        req->rq_rcv_buf.flags |= XDRBUF_READ;
1870out:
1871        return status;
1872}
1873
1874/*
1875 * Encode an SETATTR request
1876 */
1877static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_setattrargs *args)
1878
1879{
1880        struct xdr_stream xdr;
1881        struct compound_hdr hdr = {
1882                .nops   = 3,
1883        };
1884        int status;
1885
1886        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1887        encode_compound_hdr(&xdr, &hdr);
1888        status = encode_putfh(&xdr, args->fh);
1889        if(status)
1890                goto out;
1891        status = encode_setattr(&xdr, args, args->server);
1892        if(status)
1893                goto out;
1894        status = encode_getfattr(&xdr, args->bitmask);
1895out:
1896        return status;
1897}
1898
1899/*
1900 * Encode a GETACL request
1901 */
1902static int
1903nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p,
1904                struct nfs_getaclargs *args)
1905{
1906        struct xdr_stream xdr;
1907        struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
1908        struct compound_hdr hdr = {
1909                .nops   = 2,
1910        };
1911        int replen, status;
1912
1913        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1914        encode_compound_hdr(&xdr, &hdr);
1915        status = encode_putfh(&xdr, args->fh);
1916        if (status)
1917                goto out;
1918        status = encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0);
1919        /* set up reply buffer: */
1920        replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS4_dec_getacl_sz) << 2;
1921        xdr_inline_pages(&req->rq_rcv_buf, replen,
1922                args->acl_pages, args->acl_pgbase, args->acl_len);
1923out:
1924        return status;
1925}
1926
1927/*
1928 * Encode a WRITE request
1929 */
1930static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
1931{
1932        struct xdr_stream xdr;
1933        struct compound_hdr hdr = {
1934                .nops = 3,
1935        };
1936        int status;
1937
1938        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1939        encode_compound_hdr(&xdr, &hdr);
1940        status = encode_putfh(&xdr, args->fh);
1941        if (status)
1942                goto out;
1943        status = encode_write(&xdr, args);
1944        if (status)
1945                goto out;
1946        req->rq_snd_buf.flags |= XDRBUF_WRITE;
1947        status = encode_getfattr(&xdr, args->bitmask);
1948out:
1949        return status;
1950}
1951
1952/*
1953 *  a COMMIT request
1954 */
1955static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args)
1956{
1957        struct xdr_stream xdr;
1958        struct compound_hdr hdr = {
1959                .nops = 3,
1960        };
1961        int status;
1962
1963        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1964        encode_compound_hdr(&xdr, &hdr);
1965        status = encode_putfh(&xdr, args->fh);
1966        if (status)
1967                goto out;
1968        status = encode_commit(&xdr, args);
1969        if (status)
1970                goto out;
1971        status = encode_getfattr(&xdr, args->bitmask);
1972out:
1973        return status;
1974}
1975
1976/*
1977 * FSINFO request
1978 */
1979static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsinfo_arg *args)
1980{
1981        struct xdr_stream xdr;
1982        struct compound_hdr hdr = {
1983                .nops   = 2,
1984        };
1985        int status;
1986
1987        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
1988        encode_compound_hdr(&xdr, &hdr);
1989        status = encode_putfh(&xdr, args->fh);
1990        if (!status)
1991                status = encode_fsinfo(&xdr, args->bitmask);
1992        return status;
1993}
1994
1995/*
1996 * a PATHCONF request
1997 */
1998static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct nfs4_pathconf_arg *args)
1999{
2000        struct xdr_stream xdr;
2001        struct compound_hdr hdr = {
2002                .nops = 2,
2003        };
2004        int status;
2005
2006        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2007        encode_compound_hdr(&xdr, &hdr);
2008        status = encode_putfh(&xdr, args->fh);
2009        if (!status)
2010                status = encode_getattr_one(&xdr,
2011                                args->bitmask[0] & nfs4_pathconf_bitmap[0]);
2012        return status;
2013}
2014
2015/*
2016 * a STATFS request
2017 */
2018static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs4_statfs_arg *args)
2019{
2020        struct xdr_stream xdr;
2021        struct compound_hdr hdr = {
2022                .nops = 2,
2023        };
2024        int status;
2025
2026        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2027        encode_compound_hdr(&xdr, &hdr);
2028        status = encode_putfh(&xdr, args->fh);
2029        if (status == 0)
2030                status = encode_getattr_two(&xdr,
2031                                args->bitmask[0] & nfs4_statfs_bitmap[0],
2032                                args->bitmask[1] & nfs4_statfs_bitmap[1]);
2033        return status;
2034}
2035
2036/*
2037 * GETATTR_BITMAP request
2038 */
2039static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, const struct nfs_fh *fhandle)
2040{
2041        struct xdr_stream xdr;
2042        struct compound_hdr hdr = {
2043                .nops = 2,
2044        };
2045        int status;
2046
2047        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2048        encode_compound_hdr(&xdr, &hdr);
2049        status = encode_putfh(&xdr, fhandle);
2050        if (status == 0)
2051                status = encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS|
2052                                FATTR4_WORD0_LINK_SUPPORT|
2053                                FATTR4_WORD0_SYMLINK_SUPPORT|
2054                                FATTR4_WORD0_ACLSUPPORT);
2055        return status;
2056}
2057
2058/*
2059 * a RENEW request
2060 */
2061static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp)
2062{
2063        struct xdr_stream xdr;
2064        struct compound_hdr hdr = {
2065                .nops   = 1,
2066        };
2067
2068        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2069        encode_compound_hdr(&xdr, &hdr);
2070        return encode_renew(&xdr, clp);
2071}
2072
2073/*
2074 * a SETCLIENTID request
2075 */
2076static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid *sc)
2077{
2078        struct xdr_stream xdr;
2079        struct compound_hdr hdr = {
2080                .nops   = 1,
2081        };
2082
2083        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2084        encode_compound_hdr(&xdr, &hdr);
2085        return encode_setclientid(&xdr, sc);
2086}
2087
2088/*
2089 * a SETCLIENTID_CONFIRM request
2090 */
2091static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp)
2092{
2093        struct xdr_stream xdr;
2094        struct compound_hdr hdr = {
2095                .nops   = 3,
2096        };
2097        const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 };
2098        int status;
2099
2100        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2101        encode_compound_hdr(&xdr, &hdr);
2102        status = encode_setclientid_confirm(&xdr, clp);
2103        if (!status)
2104                status = encode_putrootfh(&xdr);
2105        if (!status)
2106                status = encode_fsinfo(&xdr, lease_bitmap);
2107        return status;
2108}
2109
2110/*
2111 * DELEGRETURN request
2112 */
2113static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struct nfs4_delegreturnargs *args)
2114{
2115        struct xdr_stream xdr;
2116        struct compound_hdr hdr = {
2117                .nops = 3,
2118        };
2119        int status;
2120
2121        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2122        encode_compound_hdr(&xdr, &hdr);
2123        status = encode_putfh(&xdr, args->fhandle);
2124        if (status != 0)
2125                goto out;
2126        status = encode_delegreturn(&xdr, args->stateid);
2127        if (status != 0)
2128                goto out;
2129        status = encode_getfattr(&xdr, args->bitmask);
2130out:
2131        return status;
2132}
2133
2134/*
2135 * Encode FS_LOCATIONS request
2136 */
2137static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations_arg *args)
2138{
2139        struct xdr_stream xdr;
2140        struct compound_hdr hdr = {
2141                .nops = 3,
2142        };
2143        struct rpc_auth *auth = req->rq_task->tk_msg.rpc_cred->cr_auth;
2144        int replen;
2145        int status;
2146
2147        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
2148        encode_compound_hdr(&xdr, &hdr);
2149        if ((status = encode_putfh(&xdr, args->dir_fh)) != 0)
2150                goto out;
2151        if ((status = encode_lookup(&xdr, args->name)) != 0)
2152                goto out;
2153        if ((status = encode_fs_locations(&xdr, args->bitmask)) != 0)
2154                goto out;
2155        /* set up reply
2156         *   toplevel_status + OP_PUTFH + status
2157         *   + OP_LOOKUP + status + OP_GETATTR + status = 7
2158         */
2159        replen = (RPC_REPHDRSIZE + auth->au_rslack + 7) << 2;
2160        xdr_inline_pages(&req->rq_rcv_buf, replen, &args->page,
2161                        0, PAGE_SIZE);
2162out:
2163        return status;
2164}
2165
2166/*
2167 * START OF "GENERIC" DECODE ROUTINES.
2168 *   These may look a little ugly since they are imported from a "generic"
2169 * set of XDR encode/decode routines which are intended to be shared by
2170 * all of our NFSv4 implementations (OpenBSD, MacOS X...).
2171 *
2172 * If the pain of reading these is too great, it should be a straightforward
2173 * task to translate them into Linux-specific versions which are more
2174 * consistent with the style used in NFSv2/v3...
2175 */
2176#define READ32(x)         (x) = ntohl(*p++)
2177#define READ64(x)         do {                  \
2178        (x) = (u64)ntohl(*p++) << 32;           \
2179        (x) |= ntohl(*p++);                     \
2180} while (0)
2181#define READTIME(x)       do {                  \
2182        p++;                                    \
2183        (x.tv_sec) = ntohl(*p++);               \
2184        (x.tv_nsec) = ntohl(*p++);              \
2185} while (0)
2186#define COPYMEM(x,nbytes) do {                  \
2187        memcpy((x), p, nbytes);                 \
2188        p += XDR_QUADLEN(nbytes);               \
2189} while (0)
2190
2191#define READ_BUF(nbytes)  do { \
2192        p = xdr_inline_decode(xdr, nbytes); \
2193        if (unlikely(!p)) { \
2194                dprintk("nfs: %s: prematurely hit end of receive" \
2195                                " buffer\n", __func__); \
2196                dprintk("nfs: %s: xdr->p=%p, bytes=%u, xdr->end=%p\n", \
2197                                __func__, xdr->p, nbytes, xdr->end); \
2198                return -EIO; \
2199        } \
2200} while (0)
2201
2202static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string)
2203{
2204        __be32 *p;
2205
2206        READ_BUF(4);
2207        READ32(*len);
2208        READ_BUF(*len);
2209        *string = (char *)p;
2210        return 0;
2211}
2212
2213static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr)
2214{
2215        __be32 *p;
2216
2217        READ_BUF(8);
2218        READ32(hdr->status);
2219        READ32(hdr->taglen);
2220        
2221        READ_BUF(hdr->taglen + 4);
2222        hdr->tag = (char *)p;
2223        p += XDR_QUADLEN(hdr->taglen);
2224        READ32(hdr->nops);
2225        return 0;
2226}
2227
2228static int decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected)
2229{
2230        __be32 *p;
2231        uint32_t opnum;
2232        int32_t nfserr;
2233
2234        READ_BUF(8);
2235        READ32(opnum);
2236        if (opnum != expected) {
2237                dprintk("nfs: Server returned operation"
2238                        " %d but we issued a request for %d\n",
2239                                opnum, expected);
2240                return -EIO;
2241        }
2242        READ32(nfserr);
2243        if (nfserr != NFS_OK)
2244                return nfs4_stat_to_errno(nfserr);
2245        return 0;
2246}
2247
2248/* Dummy routine */
2249static int decode_ace(struct xdr_stream *xdr, void *ace, struct nfs_client *clp)
2250{
2251        __be32 *p;
2252        unsigned int strlen;
2253        char *str;
2254
2255        READ_BUF(12);
2256        return decode_opaque_inline(xdr, &strlen, &str);
2257}
2258
2259static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap)
2260{
2261        uint32_t bmlen;
2262        __be32 *p;
2263
2264        READ_BUF(4);
2265        READ32(bmlen);
2266
2267        bitmap[0] = bitmap[1] = 0;
2268        READ_BUF((bmlen << 2));
2269        if (bmlen > 0) {
2270                READ32(bitmap[0]);
2271                if (bmlen > 1)
2272                        READ32(bitmap[1]);
2273        }
2274        return 0;
2275}
2276
2277static inline int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, __be32 **savep)
2278{
2279        __be32 *p;
2280
2281        READ_BUF(4);
2282        READ32(*attrlen);
2283        *savep = xdr->p;
2284        return 0;
2285}
2286
2287static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask)
2288{
2289        if (likely(bitmap[0] & FATTR4_WORD0_SUPPORTED_ATTRS)) {
2290                decode_attr_bitmap(xdr, bitmask);
2291                bitmap[0] &= ~FATTR4_WORD0_SUPPORTED_ATTRS;
2292        } else
2293                bitmask[0] = bitmask[1] = 0;
2294        dprintk("%s: bitmask=%08x:%08x\n", __func__, bitmask[0], bitmask[1]);
2295        return 0;
2296}
2297
2298static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *type)
2299{
2300        __be32 *p;
2301
2302        *type = 0;
2303        if (unlikely(bitmap[0] & (FATTR4_WORD0_TYPE - 1U)))
2304                return -EIO;
2305        if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) {
2306                READ_BUF(4);
2307                READ32(*type);
2308                if (*type < NF4REG || *type > NF4NAMEDATTR) {
2309                        dprintk("%s: bad type %d\n", __func__, *type);
2310                        return -EIO;
2311                }
2312                bitmap[0] &= ~FATTR4_WORD0_TYPE;
2313        }
2314        dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type].nfs2type);
2315        return 0;
2316}
2317
2318static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change)
2319{
2320        __be32 *p;
2321
2322        *change = 0;
2323        if (unlikely(bitmap[0] & (FATTR4_WORD0_CHANGE - 1U)))
2324                return -EIO;
2325        if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) {
2326                READ_BUF(8);
2327                READ64(*change);
2328                bitmap[0] &= ~FATTR4_WORD0_CHANGE;
2329        }
2330        dprintk("%s: change attribute=%Lu\n", __func__,
2331                        (unsigned long long)*change);
2332        return 0;
2333}
2334
2335static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size)
2336{
2337        __be32 *p;
2338
2339        *size = 0;
2340        if (unlikely(bitmap[0] & (FATTR4_WORD0_SIZE - 1U)))
2341                return -EIO;
2342        if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) {
2343                READ_BUF(8);
2344                READ64(*size);
2345                bitmap[0] &= ~FATTR4_WORD0_SIZE;
2346        }
2347        dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size);
2348        return 0;
2349}
2350
2351static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2352{
2353        __be32 *p;
2354
2355        *res = 0;
2356        if (unlikely(bitmap[0] & (FATTR4_WORD0_LINK_SUPPORT - 1U)))
2357                return -EIO;
2358        if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) {
2359                READ_BUF(4);
2360                READ32(*res);
2361                bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT;
2362        }
2363        dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true");
2364        return 0;
2365}
2366
2367static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2368{
2369        __be32 *p;
2370
2371        *res = 0;
2372        if (unlikely(bitmap[0] & (FATTR4_WORD0_SYMLINK_SUPPORT - 1U)))
2373                return -EIO;
2374        if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) {
2375                READ_BUF(4);
2376                READ32(*res);
2377                bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT;
2378        }
2379        dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true");
2380        return 0;
2381}
2382
2383static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid)
2384{
2385        __be32 *p;
2386
2387        fsid->major = 0;
2388        fsid->minor = 0;
2389        if (unlikely(bitmap[0] & (FATTR4_WORD0_FSID - 1U)))
2390                return -EIO;
2391        if (likely(bitmap[0] & FATTR4_WORD0_FSID)) {
2392                READ_BUF(16);
2393                READ64(fsid->major);
2394                READ64(fsid->minor);
2395                bitmap[0] &= ~FATTR4_WORD0_FSID;
2396        }
2397        dprintk("%s: fsid=(0x%Lx/0x%Lx)\n", __func__,
2398                        (unsigned long long)fsid->major,
2399                        (unsigned long long)fsid->minor);
2400        return 0;
2401}
2402
2403static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2404{
2405        __be32 *p;
2406
2407        *res = 60;
2408        if (unlikely(bitmap[0] & (FATTR4_WORD0_LEASE_TIME - 1U)))
2409                return -EIO;
2410        if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) {
2411                READ_BUF(4);
2412                READ32(*res);
2413                bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME;
2414        }
2415        dprintk("%s: file size=%u\n", __func__, (unsigned int)*res);
2416        return 0;
2417}
2418
2419static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2420{
2421        __be32 *p;
2422
2423        *res = ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL;
2424        if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U)))
2425                return -EIO;
2426        if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) {
2427                READ_BUF(4);
2428                READ32(*res);
2429                bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT;
2430        }
2431        dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res);
2432        return 0;
2433}
2434
2435static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
2436{
2437        __be32 *p;
2438
2439        *fileid = 0;
2440        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILEID - 1U)))
2441                return -EIO;
2442        if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) {
2443                READ_BUF(8);
2444                READ64(*fileid);
2445                bitmap[0] &= ~FATTR4_WORD0_FILEID;
2446        }
2447        dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
2448        return 0;
2449}
2450
2451static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid)
2452{
2453        __be32 *p;
2454
2455        *fileid = 0;
2456        if (unlikely(bitmap[1] & (FATTR4_WORD1_MOUNTED_ON_FILEID - 1U)))
2457                return -EIO;
2458        if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) {
2459                READ_BUF(8);
2460                READ64(*fileid);
2461                bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID;
2462        }
2463        dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid);
2464        return 0;
2465}
2466
2467static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2468{
2469        __be32 *p;
2470        int status = 0;
2471
2472        *res = 0;
2473        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_AVAIL - 1U)))
2474                return -EIO;
2475        if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) {
2476                READ_BUF(8);
2477                READ64(*res);
2478                bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL;
2479        }
2480        dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res);
2481        return status;
2482}
2483
2484static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2485{
2486        __be32 *p;
2487        int status = 0;
2488
2489        *res = 0;
2490        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_FREE - 1U)))
2491                return -EIO;
2492        if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) {
2493                READ_BUF(8);
2494                READ64(*res);
2495                bitmap[0] &= ~FATTR4_WORD0_FILES_FREE;
2496        }
2497        dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res);
2498        return status;
2499}
2500
2501static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2502{
2503        __be32 *p;
2504        int status = 0;
2505
2506        *res = 0;
2507        if (unlikely(bitmap[0] & (FATTR4_WORD0_FILES_TOTAL - 1U)))
2508                return -EIO;
2509        if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) {
2510                READ_BUF(8);
2511                READ64(*res);
2512                bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL;
2513        }
2514        dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res);
2515        return status;
2516}
2517
2518static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path)
2519{
2520        u32 n;
2521        __be32 *p;
2522        int status = 0;
2523
2524        READ_BUF(4);
2525        READ32(n);
2526        if (n == 0)
2527                goto root_path;
2528        dprintk("path ");
2529        path->ncomponents = 0;
2530        while (path->ncomponents < n) {
2531                struct nfs4_string *component = &path->components[path->ncomponents];
2532                status = decode_opaque_inline(xdr, &component->len, &component->data);
2533                if (unlikely(status != 0))
2534                        goto out_eio;
2535                if (path->ncomponents != n)
2536                        dprintk("/");
2537                dprintk("%s", component->data);
2538                if (path->ncomponents < NFS4_PATHNAME_MAXCOMPONENTS)
2539                        path->ncomponents++;
2540                else {
2541                        dprintk("cannot parse %d components in path\n", n);
2542                        goto out_eio;
2543                }
2544        }
2545out:
2546        dprintk("\n");
2547        return status;
2548root_path:
2549/* a root pathname is sent as a zero component4 */
2550        path->ncomponents = 1;
2551        path->components[0].len=0;
2552        path->components[0].data=NULL;
2553        dprintk("path /\n");
2554        goto out;
2555out_eio:
2556        dprintk(" status %d", status);
2557        status = -EIO;
2558        goto out;
2559}
2560
2561static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res)
2562{
2563        int n;
2564        __be32 *p;
2565        int status = -EIO;
2566
2567        if (unlikely(bitmap[0] & (FATTR4_WORD0_FS_LOCATIONS -1U)))
2568                goto out;
2569        status = 0;
2570        if (unlikely(!(bitmap[0] & FATTR4_WORD0_FS_LOCATIONS)))
2571                goto out;
2572        dprintk("%s: fsroot ", __func__);
2573        status = decode_pathname(xdr, &res->fs_path);
2574        if (unlikely(status != 0))
2575                goto out;
2576        READ_BUF(4);
2577        READ32(n);
2578        if (n <= 0)
2579                goto out_eio;
2580        res->nlocations = 0;
2581        while (res->nlocations < n) {
2582                u32 m;
2583                struct nfs4_fs_location *loc = &res->locations[res->nlocations];
2584
2585                READ_BUF(4);
2586                READ32(m);
2587
2588                loc->nservers = 0;
2589                dprintk("%s: servers ", __func__);
2590                while (loc->nservers < m) {
2591                        struct nfs4_string *server = &loc->servers[loc->nservers];
2592                        status = decode_opaque_inline(xdr, &server->len, &server->data);
2593                        if (unlikely(status != 0))
2594                                goto out_eio;
2595                        dprintk("%s ", server->data);
2596                        if (loc->nservers < NFS4_FS_LOCATION_MAXSERVERS)
2597                                loc->nservers++;
2598                        else {
2599                                unsigned int i;
2600                                dprintk("%s: using first %u of %u servers "
2601                                        "returned for location %u\n",
2602                                                __func__,
2603                                                NFS4_FS_LOCATION_MAXSERVERS,
2604                                                m, res->nlocations);
2605                                for (i = loc->nservers; i < m; i++) {
2606                                        unsigned int len;
2607                                        char *data;
2608                                        status = decode_opaque_inline(xdr, &len, &data);
2609                                        if (unlikely(status != 0))
2610                                                goto out_eio;
2611                                }
2612                        }
2613                }
2614                status = decode_pathname(xdr, &loc->rootpath);
2615                if (unlikely(status != 0))
2616                        goto out_eio;
2617                if (res->nlocations < NFS4_FS_LOCATIONS_MAXENTRIES)
2618                        res->nlocations++;
2619        }
2620out:
2621        dprintk("%s: fs_locations done, error = %d\n", __func__, status);
2622        return status;
2623out_eio:
2624        status = -EIO;
2625        goto out;
2626}
2627
2628static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2629{
2630        __be32 *p;
2631        int status = 0;
2632
2633        *res = 0;
2634        if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXFILESIZE - 1U)))
2635                return -EIO;
2636        if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) {
2637                READ_BUF(8);
2638                READ64(*res);
2639                bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE;
2640        }
2641        dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res);
2642        return status;
2643}
2644
2645static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink)
2646{
2647        __be32 *p;
2648        int status = 0;
2649
2650        *maxlink = 1;
2651        if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXLINK - 1U)))
2652                return -EIO;
2653        if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) {
2654                READ_BUF(4);
2655                READ32(*maxlink);
2656                bitmap[0] &= ~FATTR4_WORD0_MAXLINK;
2657        }
2658        dprintk("%s: maxlink=%u\n", __func__, *maxlink);
2659        return status;
2660}
2661
2662static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname)
2663{
2664        __be32 *p;
2665        int status = 0;
2666
2667        *maxname = 1024;
2668        if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXNAME - 1U)))
2669                return -EIO;
2670        if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) {
2671                READ_BUF(4);
2672                READ32(*maxname);
2673                bitmap[0] &= ~FATTR4_WORD0_MAXNAME;
2674        }
2675        dprintk("%s: maxname=%u\n", __func__, *maxname);
2676        return status;
2677}
2678
2679static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2680{
2681        __be32 *p;
2682        int status = 0;
2683
2684        *res = 1024;
2685        if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXREAD - 1U)))
2686                return -EIO;
2687        if (likely(bitmap[0] & FATTR4_WORD0_MAXREAD)) {
2688                uint64_t maxread;
2689                READ_BUF(8);
2690                READ64(maxread);
2691                if (maxread > 0x7FFFFFFF)
2692                        maxread = 0x7FFFFFFF;
2693                *res = (uint32_t)maxread;
2694                bitmap[0] &= ~FATTR4_WORD0_MAXREAD;
2695        }
2696        dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res);
2697        return status;
2698}
2699
2700static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res)
2701{
2702        __be32 *p;
2703        int status = 0;
2704
2705        *res = 1024;
2706        if (unlikely(bitmap[0] & (FATTR4_WORD0_MAXWRITE - 1U)))
2707                return -EIO;
2708        if (likely(bitmap[0] & FATTR4_WORD0_MAXWRITE)) {
2709                uint64_t maxwrite;
2710                READ_BUF(8);
2711                READ64(maxwrite);
2712                if (maxwrite > 0x7FFFFFFF)
2713                        maxwrite = 0x7FFFFFFF;
2714                *res = (uint32_t)maxwrite;
2715                bitmap[0] &= ~FATTR4_WORD0_MAXWRITE;
2716        }
2717        dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res);
2718        return status;
2719}
2720
2721static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *mode)
2722{
2723        __be32 *p;
2724
2725        *mode = 0;
2726        if (unlikely(bitmap[1] & (FATTR4_WORD1_MODE - 1U)))
2727                return -EIO;
2728        if (likely(bitmap[1] & FATTR4_WORD1_MODE)) {
2729                READ_BUF(4);
2730                READ32(*mode);
2731                *mode &= ~S_IFMT;
2732                bitmap[1] &= ~FATTR4_WORD1_MODE;
2733        }
2734        dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode);
2735        return 0;
2736}
2737
2738static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink)
2739{
2740        __be32 *p;
2741
2742        *nlink = 1;
2743        if (unlikely(bitmap[1] & (FATTR4_WORD1_NUMLINKS - 1U)))
2744                return -EIO;
2745        if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) {
2746                READ_BUF(4);
2747                READ32(*nlink);
2748                bitmap[1] &= ~FATTR4_WORD1_NUMLINKS;
2749        }
2750        dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink);
2751        return 0;
2752}
2753
2754static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *uid)
2755{
2756        uint32_t len;
2757        __be32 *p;
2758
2759        *uid = -2;
2760        if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER - 1U)))
2761                return -EIO;
2762        if (likely(bitmap[1] & FATTR4_WORD1_OWNER)) {
2763                READ_BUF(4);
2764                READ32(len);
2765                READ_BUF(len);
2766                if (len < XDR_MAX_NETOBJ) {
2767                        if (nfs_map_name_to_uid(clp, (char *)p, len, uid) != 0)
2768                                dprintk("%s: nfs_map_name_to_uid failed!\n",
2769                                                __func__);
2770                } else
2771                        dprintk("%s: name too long (%u)!\n",
2772                                        __func__, len);
2773                bitmap[1] &= ~FATTR4_WORD1_OWNER;
2774        }
2775        dprintk("%s: uid=%d\n", __func__, (int)*uid);
2776        return 0;
2777}
2778
2779static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_client *clp, uint32_t *gid)
2780{
2781        uint32_t len;
2782        __be32 *p;
2783
2784        *gid = -2;
2785        if (unlikely(bitmap[1] & (FATTR4_WORD1_OWNER_GROUP - 1U)))
2786                return -EIO;
2787        if (likely(bitmap[1] & FATTR4_WORD1_OWNER_GROUP)) {
2788                READ_BUF(4);
2789                READ32(len);
2790                READ_BUF(len);
2791                if (len < XDR_MAX_NETOBJ) {
2792                        if (nfs_map_group_to_gid(clp, (char *)p, len, gid) != 0)
2793                                dprintk("%s: nfs_map_group_to_gid failed!\n",
2794                                                __func__);
2795                } else
2796                        dprintk("%s: name too long (%u)!\n",
2797                                        __func__, len);
2798                bitmap[1] &= ~FATTR4_WORD1_OWNER_GROUP;
2799        }
2800        dprintk("%s: gid=%d\n", __func__, (int)*gid);
2801        return 0;
2802}
2803
2804static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev)
2805{
2806        uint32_t major = 0, minor = 0;
2807        __be32 *p;
2808
2809        *rdev = MKDEV(0,0);
2810        if (unlikely(bitmap[1] & (FATTR4_WORD1_RAWDEV - 1U)))
2811                return -EIO;
2812        if (likely(bitmap[1] & FATTR4_WORD1_RAWDEV)) {
2813                dev_t tmp;
2814
2815                READ_BUF(8);
2816                READ32(major);
2817                READ32(minor);
2818                tmp = MKDEV(major, minor);
2819                if (MAJOR(tmp) == major && MINOR(tmp) == minor)
2820                        *rdev = tmp;
2821                bitmap[1] &= ~ FATTR4_WORD1_RAWDEV;
2822        }
2823        dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor);
2824        return 0;
2825}
2826
2827static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2828{
2829        __be32 *p;
2830        int status = 0;
2831
2832        *res = 0;
2833        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_AVAIL - 1U)))
2834                return -EIO;
2835        if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) {
2836                READ_BUF(8);
2837                READ64(*res);
2838                bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL;
2839        }
2840        dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res);
2841        return status;
2842}
2843
2844static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2845{
2846        __be32 *p;
2847        int status = 0;
2848
2849        *res = 0;
2850        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_FREE - 1U)))
2851                return -EIO;
2852        if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) {
2853                READ_BUF(8);
2854                READ64(*res);
2855                bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE;
2856        }
2857        dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res);
2858        return status;
2859}
2860
2861static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res)
2862{
2863        __be32 *p;
2864        int status = 0;
2865
2866        *res = 0;
2867        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_TOTAL - 1U)))
2868                return -EIO;
2869        if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) {
2870                READ_BUF(8);
2871                READ64(*res);
2872                bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL;
2873        }
2874        dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res);
2875        return status;
2876}
2877
2878static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used)
2879{
2880        __be32 *p;
2881
2882        *used = 0;
2883        if (unlikely(bitmap[1] & (FATTR4_WORD1_SPACE_USED - 1U)))
2884                return -EIO;
2885        if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) {
2886                READ_BUF(8);
2887                READ64(*used);
2888                bitmap[1] &= ~FATTR4_WORD1_SPACE_USED;
2889        }
2890        dprintk("%s: space used=%Lu\n", __func__,
2891                        (unsigned long long)*used);
2892        return 0;
2893}
2894
2895static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time)
2896{
2897        __be32 *p;
2898        uint64_t sec;
2899        uint32_t nsec;
2900
2901        READ_BUF(12);
2902        READ64(sec);
2903        READ32(nsec);
2904        time->tv_sec = (time_t)sec;
2905        time->tv_nsec = (long)nsec;
2906        return 0;
2907}
2908
2909static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
2910{
2911        int status = 0;
2912
2913        time->tv_sec = 0;
2914        time->tv_nsec = 0;
2915        if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_ACCESS - 1U)))
2916                return -EIO;
2917        if (likely(bitmap[1] & FATTR4_WORD1_TIME_ACCESS)) {
2918                status = decode_attr_time(xdr, time);
2919                bitmap[1] &= ~FATTR4_WORD1_TIME_ACCESS;
2920        }
2921        dprintk("%s: atime=%ld\n", __func__, (long)time->tv_sec);
2922        return status;
2923}
2924
2925static int decode_attr_time_metadata(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
2926{
2927        int status = 0;
2928
2929        time->tv_sec = 0;
2930        time->tv_nsec = 0;
2931        if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_METADATA - 1U)))
2932                return -EIO;
2933        if (likely(bitmap[1] & FATTR4_WORD1_TIME_METADATA)) {
2934                status = decode_attr_time(xdr, time);
2935                bitmap[1] &= ~FATTR4_WORD1_TIME_METADATA;
2936        }
2937        dprintk("%s: ctime=%ld\n", __func__, (long)time->tv_sec);
2938        return status;
2939}
2940
2941static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time)
2942{
2943        int status = 0;
2944
2945        time->tv_sec = 0;
2946        time->tv_nsec = 0;
2947        if (unlikely(bitmap[1] & (FATTR4_WORD1_TIME_MODIFY - 1U)))
2948                return -EIO;
2949        if (likely(bitmap[1] & FATTR4_WORD1_TIME_MODIFY)) {
2950                status = decode_attr_time(xdr, time);
2951                bitmap[1] &= ~FATTR4_WORD1_TIME_MODIFY;
2952        }
2953        dprintk("%s: mtime=%ld\n", __func__, (long)time->tv_sec);
2954        return status;
2955}
2956
2957static int verify_attr_len(struct xdr_stream *xdr, __be32 *savep, uint32_t attrlen)
2958{
2959        unsigned int attrwords = XDR_QUADLEN(attrlen);
2960        unsigned int nwords = xdr->p - savep;
2961
2962        if (unlikely(attrwords != nwords)) {
2963                dprintk("%s: server returned incorrect attribute length: "
2964                        "%u %c %u\n",
2965                                __func__,
2966                                attrwords << 2,
2967                                (attrwords < nwords) ? '<' : '>',
2968                                nwords << 2);
2969                return -EIO;
2970        }
2971        return 0;
2972}
2973
2974static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
2975{
2976        __be32 *p;
2977
2978        READ_BUF(20);
2979        READ32(cinfo->atomic);
2980        READ64(cinfo->before);
2981        READ64(cinfo->after);
2982        return 0;
2983}
2984
2985static int decode_access(struct xdr_stream *xdr, struct nfs4_accessres *access)
2986{
2987        __be32 *p;
2988        uint32_t supp, acc;
2989        int status;
2990
2991        status = decode_op_hdr(xdr, OP_ACCESS);
2992        if (status)
2993                return status;
2994        READ_BUF(8);
2995        READ32(supp);
2996        READ32(acc);
2997        access->supported = supp;
2998        access->access = acc;
2999        return 0;
3000}
3001
3002static int decode_close(struct xdr_stream *xdr, struct nfs_closeres *res)
3003{
3004        __be32 *p;
3005        int status;
3006
3007        status = decode_op_hdr(xdr, OP_CLOSE);
3008        if (status != -EIO)
3009                nfs_increment_open_seqid(status, res->seqid);
3010        if (status)
3011                return status;
3012        READ_BUF(NFS4_STATEID_SIZE);
3013        COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3014        return 0;
3015}
3016
3017static int decode_commit(struct xdr_stream *xdr, struct nfs_writeres *res)
3018{
3019        __be32 *p;
3020        int status;
3021
3022        status = decode_op_hdr(xdr, OP_COMMIT);
3023        if (status)
3024                return status;
3025        READ_BUF(8);
3026        COPYMEM(res->verf->verifier, 8);
3027        return 0;
3028}
3029
3030static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
3031{
3032        __be32 *p;
3033        uint32_t bmlen;
3034        int status;
3035
3036        status = decode_op_hdr(xdr, OP_CREATE);
3037        if (status)
3038                return status;
3039        if ((status = decode_change_info(xdr, cinfo)))
3040                return status;
3041        READ_BUF(4);
3042        READ32(bmlen);
3043        READ_BUF(bmlen << 2);
3044        return 0;
3045}
3046
3047static int decode_server_caps(struct xdr_stream *xdr, struct nfs4_server_caps_res *res)
3048{
3049        __be32 *savep;
3050        uint32_t attrlen, 
3051                 bitmap[2] = {0};
3052        int status;
3053
3054        if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3055                goto xdr_error;
3056        if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
3057                goto xdr_error;
3058        if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
3059                goto xdr_error;
3060        if ((status = decode_attr_supported(xdr, bitmap, res->attr_bitmask)) != 0)
3061                goto xdr_error;
3062        if ((status = decode_attr_link_support(xdr, bitmap, &res->has_links)) != 0)
3063                goto xdr_error;
3064        if ((status = decode_attr_symlink_support(xdr, bitmap, &res->has_symlinks)) != 0)
3065                goto xdr_error;
3066        if ((status = decode_attr_aclsupport(xdr, bitmap, &res->acl_bitmask)) != 0)
3067                goto xdr_error;
3068        status = verify_attr_len(xdr, savep, attrlen);
3069xdr_error:
3070        dprintk("%s: xdr returned %d!\n", __func__, -status);
3071        return status;
3072}
3073        
3074static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat)
3075{
3076        __be32 *savep;
3077        uint32_t attrlen, 
3078                 bitmap[2] = {0};
3079        int status;
3080        
3081        if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3082                goto xdr_error;
3083        if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
3084                goto xdr_error;
3085        if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
3086                goto xdr_error;
3087
3088        if ((status = decode_attr_files_avail(xdr, bitmap, &fsstat->afiles)) != 0)
3089                goto xdr_error;
3090        if ((status = decode_attr_files_free(xdr, bitmap, &fsstat->ffiles)) != 0)
3091                goto xdr_error;
3092        if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0)
3093                goto xdr_error;
3094        if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0)
3095                goto xdr_error;
3096        if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0)
3097                goto xdr_error;
3098        if ((status = decode_attr_space_total(xdr, bitmap, &fsstat->tbytes)) != 0)
3099                goto xdr_error;
3100
3101        status = verify_attr_len(xdr, savep, attrlen);
3102xdr_error:
3103        dprintk("%s: xdr returned %d!\n", __func__, -status);
3104        return status;
3105}
3106
3107static int decode_pathconf(struct xdr_stream *xdr, struct nfs_pathconf *pathconf)
3108{
3109        __be32 *savep;
3110        uint32_t attrlen, 
3111                 bitmap[2] = {0};
3112        int status;
3113        
3114        if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3115                goto xdr_error;
3116        if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
3117                goto xdr_error;
3118        if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
3119                goto xdr_error;
3120
3121        if ((status = decode_attr_maxlink(xdr, bitmap, &pathconf->max_link)) != 0)
3122                goto xdr_error;
3123        if ((status = decode_attr_maxname(xdr, bitmap, &pathconf->max_namelen)) != 0)
3124                goto xdr_error;
3125
3126        status = verify_attr_len(xdr, savep, attrlen);
3127xdr_error:
3128        dprintk("%s: xdr returned %d!\n", __func__, -status);
3129        return status;
3130}
3131
3132static int decode_getfattr(struct xdr_stream *xdr, struct nfs_fattr *fattr, const struct nfs_server *server)
3133{
3134        __be32 *savep;
3135        uint32_t attrlen,
3136                 bitmap[2] = {0},
3137                 type;
3138        int status, fmode = 0;
3139        uint64_t fileid;
3140
3141        if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3142                goto xdr_error;
3143        if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
3144                goto xdr_error;
3145
3146        fattr->bitmap[0] = bitmap[0];
3147        fattr->bitmap[1] = bitmap[1];
3148
3149        if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
3150                goto xdr_error;
3151
3152
3153        if ((status = decode_attr_type(xdr, bitmap, &type)) != 0)
3154                goto xdr_error;
3155        fattr->type = nfs_type2fmt[type].nfs2type;
3156        fmode = nfs_type2fmt[type].mode;
3157
3158        if ((status = decode_attr_change(xdr, bitmap, &fattr->change_attr)) != 0)
3159                goto xdr_error;
3160        if ((status = decode_attr_size(xdr, bitmap, &fattr->size)) != 0)
3161                goto xdr_error;
3162        if ((status = decode_attr_fsid(xdr, bitmap, &fattr->fsid)) != 0)
3163                goto xdr_error;
3164        if ((status = decode_attr_fileid(xdr, bitmap, &fattr->fileid)) != 0)
3165                goto xdr_error;
3166        if ((status = decode_attr_fs_locations(xdr, bitmap, container_of(fattr,
3167                                                struct nfs4_fs_locations,
3168                                                fattr))) != 0)
3169                goto xdr_error;
3170        if ((status = decode_attr_mode(xdr, bitmap, &fattr->mode)) != 0)
3171                goto xdr_error;
3172        fattr->mode |= fmode;
3173        if ((status = decode_attr_nlink(xdr, bitmap, &fattr->nlink)) != 0)
3174                goto xdr_error;
3175        if ((status = decode_attr_owner(xdr, bitmap, server->nfs_client, &fattr->uid)) != 0)
3176                goto xdr_error;
3177        if ((status = decode_attr_group(xdr, bitmap, server->nfs_client, &fattr->gid)) != 0)
3178                goto xdr_error;
3179        if ((status = decode_attr_rdev(xdr, bitmap, &fattr->rdev)) != 0)
3180                goto xdr_error;
3181        if ((status = decode_attr_space_used(xdr, bitmap, &fattr->du.nfs3.used)) != 0)
3182                goto xdr_error;
3183        if ((status = decode_attr_time_access(xdr, bitmap, &fattr->atime)) != 0)
3184                goto xdr_error;
3185        if ((status = decode_attr_time_metadata(xdr, bitmap, &fattr->ctime)) != 0)
3186                goto xdr_error;
3187        if ((status = decode_attr_time_modify(xdr, bitmap, &fattr->mtime)) != 0)
3188                goto xdr_error;
3189        if ((status = decode_attr_mounted_on_fileid(xdr, bitmap, &fileid)) != 0)
3190                goto xdr_error;
3191        if (fattr->fileid == 0 && fileid != 0)
3192                fattr->fileid = fileid;
3193        if ((status = verify_attr_len(xdr, savep, attrlen)) == 0)
3194                fattr->valid = NFS_ATTR_FATTR | NFS_ATTR_FATTR_V3 | NFS_ATTR_FATTR_V4;
3195xdr_error:
3196        dprintk("%s: xdr returned %d\n", __func__, -status);
3197        return status;
3198}
3199
3200
3201static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
3202{
3203        __be32 *savep;
3204        uint32_t attrlen, bitmap[2];
3205        int status;
3206
3207        if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3208                goto xdr_error;
3209        if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
3210                goto xdr_error;
3211        if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
3212                goto xdr_error;
3213
3214        fsinfo->rtmult = fsinfo->wtmult = 512;  /* ??? */
3215
3216        if ((status = decode_attr_lease_time(xdr, bitmap, &fsinfo->lease_time)) != 0)
3217                goto xdr_error;
3218        if ((status = decode_attr_maxfilesize(xdr, bitmap, &fsinfo->maxfilesize)) != 0)
3219                goto xdr_error;
3220        if ((status = decode_attr_maxread(xdr, bitmap, &fsinfo->rtmax)) != 0)
3221                goto xdr_error;
3222        fsinfo->rtpref = fsinfo->dtpref = fsinfo->rtmax;
3223        if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0)
3224                goto xdr_error;
3225        fsinfo->wtpref = fsinfo->wtmax;
3226
3227        status = verify_attr_len(xdr, savep, attrlen);
3228xdr_error:
3229        dprintk("%s: xdr returned %d!\n", __func__, -status);
3230        return status;
3231}
3232
3233static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh)
3234{
3235        __be32 *p;
3236        uint32_t len;
3237        int status;
3238
3239        /* Zero handle first to allow comparisons */
3240        memset(fh, 0, sizeof(*fh));
3241
3242        status = decode_op_hdr(xdr, OP_GETFH);
3243        if (status)
3244                return status;
3245
3246        READ_BUF(4);
3247        READ32(len);
3248        if (len > NFS4_FHSIZE)
3249                return -EIO;
3250        fh->size = len;
3251        READ_BUF(len);
3252        COPYMEM(fh->data, len);
3253        return 0;
3254}
3255
3256static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
3257{
3258        int status;
3259        
3260        status = decode_op_hdr(xdr, OP_LINK);
3261        if (status)
3262                return status;
3263        return decode_change_info(xdr, cinfo);
3264}
3265
3266/*
3267 * We create the owner, so we know a proper owner.id length is 4.
3268 */
3269static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl)
3270{
3271        uint64_t offset, length, clientid;
3272        __be32 *p;
3273        uint32_t namelen, type;
3274
3275        READ_BUF(32);
3276        READ64(offset);
3277        READ64(length);
3278        READ32(type);
3279        if (fl != NULL) {
3280                fl->fl_start = (loff_t)offset;
3281                fl->fl_end = fl->fl_start + (loff_t)length - 1;
3282                if (length == ~(uint64_t)0)
3283                        fl->fl_end = OFFSET_MAX;
3284                fl->fl_type = F_WRLCK;
3285                if (type & 1)
3286                        fl->fl_type = F_RDLCK;
3287                fl->fl_pid = 0;
3288        }
3289        READ64(clientid);
3290        READ32(namelen);
3291        READ_BUF(namelen);
3292        return -NFS4ERR_DENIED;
3293}
3294
3295static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res)
3296{
3297        __be32 *p;
3298        int status;
3299
3300        status = decode_op_hdr(xdr, OP_LOCK);
3301        if (status == -EIO)
3302                goto out;
3303        if (status == 0) {
3304                READ_BUF(NFS4_STATEID_SIZE);
3305                COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3306        } else if (status == -NFS4ERR_DENIED)
3307                status = decode_lock_denied(xdr, NULL);
3308        if (res->open_seqid != NULL)
3309                nfs_increment_open_seqid(status, res->open_seqid);
3310        nfs_increment_lock_seqid(status, res->lock_seqid);
3311out:
3312        return status;
3313}
3314
3315static int decode_lockt(struct xdr_stream *xdr, struct nfs_lockt_res *res)
3316{
3317        int status;
3318        status = decode_op_hdr(xdr, OP_LOCKT);
3319        if (status == -NFS4ERR_DENIED)
3320                return decode_lock_denied(xdr, res->denied);
3321        return status;
3322}
3323
3324static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
3325{
3326        __be32 *p;
3327        int status;
3328
3329        status = decode_op_hdr(xdr, OP_LOCKU);
3330        if (status != -EIO)
3331                nfs_increment_lock_seqid(status, res->seqid);
3332        if (status == 0) {
3333                READ_BUF(NFS4_STATEID_SIZE);
3334                COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3335        }
3336        return status;
3337}
3338
3339static int decode_lookup(struct xdr_stream *xdr)
3340{
3341        return decode_op_hdr(xdr, OP_LOOKUP);
3342}
3343
3344/* This is too sick! */
3345static int decode_space_limit(struct xdr_stream *xdr, u64 *maxsize)
3346{
3347        __be32 *p;
3348        uint32_t limit_type, nblocks, blocksize;
3349
3350        READ_BUF(12);
3351        READ32(limit_type);
3352        switch (limit_type) {
3353                case 1:
3354                        READ64(*maxsize);
3355                        break;
3356                case 2:
3357                        READ32(nblocks);
3358                        READ32(blocksize);
3359                        *maxsize = (uint64_t)nblocks * (uint64_t)blocksize;
3360        }
3361        return 0;
3362}
3363
3364static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res)
3365{
3366        __be32 *p;
3367        uint32_t delegation_type;
3368
3369        READ_BUF(4);
3370        READ32(delegation_type);
3371        if (delegation_type == NFS4_OPEN_DELEGATE_NONE) {
3372                res->delegation_type = 0;
3373                return 0;
3374        }
3375        READ_BUF(NFS4_STATEID_SIZE+4);
3376        COPYMEM(res->delegation.data, NFS4_STATEID_SIZE);
3377        READ32(res->do_recall);
3378        switch (delegation_type) {
3379                case NFS4_OPEN_DELEGATE_READ:
3380                        res->delegation_type = FMODE_READ;
3381                        break;
3382                case NFS4_OPEN_DELEGATE_WRITE:
3383                        res->delegation_type = FMODE_WRITE|FMODE_READ;
3384                        if (decode_space_limit(xdr, &res->maxsize) < 0)
3385                                return -EIO;
3386        }
3387        return decode_ace(xdr, NULL, res->server->nfs_client);
3388}
3389
3390static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res)
3391{
3392        __be32 *p;
3393        uint32_t savewords, bmlen, i;
3394        int status;
3395
3396        status = decode_op_hdr(xdr, OP_OPEN);
3397        if (status != -EIO)
3398                nfs_increment_open_seqid(status, res->seqid);
3399        if (status)
3400                return status;
3401        READ_BUF(NFS4_STATEID_SIZE);
3402        COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3403
3404        decode_change_info(xdr, &res->cinfo);
3405
3406        READ_BUF(8);
3407        READ32(res->rflags);
3408        READ32(bmlen);
3409        if (bmlen > 10)
3410                goto xdr_error;
3411
3412        READ_BUF(bmlen << 2);
3413        savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE);
3414        for (i = 0; i < savewords; ++i)
3415                READ32(res->attrset[i]);
3416        for (; i < NFS4_BITMAP_SIZE; i++)
3417                res->attrset[i] = 0;
3418
3419        return decode_delegation(xdr, res);
3420xdr_error:
3421        dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen);
3422        return -EIO;
3423}
3424
3425static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res)
3426{
3427        __be32 *p;
3428        int status;
3429
3430        status = decode_op_hdr(xdr, OP_OPEN_CONFIRM);
3431        if (status != -EIO)
3432                nfs_increment_open_seqid(status, res->seqid);
3433        if (status)
3434                return status;
3435        READ_BUF(NFS4_STATEID_SIZE);
3436        COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3437        return 0;
3438}
3439
3440static int decode_open_downgrade(struct xdr_stream *xdr, struct nfs_closeres *res)
3441{
3442        __be32 *p;
3443        int status;
3444
3445        status = decode_op_hdr(xdr, OP_OPEN_DOWNGRADE);
3446        if (status != -EIO)
3447                nfs_increment_open_seqid(status, res->seqid);
3448        if (status)
3449                return status;
3450        READ_BUF(NFS4_STATEID_SIZE);
3451        COPYMEM(res->stateid.data, NFS4_STATEID_SIZE);
3452        return 0;
3453}
3454
3455static int decode_putfh(struct xdr_stream *xdr)
3456{
3457        return decode_op_hdr(xdr, OP_PUTFH);
3458}
3459
3460static int decode_putrootfh(struct xdr_stream *xdr)
3461{
3462        return decode_op_hdr(xdr, OP_PUTROOTFH);
3463}
3464
3465static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_readres *res)
3466{
3467        struct kvec *iov = req->rq_rcv_buf.head;
3468        __be32 *p;
3469        uint32_t count, eof, recvd, hdrlen;
3470        int status;
3471
3472        status = decode_op_hdr(xdr, OP_READ);
3473        if (status)
3474                return status;
3475        READ_BUF(8);
3476        READ32(eof);
3477        READ32(count);
3478        hdrlen = (u8 *) p - (u8 *) iov->iov_base;
3479        recvd = req->rq_rcv_buf.len - hdrlen;
3480        if (count > recvd) {
3481                dprintk("NFS: server cheating in read reply: "
3482                                "count %u > recvd %u\n", count, recvd);
3483                count = recvd;
3484                eof = 0;
3485        }
3486        xdr_read_pages(xdr, count);
3487        res->eof = eof;
3488        res->count = count;
3489        return 0;
3490}
3491
3492static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir)
3493{
3494        struct xdr_buf  *rcvbuf = &req->rq_rcv_buf;
3495        struct page     *page = *rcvbuf->pages;
3496        struct kvec     *iov = rcvbuf->head;
3497        size_t          hdrlen;
3498        u32             recvd, pglen = rcvbuf->page_len;
3499        __be32          *end, *entry, *p, *kaddr;
3500        unsigned int    nr = 0;
3501        int             status;
3502
3503        status = decode_op_hdr(xdr, OP_READDIR);
3504        if (status)
3505                return status;
3506        READ_BUF(8);
3507        COPYMEM(readdir->verifier.data, 8);
3508        dprintk("%s: verifier = %08x:%08x\n",
3509                        __func__,
3510                        ((u32 *)readdir->verifier.data)[0],
3511                        ((u32 *)readdir->verifier.data)[1]);
3512
3513
3514        hdrlen = (char *) p - (char *) iov->iov_base;
3515        recvd = rcvbuf->len - hdrlen;
3516        if (pglen > recvd)
3517                pglen = recvd;
3518        xdr_read_pages(xdr, pglen);
3519
3520        BUG_ON(pglen + readdir->pgbase > PAGE_CACHE_SIZE);
3521        kaddr = p = kmap_atomic(page, KM_USER0);
3522        end = p + ((pglen + readdir->pgbase) >> 2);
3523        entry = p;
3524
3525        /* Make sure the packet actually has a value_follows and EOF entry */
3526        if ((entry + 1) > end)
3527                goto short_pkt;
3528
3529        for (; *p++; nr++) {
3530                u32 len, attrlen, xlen;
3531                if (end - p < 3)
3532                        goto short_pkt;
3533                dprintk("cookie = %Lu, ", *((unsigned long long *)p));
3534                p += 2;                 /* cookie */
3535                len = ntohl(*p++);      /* filename length */
3536                if (len > NFS4_MAXNAMLEN) {
3537                        dprintk("NFS: giant filename in readdir (len 0x%x)\n",
3538                                        len);
3539                        goto err_unmap;
3540                }
3541                xlen = XDR_QUADLEN(len);
3542                if (end - p < xlen + 1)
3543                        goto short_pkt;
3544                dprintk("filename = %*s\n", len, (char *)p);
3545                p += xlen;
3546                len = ntohl(*p++);      /* bitmap length */
3547                if (end - p < len + 1)
3548                        goto short_pkt;
3549                p += len;
3550                attrlen = XDR_QUADLEN(ntohl(*p++));
3551                if (end - p < attrlen + 2)
3552                        goto short_pkt;
3553                p += attrlen;           /* attributes */
3554                entry = p;
3555        }
3556        /*
3557         * Apparently some server sends responses that are a valid size, but
3558         * contain no entries, and have value_follows==0 and EOF==0. For
3559         * those, just set the EOF marker.
3560         */
3561        if (!nr && entry[1] == 0) {
3562                dprintk("NFS: readdir reply truncated!\n");
3563                entry[1] = 1;
3564        }
3565out:    
3566        kunmap_atomic(kaddr, KM_USER0);
3567        return 0;
3568short_pkt:
3569        /*
3570         * When we get a short packet there are 2 possibilities. We can
3571         * return an error, or fix up the response to look like a valid
3572         * response and return what we have so far. If there are no
3573         * entries and the packet was short, then return -EIO. If there
3574         * are valid entries in the response, return them and pretend that
3575         * the call was successful, but incomplete. The caller can retry the
3576         * readdir starting at the last cookie.
3577         */
3578        dprintk("%s: short packet at entry %d\n", __func__, nr);
3579        entry[0] = entry[1] = 0;
3580        if (nr)
3581                goto out;
3582err_unmap:
3583        kunmap_atomic(kaddr, KM_USER0);
3584        return -errno_NFSERR_IO;
3585}
3586
3587static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
3588{
3589        struct xdr_buf *rcvbuf = &req->rq_rcv_buf;
3590        struct kvec *iov = rcvbuf->head;
3591        size_t hdrlen;
3592        u32 len, recvd;
3593        __be32 *p;
3594        char *kaddr;
3595        int status;
3596
3597        status = decode_op_hdr(xdr, OP_READLINK);
3598        if (status)
3599                return status;
3600
3601        /* Convert length of symlink */
3602        READ_BUF(4);
3603        READ32(len);
3604        if (len >= rcvbuf->page_len || len <= 0) {
3605                dprintk("nfs: server returned giant symlink!\n");
3606                return -ENAMETOOLONG;
3607        }
3608        hdrlen = (char *) xdr->p - (char *) iov->iov_base;
3609        recvd = req->rq_rcv_buf.len - hdrlen;
3610        if (recvd < len) {
3611                dprintk("NFS: server cheating in readlink reply: "
3612                                "count %u > recvd %u\n", len, recvd);
3613                return -EIO;
3614        }
3615        xdr_read_pages(xdr, len);
3616        /*
3617         * The XDR encode routine has set things up so that
3618         * the link text will be copied directly into the
3619         * buffer.  We just have to do overflow-checking,
3620         * and and null-terminate the text (the VFS expects
3621         * null-termination).
3622         */
3623        kaddr = (char *)kmap_atomic(rcvbuf->pages[0], KM_USER0);
3624        kaddr[len+rcvbuf->page_base] = '\0';
3625        kunmap_atomic(kaddr, KM_USER0);
3626        return 0;
3627}
3628
3629static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo)
3630{
3631        int status;
3632
3633        status = decode_op_hdr(xdr, OP_REMOVE);
3634        if (status)
3635                goto out;
3636        status = decode_change_info(xdr, cinfo);
3637out:
3638        return status;
3639}
3640
3641static int decode_rename(struct xdr_stream *xdr, struct nfs4_change_info *old_cinfo,
3642              struct nfs4_change_info *new_cinfo)
3643{
3644        int status;
3645
3646        status = decode_op_hdr(xdr, OP_RENAME);
3647        if (status)
3648                goto out;
3649        if ((status = decode_change_info(xdr, old_cinfo)))
3650                goto out;
3651        status = decode_change_info(xdr, new_cinfo);
3652out:
3653        return status;
3654}
3655
3656static int decode_renew(struct xdr_stream *xdr)
3657{
3658        return decode_op_hdr(xdr, OP_RENEW);
3659}
3660
3661static int
3662decode_restorefh(struct xdr_stream *xdr)
3663{
3664        return decode_op_hdr(xdr, OP_RESTOREFH);
3665}
3666
3667static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req,
3668                size_t *acl_len)
3669{
3670        __be32 *savep;
3671        uint32_t attrlen,
3672                 bitmap[2] = {0};
3673        struct kvec *iov = req->rq_rcv_buf.head;
3674        int status;
3675
3676        *acl_len = 0;
3677        if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0)
3678                goto out;
3679        if ((status = decode_attr_bitmap(xdr, bitmap)) != 0)
3680                goto out;
3681        if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0)
3682                goto out;
3683
3684        if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U)))
3685                return -EIO;
3686        if (likely(bitmap[0] & FATTR4_WORD0_ACL)) {
3687                size_t hdrlen;
3688                u32 recvd;
3689
3690                /* We ignore &savep and don't do consistency checks on
3691                 * the attr length.  Let userspace figure it out.... */
3692                hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base;
3693                recvd = req->rq_rcv_buf.len - hdrlen;
3694                if (attrlen > recvd) {
3695                        dprintk("NFS: server cheating in getattr"
3696                                        " acl reply: attrlen %u > recvd %u\n",
3697                                        attrlen, recvd);
3698                        return -EINVAL;
3699                }
3700                xdr_read_pages(xdr, attrlen);
3701                *acl_len = attrlen;
3702        } else
3703                status = -EOPNOTSUPP;
3704
3705out:
3706        return status;
3707}
3708
3709static int
3710decode_savefh(struct xdr_stream *xdr)
3711{
3712        return decode_op_hdr(xdr, OP_SAVEFH);
3713}
3714
3715static int decode_setattr(struct xdr_stream *xdr, struct nfs_setattrres *res)
3716{
3717        __be32 *p;
3718        uint32_t bmlen;
3719        int status;
3720
3721        
3722        status = decode_op_hdr(xdr, OP_SETATTR);
3723        if (status)
3724                return status;
3725        READ_BUF(4);
3726        READ32(bmlen);
3727        READ_BUF(bmlen << 2);
3728        return 0;
3729}
3730
3731static int decode_setclientid(struct xdr_stream *xdr, struct nfs_client *clp)
3732{
3733        __be32 *p;
3734        uint32_t opnum;
3735        int32_t nfserr;
3736
3737        READ_BUF(8);
3738        READ32(opnum);
3739        if (opnum != OP_SETCLIENTID) {
3740                dprintk("nfs: decode_setclientid: Server returned operation"
3741                                " %d\n", opnum);
3742                return -EIO;
3743        }
3744        READ32(nfserr);
3745        if (nfserr == NFS_OK) {
3746                READ_BUF(8 + NFS4_VERIFIER_SIZE);
3747                READ64(clp->cl_clientid);
3748                COPYMEM(clp->cl_confirm.data, NFS4_VERIFIER_SIZE);
3749        } else if (nfserr == NFSERR_CLID_INUSE) {
3750                uint32_t len;
3751
3752                /* skip netid string */
3753                READ_BUF(4);
3754                READ32(len);
3755                READ_BUF(len);
3756
3757                /* skip uaddr string */
3758                READ_BUF(4);
3759                READ32(len);
3760                READ_BUF(len);
3761                return -NFSERR_CLID_INUSE;
3762        } else
3763                return nfs4_stat_to_errno(nfserr);
3764
3765        return 0;
3766}
3767
3768static int decode_setclientid_confirm(struct xdr_stream *xdr)
3769{
3770        return decode_op_hdr(xdr, OP_SETCLIENTID_CONFIRM);
3771}
3772
3773static int decode_write(struct xdr_stream *xdr, struct nfs_writeres *res)
3774{
3775        __be32 *p;
3776        int status;
3777
3778        status = decode_op_hdr(xdr, OP_WRITE);
3779        if (status)
3780                return status;
3781
3782        READ_BUF(16);
3783        READ32(res->count);
3784        READ32(res->verf->committed);
3785        COPYMEM(res->verf->verifier, 8);
3786        return 0;
3787}
3788
3789static int decode_delegreturn(struct xdr_stream *xdr)
3790{
3791        return decode_op_hdr(xdr, OP_DELEGRETURN);
3792}
3793
3794/*
3795 * Decode OPEN_DOWNGRADE response
3796 */
3797static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res)
3798{
3799        struct xdr_stream xdr;
3800        struct compound_hdr hdr;
3801        int status;
3802
3803        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3804        status = decode_compound_hdr(&xdr, &hdr);
3805        if (status)
3806                goto out;
3807        status = decode_putfh(&xdr);
3808        if (status)
3809                goto out;
3810        status = decode_open_downgrade(&xdr, res);
3811        if (status != 0)
3812                goto out;
3813        decode_getfattr(&xdr, res->fattr, res->server);
3814out:
3815        return status;
3816}
3817
3818/*
3819 * END OF "GENERIC" DECODE ROUTINES.
3820 */
3821
3822/*
3823 * Decode ACCESS response
3824 */
3825static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_accessres *res)
3826{
3827        struct xdr_stream xdr;
3828        struct compound_hdr hdr;
3829        int status;
3830        
3831        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3832        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3833                goto out;
3834        status = decode_putfh(&xdr);
3835        if (status != 0)
3836                goto out;
3837        status = decode_access(&xdr, res);
3838        if (status != 0)
3839                goto out;
3840        decode_getfattr(&xdr, res->fattr, res->server);
3841out:
3842        return status;
3843}
3844
3845/*
3846 * Decode LOOKUP response
3847 */
3848static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res)
3849{
3850        struct xdr_stream xdr;
3851        struct compound_hdr hdr;
3852        int status;
3853        
3854        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3855        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3856                goto out;
3857        if ((status = decode_putfh(&xdr)) != 0)
3858                goto out;
3859        if ((status = decode_lookup(&xdr)) != 0)
3860                goto out;
3861        if ((status = decode_getfh(&xdr, res->fh)) != 0)
3862                goto out;
3863        status = decode_getfattr(&xdr, res->fattr, res->server);
3864out:
3865        return status;
3866}
3867
3868/*
3869 * Decode LOOKUP_ROOT response
3870 */
3871static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res)
3872{
3873        struct xdr_stream xdr;
3874        struct compound_hdr hdr;
3875        int status;
3876        
3877        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3878        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3879                goto out;
3880        if ((status = decode_putrootfh(&xdr)) != 0)
3881                goto out;
3882        if ((status = decode_getfh(&xdr, res->fh)) == 0)
3883                status = decode_getfattr(&xdr, res->fattr, res->server);
3884out:
3885        return status;
3886}
3887
3888/*
3889 * Decode REMOVE response
3890 */
3891static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_removeres *res)
3892{
3893        struct xdr_stream xdr;
3894        struct compound_hdr hdr;
3895        int status;
3896        
3897        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3898        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3899                goto out;
3900        if ((status = decode_putfh(&xdr)) != 0)
3901                goto out;
3902        if ((status = decode_remove(&xdr, &res->cinfo)) != 0)
3903                goto out;
3904        decode_getfattr(&xdr, &res->dir_attr, res->server);
3905out:
3906        return status;
3907}
3908
3909/*
3910 * Decode RENAME response
3911 */
3912static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_rename_res *res)
3913{
3914        struct xdr_stream xdr;
3915        struct compound_hdr hdr;
3916        int status;
3917        
3918        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3919        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3920                goto out;
3921        if ((status = decode_putfh(&xdr)) != 0)
3922                goto out;
3923        if ((status = decode_savefh(&xdr)) != 0)
3924                goto out;
3925        if ((status = decode_putfh(&xdr)) != 0)
3926                goto out;
3927        if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0)
3928                goto out;
3929        /* Current FH is target directory */
3930        if (decode_getfattr(&xdr, res->new_fattr, res->server) != 0)
3931                goto out;
3932        if ((status = decode_restorefh(&xdr)) != 0)
3933                goto out;
3934        decode_getfattr(&xdr, res->old_fattr, res->server);
3935out:
3936        return status;
3937}
3938
3939/*
3940 * Decode LINK response
3941 */
3942static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link_res *res)
3943{
3944        struct xdr_stream xdr;
3945        struct compound_hdr hdr;
3946        int status;
3947        
3948        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3949        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3950                goto out;
3951        if ((status = decode_putfh(&xdr)) != 0)
3952                goto out;
3953        if ((status = decode_savefh(&xdr)) != 0)
3954                goto out;
3955        if ((status = decode_putfh(&xdr)) != 0)
3956                goto out;
3957        if ((status = decode_link(&xdr, &res->cinfo)) != 0)
3958                goto out;
3959        /*
3960         * Note order: OP_LINK leaves the directory as the current
3961         *             filehandle.
3962         */
3963        if (decode_getfattr(&xdr, res->dir_attr, res->server) != 0)
3964                goto out;
3965        if ((status = decode_restorefh(&xdr)) != 0)
3966                goto out;
3967        decode_getfattr(&xdr, res->fattr, res->server);
3968out:
3969        return status;
3970}
3971
3972/*
3973 * Decode CREATE response
3974 */
3975static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res)
3976{
3977        struct xdr_stream xdr;
3978        struct compound_hdr hdr;
3979        int status;
3980        
3981        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
3982        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
3983                goto out;
3984        if ((status = decode_putfh(&xdr)) != 0)
3985                goto out;
3986        if ((status = decode_savefh(&xdr)) != 0)
3987                goto out;
3988        if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0)
3989                goto out;
3990        if ((status = decode_getfh(&xdr, res->fh)) != 0)
3991                goto out;
3992        if (decode_getfattr(&xdr, res->fattr, res->server) != 0)
3993                goto out;
3994        if ((status = decode_restorefh(&xdr)) != 0)
3995                goto out;
3996        decode_getfattr(&xdr, res->dir_fattr, res->server);
3997out:
3998        return status;
3999}
4000
4001/*
4002 * Decode SYMLINK response
4003 */
4004static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res)
4005{
4006        return nfs4_xdr_dec_create(rqstp, p, res);
4007}
4008
4009/*
4010 * Decode GETATTR response
4011 */
4012static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_getattr_res *res)
4013{
4014        struct xdr_stream xdr;
4015        struct compound_hdr hdr;
4016        int status;
4017        
4018        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4019        status = decode_compound_hdr(&xdr, &hdr);
4020        if (status)
4021                goto out;
4022        status = decode_putfh(&xdr);
4023        if (status)
4024                goto out;
4025        status = decode_getfattr(&xdr, res->fattr, res->server);
4026out:
4027        return status;
4028
4029}
4030
4031/*
4032 * Encode an SETACL request
4033 */
4034static int
4035nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args)
4036{
4037        struct xdr_stream xdr;
4038        struct compound_hdr hdr = {
4039                .nops   = 2,
4040        };
4041        int status;
4042
4043        xdr_init_encode(&xdr, &req->rq_snd_buf, p);
4044        encode_compound_hdr(&xdr, &hdr);
4045        status = encode_putfh(&xdr, args->fh);
4046        if (status)
4047                goto out;
4048        status = encode_setacl(&xdr, args);
4049out:
4050        return status;
4051}
4052/*
4053 * Decode SETACL response
4054 */
4055static int
4056nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, void *res)
4057{
4058        struct xdr_stream xdr;
4059        struct compound_hdr hdr;
4060        int status;
4061
4062        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4063        status = decode_compound_hdr(&xdr, &hdr);
4064        if (status)
4065                goto out;
4066        status = decode_putfh(&xdr);
4067        if (status)
4068                goto out;
4069        status = decode_setattr(&xdr, res);
4070out:
4071        return status;
4072}
4073
4074/*
4075 * Decode GETACL response
4076 */
4077static int
4078nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, size_t *acl_len)
4079{
4080        struct xdr_stream xdr;
4081        struct compound_hdr hdr;
4082        int status;
4083
4084        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4085        status = decode_compound_hdr(&xdr, &hdr);
4086        if (status)
4087                goto out;
4088        status = decode_putfh(&xdr);
4089        if (status)
4090                goto out;
4091        status = decode_getacl(&xdr, rqstp, acl_len);
4092
4093out:
4094        return status;
4095}
4096
4097/*
4098 * Decode CLOSE response
4099 */
4100static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res)
4101{
4102        struct xdr_stream xdr;
4103        struct compound_hdr hdr;
4104        int status;
4105
4106        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4107        status = decode_compound_hdr(&xdr, &hdr);
4108        if (status)
4109                goto out;
4110        status = decode_putfh(&xdr);
4111        if (status)
4112                goto out;
4113        status = decode_close(&xdr, res);
4114        if (status != 0)
4115                goto out;
4116        /*
4117         * Note: Server may do delete on close for this file
4118         *      in which case the getattr call will fail with
4119         *      an ESTALE error. Shouldn't be a problem,
4120         *      though, since fattr->valid will remain unset.
4121         */
4122        decode_getfattr(&xdr, res->fattr, res->server);
4123out:
4124        return status;
4125}
4126
4127/*
4128 * Decode OPEN response
4129 */
4130static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
4131{
4132        struct xdr_stream xdr;
4133        struct compound_hdr hdr;
4134        int status;
4135
4136        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4137        status = decode_compound_hdr(&xdr, &hdr);
4138        if (status)
4139                goto out;
4140        status = decode_putfh(&xdr);
4141        if (status)
4142                goto out;
4143        status = decode_savefh(&xdr);
4144        if (status)
4145                goto out;
4146        status = decode_open(&xdr, res);
4147        if (status)
4148                goto out;
4149        if (decode_getfh(&xdr, &res->fh) != 0)
4150                goto out;
4151        if (decode_getfattr(&xdr, res->f_attr, res->server) != 0)
4152                goto out;
4153        if (decode_restorefh(&xdr) != 0)
4154                goto out;
4155        decode_getfattr(&xdr, res->dir_attr, res->server);
4156out:
4157        return status;
4158}
4159
4160/*
4161 * Decode OPEN_CONFIRM response
4162 */
4163static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct nfs_open_confirmres *res)
4164{
4165        struct xdr_stream xdr;
4166        struct compound_hdr hdr;
4167        int status;
4168
4169        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4170        status = decode_compound_hdr(&xdr, &hdr);
4171        if (status)
4172                goto out;
4173        status = decode_putfh(&xdr);
4174        if (status)
4175                goto out;
4176        status = decode_open_confirm(&xdr, res);
4177out:
4178        return status;
4179}
4180
4181/*
4182 * Decode OPEN response
4183 */
4184static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res)
4185{
4186        struct xdr_stream xdr;
4187        struct compound_hdr hdr;
4188        int status;
4189
4190        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4191        status = decode_compound_hdr(&xdr, &hdr);
4192        if (status)
4193                goto out;
4194        status = decode_putfh(&xdr);
4195        if (status)
4196                goto out;
4197        status = decode_open(&xdr, res);
4198        if (status)
4199                goto out;
4200        decode_getfattr(&xdr, res->f_attr, res->server);
4201out:
4202        return status;
4203}
4204
4205/*
4206 * Decode SETATTR response
4207 */
4208static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_setattrres *res)
4209{
4210        struct xdr_stream xdr;
4211        struct compound_hdr hdr;
4212        int status;
4213
4214        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4215        status = decode_compound_hdr(&xdr, &hdr);
4216        if (status)
4217                goto out;
4218        status = decode_putfh(&xdr);
4219        if (status)
4220                goto out;
4221        status = decode_setattr(&xdr, res);
4222        if (status)
4223                goto out;
4224        status = decode_getfattr(&xdr, res->fattr, res->server);
4225        if (status == NFS4ERR_DELAY)
4226                status = 0;
4227out:
4228        return status;
4229}
4230
4231/*
4232 * Decode LOCK response
4233 */
4234static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_res *res)
4235{
4236        struct xdr_stream xdr;
4237        struct compound_hdr hdr;
4238        int status;
4239
4240        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4241        status = decode_compound_hdr(&xdr, &hdr);
4242        if (status)
4243                goto out;
4244        status = decode_putfh(&xdr);
4245        if (status)
4246                goto out;
4247        status = decode_lock(&xdr, res);
4248out:
4249        return status;
4250}
4251
4252/*
4253 * Decode LOCKT response
4254 */
4255static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lockt_res *res)
4256{
4257        struct xdr_stream xdr;
4258        struct compound_hdr hdr;
4259        int status;
4260
4261        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4262        status = decode_compound_hdr(&xdr, &hdr);
4263        if (status)
4264                goto out;
4265        status = decode_putfh(&xdr);
4266        if (status)
4267                goto out;
4268        status = decode_lockt(&xdr, res);
4269out:
4270        return status;
4271}
4272
4273/*
4274 * Decode LOCKU response
4275 */
4276static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_locku_res *res)
4277{
4278        struct xdr_stream xdr;
4279        struct compound_hdr hdr;
4280        int status;
4281
4282        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4283        status = decode_compound_hdr(&xdr, &hdr);
4284        if (status)
4285                goto out;
4286        status = decode_putfh(&xdr);
4287        if (status)
4288                goto out;
4289        status = decode_locku(&xdr, res);
4290out:
4291        return status;
4292}
4293
4294/*
4295 * Decode READLINK response
4296 */
4297static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, void *res)
4298{
4299        struct xdr_stream xdr;
4300        struct compound_hdr hdr;
4301        int status;
4302
4303        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4304        status = decode_compound_hdr(&xdr, &hdr);
4305        if (status)
4306                goto out;
4307        status = decode_putfh(&xdr);
4308        if (status)
4309                goto out;
4310        status = decode_readlink(&xdr, rqstp);
4311out:
4312        return status;
4313}
4314
4315/*
4316 * Decode READDIR response
4317 */
4318static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_readdir_res *res)
4319{
4320        struct xdr_stream xdr;
4321        struct compound_hdr hdr;
4322        int status;
4323
4324        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4325        status = decode_compound_hdr(&xdr, &hdr);
4326        if (status)
4327                goto out;
4328        status = decode_putfh(&xdr);
4329        if (status)
4330                goto out;
4331        status = decode_readdir(&xdr, rqstp, res);
4332out:
4333        return status;
4334}
4335
4336/*
4337 * Decode Read response
4338 */
4339static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readres *res)
4340{
4341        struct xdr_stream xdr;
4342        struct compound_hdr hdr;
4343        int status;
4344
4345        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4346        status = decode_compound_hdr(&xdr, &hdr);
4347        if (status)
4348                goto out;
4349        status = decode_putfh(&xdr);
4350        if (status)
4351                goto out;
4352        status = decode_read(&xdr, rqstp, res);
4353        if (!status)
4354                status = res->count;
4355out:
4356        return status;
4357}
4358
4359/*
4360 * Decode WRITE response
4361 */
4362static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res)
4363{
4364        struct xdr_stream xdr;
4365        struct compound_hdr hdr;
4366        int status;
4367
4368        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4369        status = decode_compound_hdr(&xdr, &hdr);
4370        if (status)
4371                goto out;
4372        status = decode_putfh(&xdr);
4373        if (status)
4374                goto out;
4375        status = decode_write(&xdr, res);
4376        if (status)
4377                goto out;
4378        decode_getfattr(&xdr, res->fattr, res->server);
4379        if (!status)
4380                status = res->count;
4381out:
4382        return status;
4383}
4384
4385/*
4386 * Decode COMMIT response
4387 */
4388static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res)
4389{
4390        struct xdr_stream xdr;
4391        struct compound_hdr hdr;
4392        int status;
4393
4394        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4395        status = decode_compound_hdr(&xdr, &hdr);
4396        if (status)
4397                goto out;
4398        status = decode_putfh(&xdr);
4399        if (status)
4400                goto out;
4401        status = decode_commit(&xdr, res);
4402        if (status)
4403                goto out;
4404        decode_getfattr(&xdr, res->fattr, res->server);
4405out:
4406        return status;
4407}
4408
4409/*
4410 * FSINFO request
4411 */
4412static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
4413{
4414        struct xdr_stream xdr;
4415        struct compound_hdr hdr;
4416        int status;
4417
4418        xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4419        status = decode_compound_hdr(&xdr, &hdr);
4420        if (!status)
4421                status = decode_putfh(&xdr);
4422        if (!status)
4423                status = decode_fsinfo(&xdr, fsinfo);
4424        if (!status)
4425                status = nfs4_stat_to_errno(hdr.status);
4426        return status;
4427}
4428
4429/*
4430 * PATHCONF request
4431 */
4432static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *pathconf)
4433{
4434        struct xdr_stream xdr;
4435        struct compound_hdr hdr;
4436        int status;
4437
4438        xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4439        status = decode_compound_hdr(&xdr, &hdr);
4440        if (!status)
4441                status = decode_putfh(&xdr);
4442        if (!status)
4443                status = decode_pathconf(&xdr, pathconf);
4444        return status;
4445}
4446
4447/*
4448 * STATFS request
4449 */
4450static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *fsstat)
4451{
4452        struct xdr_stream xdr;
4453        struct compound_hdr hdr;
4454        int status;
4455
4456        xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4457        status = decode_compound_hdr(&xdr, &hdr);
4458        if (!status)
4459                status = decode_putfh(&xdr);
4460        if (!status)
4461                status = decode_statfs(&xdr, fsstat);
4462        return status;
4463}
4464
4465/*
4466 * GETATTR_BITMAP request
4467 */
4468static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4_server_caps_res *res)
4469{
4470        struct xdr_stream xdr;
4471        struct compound_hdr hdr;
4472        int status;
4473
4474        xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4475        if ((status = decode_compound_hdr(&xdr, &hdr)) != 0)
4476                goto out;
4477        if ((status = decode_putfh(&xdr)) != 0)
4478                goto out;
4479        status = decode_server_caps(&xdr, res);
4480out:
4481        return status;
4482}
4483
4484/*
4485 * Decode RENEW response
4486 */
4487static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
4488{
4489        struct xdr_stream xdr;
4490        struct compound_hdr hdr;
4491        int status;
4492
4493        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4494        status = decode_compound_hdr(&xdr, &hdr);
4495        if (!status)
4496                status = decode_renew(&xdr);
4497        return status;
4498}
4499
4500/*
4501 * a SETCLIENTID request
4502 */
4503static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p,
4504                struct nfs_client *clp)
4505{
4506        struct xdr_stream xdr;
4507        struct compound_hdr hdr;
4508        int status;
4509
4510        xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4511        status = decode_compound_hdr(&xdr, &hdr);
4512        if (!status)
4513                status = decode_setclientid(&xdr, clp);
4514        if (!status)
4515                status = nfs4_stat_to_errno(hdr.status);
4516        return status;
4517}
4518
4519/*
4520 * a SETCLIENTID_CONFIRM request
4521 */
4522static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo)
4523{
4524        struct xdr_stream xdr;
4525        struct compound_hdr hdr;
4526        int status;
4527
4528        xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4529        status = decode_compound_hdr(&xdr, &hdr);
4530        if (!status)
4531                status = decode_setclientid_confirm(&xdr);
4532        if (!status)
4533                status = decode_putrootfh(&xdr);
4534        if (!status)
4535                status = decode_fsinfo(&xdr, fsinfo);
4536        if (!status)
4537                status = nfs4_stat_to_errno(hdr.status);
4538        return status;
4539}
4540
4541/*
4542 * DELEGRETURN request
4543 */
4544static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_delegreturnres *res)
4545{
4546        struct xdr_stream xdr;
4547        struct compound_hdr hdr;
4548        int status;
4549
4550        xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
4551        status = decode_compound_hdr(&xdr, &hdr);
4552        if (status != 0)
4553                goto out;
4554        status = decode_putfh(&xdr);
4555        if (status != 0)
4556                goto out;
4557        status = decode_delegreturn(&xdr);
4558        decode_getfattr(&xdr, res->fattr, res->server);
4559out:
4560        return status;
4561}
4562
4563/*
4564 * FS_LOCATIONS request
4565 */
4566static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations *res)
4567{
4568        struct xdr_stream xdr;
4569        struct compound_hdr hdr;
4570        int status;
4571
4572        xdr_init_decode(&xdr, &req->rq_rcv_buf, p);
4573        status = decode_compound_hdr(&xdr, &hdr);
4574        if (status != 0)
4575                goto out;
4576        if ((status = decode_putfh(&xdr)) != 0)
4577                goto out;
4578        if ((status = decode_lookup(&xdr)) != 0)
4579                goto out;
4580        xdr_enter_page(&xdr, PAGE_SIZE);
4581        status = decode_getfattr(&xdr, &res->fattr, res->server);
4582out:
4583        return status;
4584}
4585
4586__be32 *nfs4_decode_dirent(__be32 *p, struct nfs_entry *entry, int plus)
4587{
4588        uint32_t bitmap[2] = {0};
4589        uint32_t len;
4590
4591        if (!*p++) {
4592                if (!*p)
4593                        return ERR_PTR(-EAGAIN);
4594                entry->eof = 1;
4595                return ERR_PTR(-EBADCOOKIE);
4596        }
4597
4598        entry->prev_cookie = entry->cookie;
4599        p = xdr_decode_hyper(p, &entry->cookie);
4600        entry->len = ntohl(*p++);
4601        entry->name = (const char *) p;
4602        p += XDR_QUADLEN(entry->len);
4603
4604        /*
4605         * In case the server doesn't return an inode number,
4606         * we fake one here.  (We don't use inode number 0,
4607         * since glibc seems to choke on it...)
4608         */
4609        entry->ino = 1;
4610
4611        len = ntohl(*p++);              /* bitmap length */
4612        if (len-- > 0) {
4613                bitmap[0] = ntohl(*p++);
4614                if (len-- > 0) {
4615                        bitmap[1] = ntohl(*p++);
4616                        p += len;
4617                }
4618        }
4619        len = XDR_QUADLEN(ntohl(*p++)); /* attribute buffer length */
4620        if (len > 0) {
4621                if (bitmap[0] & FATTR4_WORD0_RDATTR_ERROR) {
4622                        bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR;
4623                        /* Ignore the return value of rdattr_error for now */
4624                        p++;
4625                        len--;
4626                }
4627                if (bitmap[0] == 0 && bitmap[1] == FATTR4_WORD1_MOUNTED_ON_FILEID)
4628                        xdr_decode_hyper(p, &entry->ino);
4629                else if (bitmap[0] == FATTR4_WORD0_FILEID)
4630                        xdr_decode_hyper(p, &entry->ino);
4631                p += len;
4632        }
4633
4634        entry->eof = !p[0] && p[1];
4635        return p;
4636}
4637
4638/*
4639 * We need to translate between nfs status return values and
4640 * the local errno values which may not be the same.
4641 */
4642static struct {
4643        int stat;
4644        int errno;
4645} nfs_errtbl[] = {
4646        { NFS4_OK,              0               },
4647        { NFS4ERR_PERM,         -EPERM          },
4648        { NFS4ERR_NOENT,        -ENOENT         },
4649        { NFS4ERR_IO,           -errno_NFSERR_IO},
4650        { NFS4ERR_NXIO,         -ENXIO          },
4651        { NFS4ERR_ACCESS,       -EACCES         },
4652        { NFS4ERR_EXIST,        -EEXIST         },
4653        { NFS4ERR_XDEV,         -EXDEV          },
4654        { NFS4ERR_NOTDIR,       -ENOTDIR        },
4655        { NFS4ERR_ISDIR,        -EISDIR         },
4656        { NFS4ERR_INVAL,        -EINVAL         },
4657        { NFS4ERR_FBIG,         -EFBIG          },
4658        { NFS4ERR_NOSPC,        -ENOSPC         },
4659        { NFS4ERR_ROFS,         -EROFS          },
4660        { NFS4ERR_MLINK,        -EMLINK         },
4661        { NFS4ERR_NAMETOOLONG,  -ENAMETOOLONG   },
4662        { NFS4ERR_NOTEMPTY,     -ENOTEMPTY      },
4663        { NFS4ERR_DQUOT,        -EDQUOT         },
4664        { NFS4ERR_STALE,        -ESTALE         },
4665        { NFS4ERR_BADHANDLE,    -EBADHANDLE     },
4666        { NFS4ERR_BADOWNER,     -EINVAL         },
4667        { NFS4ERR_BADNAME,      -EINVAL         },
4668        { NFS4ERR_BAD_COOKIE,   -EBADCOOKIE     },
4669        { NFS4ERR_NOTSUPP,      -ENOTSUPP       },
4670        { NFS4ERR_TOOSMALL,     -ETOOSMALL      },
4671        { NFS4ERR_SERVERFAULT,  -ESERVERFAULT   },
4672        { NFS4ERR_BADTYPE,      -EBADTYPE       },
4673        { NFS4ERR_LOCKED,       -EAGAIN         },
4674        { NFS4ERR_RESOURCE,     -EREMOTEIO      },
4675        { NFS4ERR_SYMLINK,      -ELOOP          },
4676        { NFS4ERR_OP_ILLEGAL,   -EOPNOTSUPP     },
4677        { NFS4ERR_DEADLOCK,     -EDEADLK        },
4678        { NFS4ERR_WRONGSEC,     -EPERM          }, /* FIXME: this needs
4679                                                    * to be handled by a
4680                                                    * middle-layer.
4681                                                    */
4682        { -1,                   -EIO            }
4683};
4684
4685/*
4686 * Convert an NFS error code to a local one.
4687 * This one is used jointly by NFSv2 and NFSv3.
4688 */
4689static int
4690nfs4_stat_to_errno(int stat)
4691{
4692        int i;
4693        for (i = 0; nfs_errtbl[i].stat != -1; i++) {
4694                if (nfs_errtbl[i].stat == stat)
4695                        return nfs_errtbl[i].errno;
4696        }
4697        if (stat <= 10000 || stat > 10100) {
4698                /* The server is looney tunes. */
4699                return -ESERVERFAULT;
4700        }
4701        /* If we cannot translate the error, the recovery routines should
4702         * handle it.
4703         * Note: remaining NFSv4 error codes have values > 10000, so should
4704         * not conflict with native Linux error codes.
4705         */
4706        return -stat;
4707}
4708
4709#define PROC(proc, argtype, restype)                            \
4710[NFSPROC4_CLNT_##proc] = {                                      \
4711        .p_proc   = NFSPROC4_COMPOUND,                          \
4712        .p_encode = (kxdrproc_t) nfs4_xdr_##argtype,            \
4713        .p_decode = (kxdrproc_t) nfs4_xdr_##restype,            \
4714        .p_arglen = NFS4_##argtype##_sz,                        \
4715        .p_replen = NFS4_##restype##_sz,                        \
4716        .p_statidx = NFSPROC4_CLNT_##proc,                      \
4717        .p_name   = #proc,                                      \
4718    }
4719
4720struct rpc_procinfo     nfs4_procedures[] = {
4721  PROC(READ,            enc_read,       dec_read),
4722  PROC(WRITE,           enc_write,      dec_write),
4723  PROC(COMMIT,          enc_commit,     dec_commit),
4724  PROC(OPEN,            enc_open,       dec_open),
4725  PROC(OPEN_CONFIRM,    enc_open_confirm,       dec_open_confirm),
4726  PROC(OPEN_NOATTR,     enc_open_noattr,        dec_open_noattr),
4727  PROC(OPEN_DOWNGRADE,  enc_open_downgrade,     dec_open_downgrade),
4728  PROC(CLOSE,           enc_close,      dec_close),
4729  PROC(SETATTR,         enc_setattr,    dec_setattr),
4730  PROC(FSINFO,          enc_fsinfo,     dec_fsinfo),
4731  PROC(RENEW,           enc_renew,      dec_renew),
4732  PROC(SETCLIENTID,     enc_setclientid,        dec_setclientid),
4733  PROC(SETCLIENTID_CONFIRM,     enc_setclientid_confirm,        dec_setclientid_confirm),
4734  PROC(LOCK,            enc_lock,       dec_lock),
4735  PROC(LOCKT,           enc_lockt,      dec_lockt),
4736  PROC(LOCKU,           enc_locku,      dec_locku),
4737  PROC(ACCESS,          enc_access,     dec_access),
4738  PROC(GETATTR,         enc_getattr,    dec_getattr),
4739  PROC(LOOKUP,          enc_lookup,     dec_lookup),
4740  PROC(LOOKUP_ROOT,     enc_lookup_root,        dec_lookup_root),
4741  PROC(REMOVE,          enc_remove,     dec_remove),
4742  PROC(RENAME,          enc_rename,     dec_rename),
4743  PROC(LINK,            enc_link,       dec_link),
4744  PROC(SYMLINK,         enc_symlink,    dec_symlink),
4745  PROC(CREATE,          enc_create,     dec_create),
4746  PROC(PATHCONF,        enc_pathconf,   dec_pathconf),
4747  PROC(STATFS,          enc_statfs,     dec_statfs),
4748  PROC(READLINK,        enc_readlink,   dec_readlink),
4749  PROC(READDIR,         enc_readdir,    dec_readdir),
4750  PROC(SERVER_CAPS,     enc_server_caps, dec_server_caps),
4751  PROC(DELEGRETURN,     enc_delegreturn, dec_delegreturn),
4752  PROC(GETACL,          enc_getacl,     dec_getacl),
4753  PROC(SETACL,          enc_setacl,     dec_setacl),
4754  PROC(FS_LOCATIONS,    enc_fs_locations, dec_fs_locations),
4755};
4756
4757struct rpc_version              nfs_version4 = {
4758        .number                 = 4,
4759        .nrprocs                = ARRAY_SIZE(nfs4_procedures),
4760        .procs                  = nfs4_procedures
4761};
4762
4763/*
4764 * Local variables:
4765 *  c-basic-offset: 8
4766 * End:
4767 */
4768
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.