Print this page
    
OS-20 share_nfs(1m) charset handling is unreliable
OS-22 Page fault at nfscmd_dropped_entrysize+0x1e()
OS-23 NFSv2/3/4: READDIR responses are inconsistent when charset conversion fails
OS-24 rfs3_readdir(): Issues related to nfscmd_convdirent()
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/nfs/nfs_xdr.c
          +++ new/usr/src/uts/common/fs/nfs/nfs_xdr.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
  24   24   */
       25 +/*
       26 + * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
       27 + */
  25   28  
  26   29  /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  27   30  /* All Rights Reserved */
  28   31  
  29   32  #include <sys/param.h>
  30   33  #include <sys/types.h>
  31   34  #include <sys/systm.h>
  32   35  #include <sys/user.h>
  33   36  #include <sys/vnode.h>
  34   37  #include <sys/file.h>
  35   38  #include <sys/dirent.h>
  36   39  #include <sys/vfs.h>
  37   40  #include <sys/stream.h>
  38   41  #include <sys/strsubr.h>
  39   42  #include <sys/debug.h>
  40   43  #include <sys/t_lock.h>
  41   44  #include <sys/sdt.h>
  42   45  
  43   46  #include <rpc/types.h>
  44   47  #include <rpc/xdr.h>
  45   48  
  46   49  #include <nfs/nfs.h>
  47   50  
  48   51  #include <vm/hat.h>
  49   52  #include <vm/as.h>
  50   53  #include <vm/seg.h>
  51   54  #include <vm/seg_map.h>
  52   55  #include <vm/seg_kmem.h>
  53   56  
  54   57  static bool_t xdr_fastshorten(XDR *, uint_t);
  55   58  
  56   59  /*
  57   60   * These are the XDR routines used to serialize and deserialize
  58   61   * the various structures passed as parameters accross the network
  59   62   * between NFS clients and servers.
  60   63   */
  61   64  
  62   65  /*
  63   66   * File access handle
  64   67   * The fhandle struct is treated a opaque data on the wire
  65   68   */
  66   69  bool_t
  67   70  xdr_fhandle(XDR *xdrs, fhandle_t *fh)
  68   71  {
  69   72          int32_t *ptr;
  70   73          int32_t *fhp;
  71   74  
  72   75          if (xdrs->x_op == XDR_FREE)
  73   76                  return (TRUE);
  74   77  
  75   78          ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)));
  76   79          if (ptr != NULL) {
  77   80                  fhp = (int32_t *)fh;
  78   81                  if (xdrs->x_op == XDR_DECODE) {
  79   82                          *fhp++ = *ptr++;
  80   83                          *fhp++ = *ptr++;
  81   84                          *fhp++ = *ptr++;
  82   85                          *fhp++ = *ptr++;
  83   86                          *fhp++ = *ptr++;
  84   87                          *fhp++ = *ptr++;
  85   88                          *fhp++ = *ptr++;
  86   89                          *fhp = *ptr;
  87   90                  } else {
  88   91                          *ptr++ = *fhp++;
  89   92                          *ptr++ = *fhp++;
  90   93                          *ptr++ = *fhp++;
  91   94                          *ptr++ = *fhp++;
  92   95                          *ptr++ = *fhp++;
  93   96                          *ptr++ = *fhp++;
  94   97                          *ptr++ = *fhp++;
  95   98                          *ptr = *fhp;
  96   99                  }
  97  100                  return (TRUE);
  98  101          }
  99  102  
 100  103          return (xdr_opaque(xdrs, (caddr_t)fh, NFS_FHSIZE));
 101  104  }
 102  105  
 103  106  bool_t
 104  107  xdr_fastfhandle(XDR *xdrs, fhandle_t **fh)
 105  108  {
 106  109          int32_t *ptr;
 107  110  
 108  111          if (xdrs->x_op != XDR_DECODE)
 109  112                  return (FALSE);
 110  113  
 111  114          ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)));
 112  115          if (ptr != NULL) {
 113  116                  *fh = (fhandle_t *)ptr;
 114  117                  return (TRUE);
 115  118          }
 116  119  
 117  120          return (FALSE);
 118  121  }
 119  122  
 120  123  /*
 121  124   * Arguments to remote write and writecache
 122  125   */
 123  126  bool_t
 124  127  xdr_writeargs(XDR *xdrs, struct nfswriteargs *wa)
 125  128  {
 126  129          int32_t *ptr;
 127  130          int32_t *fhp;
 128  131  
 129  132          switch (xdrs->x_op) {
 130  133          case XDR_DECODE:
 131  134                  wa->wa_args = &wa->wa_args_buf;
 132  135                  ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
 133  136                      3 * BYTES_PER_XDR_UNIT);
 134  137                  if (ptr != NULL) {
 135  138                          fhp = (int32_t *)&wa->wa_fhandle;
 136  139                          *fhp++ = *ptr++;
 137  140                          *fhp++ = *ptr++;
 138  141                          *fhp++ = *ptr++;
 139  142                          *fhp++ = *ptr++;
 140  143                          *fhp++ = *ptr++;
 141  144                          *fhp++ = *ptr++;
 142  145                          *fhp++ = *ptr++;
 143  146                          *fhp = *ptr++;
 144  147                          wa->wa_begoff = IXDR_GET_U_INT32(ptr);
 145  148                          wa->wa_offset = IXDR_GET_U_INT32(ptr);
 146  149                          wa->wa_totcount = IXDR_GET_U_INT32(ptr);
 147  150                          wa->wa_mblk = NULL;
 148  151                          wa->wa_data = NULL;
 149  152                          wa->wa_rlist = NULL;
 150  153                          wa->wa_conn = NULL;
 151  154                          if (xdrs->x_ops == &xdrmblk_ops) {
 152  155                                  return (xdrmblk_getmblk(xdrs, &wa->wa_mblk,
 153  156                                      &wa->wa_count));
 154  157                          } else {
 155  158                                  if (xdrs->x_ops == &xdrrdmablk_ops) {
 156  159                                          if (xdrrdma_getrdmablk(xdrs,
 157  160                                              &wa->wa_rlist,
 158  161                                              &wa->wa_count,
 159  162                                              &wa->wa_conn,
 160  163                                              NFS_MAXDATA) == TRUE)
 161  164                                          return (xdrrdma_read_from_client(
 162  165                                              wa->wa_rlist,
 163  166                                              &wa->wa_conn,
 164  167                                              wa->wa_count));
 165  168  
 166  169                                          wa->wa_rlist = NULL;
 167  170                                          wa->wa_conn = NULL;
 168  171                                  }
 169  172                          }
 170  173  
 171  174                          /*
 172  175                           * It is just as efficient to xdr_bytes
 173  176                           * an array of unknown length as to inline copy it.
 174  177                           */
 175  178                          return (xdr_bytes(xdrs, &wa->wa_data,
 176  179                              &wa->wa_count, NFS_MAXDATA));
 177  180                  }
 178  181                  if (xdr_fhandle(xdrs, &wa->wa_fhandle) &&
 179  182                      xdr_u_int(xdrs, &wa->wa_begoff) &&
 180  183                      xdr_u_int(xdrs, &wa->wa_offset) &&
 181  184                      xdr_u_int(xdrs, &wa->wa_totcount)) {
 182  185                          /* deal with the variety of data transfer types */
 183  186  
 184  187                          wa->wa_mblk = NULL;
 185  188                          wa->wa_data = NULL;
 186  189                          wa->wa_rlist = NULL;
 187  190                          wa->wa_conn = NULL;
 188  191  
 189  192                          if (xdrs->x_ops == &xdrmblk_ops) {
 190  193                                  if (xdrmblk_getmblk(xdrs, &wa->wa_mblk,
 191  194                                      &wa->wa_count) == TRUE)
 192  195                                          return (TRUE);
 193  196                          } else {
 194  197                                  if (xdrs->x_ops == &xdrrdmablk_ops) {
 195  198                                          if (xdrrdma_getrdmablk(xdrs,
 196  199                                              &wa->wa_rlist,
 197  200                                              &wa->wa_count,
 198  201                                              &wa->wa_conn,
 199  202                                              NFS_MAXDATA) == TRUE)
 200  203                                          return (xdrrdma_read_from_client(
 201  204                                              wa->wa_rlist,
 202  205                                              &wa->wa_conn,
 203  206                                              wa->wa_count));
 204  207  
 205  208                                          wa->wa_rlist = NULL;
 206  209                                          wa->wa_conn = NULL;
 207  210                                  }
 208  211                          }
 209  212                          return (xdr_bytes(xdrs, &wa->wa_data,
 210  213                              &wa->wa_count, NFS_MAXDATA));
 211  214                  }
 212  215                  return (FALSE);
 213  216          case XDR_ENCODE:
 214  217                  ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
 215  218                      3 * BYTES_PER_XDR_UNIT);
 216  219                  if (ptr != NULL) {
 217  220                          fhp = (int32_t *)&wa->wa_fhandle;
 218  221                          *ptr++ = *fhp++;
 219  222                          *ptr++ = *fhp++;
 220  223                          *ptr++ = *fhp++;
 221  224                          *ptr++ = *fhp++;
 222  225                          *ptr++ = *fhp++;
 223  226                          *ptr++ = *fhp++;
 224  227                          *ptr++ = *fhp++;
 225  228                          *ptr++ = *fhp;
 226  229                          IXDR_PUT_U_INT32(ptr, wa->wa_begoff);
 227  230                          IXDR_PUT_U_INT32(ptr, wa->wa_offset);
 228  231                          IXDR_PUT_U_INT32(ptr, wa->wa_totcount);
 229  232                  } else {
 230  233                          if (!(xdr_fhandle(xdrs, &wa->wa_fhandle) &&
 231  234                              xdr_u_int(xdrs, &wa->wa_begoff) &&
 232  235                              xdr_u_int(xdrs, &wa->wa_offset) &&
 233  236                              xdr_u_int(xdrs, &wa->wa_totcount)))
 234  237                                  return (FALSE);
 235  238                  }
 236  239  
 237  240                  return (xdr_bytes(xdrs, &wa->wa_data, &wa->wa_count,
 238  241                      NFS_MAXDATA));
 239  242          case XDR_FREE:
 240  243                  if (wa->wa_rlist) {
 241  244                          (void) xdrrdma_free_clist(wa->wa_conn, wa->wa_rlist);
 242  245                          wa->wa_rlist = NULL;
 243  246                  }
 244  247  
 245  248                  if (wa->wa_data != NULL) {
 246  249                          kmem_free(wa->wa_data, wa->wa_count);
 247  250                          wa->wa_data = NULL;
 248  251                  }
 249  252                  return (TRUE);
 250  253          }
 251  254          return (FALSE);
 252  255  }
 253  256  
 254  257  
 255  258  /*
 256  259   * File attributes
 257  260   */
 258  261  bool_t
 259  262  xdr_fattr(XDR *xdrs, struct nfsfattr *na)
 260  263  {
 261  264          int32_t *ptr;
 262  265  
 263  266          if (xdrs->x_op == XDR_FREE)
 264  267                  return (TRUE);
 265  268  
 266  269          ptr = XDR_INLINE(xdrs, 17 * BYTES_PER_XDR_UNIT);
 267  270          if (ptr != NULL) {
 268  271                  if (xdrs->x_op == XDR_DECODE) {
 269  272                          na->na_type = IXDR_GET_ENUM(ptr, enum nfsftype);
 270  273                          na->na_mode = IXDR_GET_U_INT32(ptr);
 271  274                          na->na_nlink = IXDR_GET_U_INT32(ptr);
 272  275                          na->na_uid = IXDR_GET_U_INT32(ptr);
 273  276                          na->na_gid = IXDR_GET_U_INT32(ptr);
 274  277                          na->na_size = IXDR_GET_U_INT32(ptr);
 275  278                          na->na_blocksize = IXDR_GET_U_INT32(ptr);
 276  279                          na->na_rdev = IXDR_GET_U_INT32(ptr);
 277  280                          na->na_blocks = IXDR_GET_U_INT32(ptr);
 278  281                          na->na_fsid = IXDR_GET_U_INT32(ptr);
 279  282                          na->na_nodeid = IXDR_GET_U_INT32(ptr);
 280  283                          na->na_atime.tv_sec = IXDR_GET_U_INT32(ptr);
 281  284                          na->na_atime.tv_usec = IXDR_GET_U_INT32(ptr);
 282  285                          na->na_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
 283  286                          na->na_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
 284  287                          na->na_ctime.tv_sec = IXDR_GET_U_INT32(ptr);
 285  288                          na->na_ctime.tv_usec = IXDR_GET_U_INT32(ptr);
 286  289                  } else {
 287  290                          IXDR_PUT_ENUM(ptr, na->na_type);
 288  291                          IXDR_PUT_U_INT32(ptr, na->na_mode);
 289  292                          IXDR_PUT_U_INT32(ptr, na->na_nlink);
 290  293                          IXDR_PUT_U_INT32(ptr, na->na_uid);
 291  294                          IXDR_PUT_U_INT32(ptr, na->na_gid);
 292  295                          IXDR_PUT_U_INT32(ptr, na->na_size);
 293  296                          IXDR_PUT_U_INT32(ptr, na->na_blocksize);
 294  297                          IXDR_PUT_U_INT32(ptr, na->na_rdev);
 295  298                          IXDR_PUT_U_INT32(ptr, na->na_blocks);
 296  299                          IXDR_PUT_U_INT32(ptr, na->na_fsid);
 297  300                          IXDR_PUT_U_INT32(ptr, na->na_nodeid);
 298  301                          IXDR_PUT_U_INT32(ptr, na->na_atime.tv_sec);
 299  302                          IXDR_PUT_U_INT32(ptr, na->na_atime.tv_usec);
 300  303                          IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_sec);
 301  304                          IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_usec);
 302  305                          IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_sec);
 303  306                          IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_usec);
 304  307                  }
 305  308                  return (TRUE);
 306  309          }
 307  310  
 308  311          if (xdr_enum(xdrs, (enum_t *)&na->na_type) &&
 309  312              xdr_u_int(xdrs, &na->na_mode) &&
 310  313              xdr_u_int(xdrs, &na->na_nlink) &&
 311  314              xdr_u_int(xdrs, &na->na_uid) &&
 312  315              xdr_u_int(xdrs, &na->na_gid) &&
 313  316              xdr_u_int(xdrs, &na->na_size) &&
 314  317              xdr_u_int(xdrs, &na->na_blocksize) &&
 315  318              xdr_u_int(xdrs, &na->na_rdev) &&
 316  319              xdr_u_int(xdrs, &na->na_blocks) &&
 317  320              xdr_u_int(xdrs, &na->na_fsid) &&
 318  321              xdr_u_int(xdrs, &na->na_nodeid) &&
 319  322              xdr_nfs2_timeval(xdrs, &na->na_atime) &&
 320  323              xdr_nfs2_timeval(xdrs, &na->na_mtime) &&
 321  324              xdr_nfs2_timeval(xdrs, &na->na_ctime)) {
 322  325                  return (TRUE);
 323  326          }
 324  327          return (FALSE);
 325  328  }
 326  329  
 327  330  #ifdef _LITTLE_ENDIAN
 328  331  bool_t
 329  332  xdr_fastfattr(XDR *xdrs, struct nfsfattr *na)
 330  333  {
 331  334          if (xdrs->x_op == XDR_FREE)
 332  335                  return (TRUE);
 333  336          if (xdrs->x_op == XDR_DECODE)
 334  337                  return (FALSE);
 335  338  
 336  339          na->na_type = htonl(na->na_type);
 337  340          na->na_mode = htonl(na->na_mode);
 338  341          na->na_nlink = htonl(na->na_nlink);
 339  342          na->na_uid = htonl(na->na_uid);
 340  343          na->na_gid = htonl(na->na_gid);
 341  344          na->na_size = htonl(na->na_size);
 342  345          na->na_blocksize = htonl(na->na_blocksize);
 343  346          na->na_rdev = htonl(na->na_rdev);
 344  347          na->na_blocks = htonl(na->na_blocks);
 345  348          na->na_fsid = htonl(na->na_fsid);
 346  349          na->na_nodeid = htonl(na->na_nodeid);
 347  350          na->na_atime.tv_sec = htonl(na->na_atime.tv_sec);
 348  351          na->na_atime.tv_usec = htonl(na->na_atime.tv_usec);
 349  352          na->na_mtime.tv_sec = htonl(na->na_mtime.tv_sec);
 350  353          na->na_mtime.tv_usec = htonl(na->na_mtime.tv_usec);
 351  354          na->na_ctime.tv_sec = htonl(na->na_ctime.tv_sec);
 352  355          na->na_ctime.tv_usec = htonl(na->na_ctime.tv_usec);
 353  356          return (TRUE);
 354  357  }
 355  358  #endif
 356  359  
 357  360  bool_t
 358  361  xdr_readlink(XDR *xdrs, fhandle_t *fh)
 359  362  {
 360  363          rdma_chunkinfo_t rci;
 361  364          struct xdr_ops *xops = xdrrdma_xops();
 362  365  
 363  366          if (xdr_fhandle(xdrs, fh)) {
 364  367                  if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
 365  368                      xdrs->x_op == XDR_ENCODE) {
 366  369                          rci.rci_type = RCI_REPLY_CHUNK;
 367  370                          rci.rci_len = MAXPATHLEN;
 368  371                          XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
 369  372                  }
 370  373  
 371  374                  return (TRUE);
 372  375          }
 373  376          return (FALSE);
 374  377  }
 375  378  
 376  379  /*
 377  380   * Arguments to remote read
 378  381   */
 379  382  bool_t
 380  383  xdr_readargs(XDR *xdrs, struct nfsreadargs *ra)
 381  384  {
 382  385          int32_t *ptr;
 383  386          int32_t *fhp;
 384  387          rdma_chunkinfo_t rci;
 385  388          rdma_wlist_conn_info_t rwci;
 386  389          struct xdr_ops *xops = xdrrdma_xops();
 387  390  
 388  391          if (xdrs->x_op == XDR_FREE)
 389  392                  return (TRUE);
 390  393  
 391  394          ptr = XDR_INLINE(xdrs,
 392  395              RNDUP(sizeof (fhandle_t)) + 3 * BYTES_PER_XDR_UNIT);
 393  396          if (ptr != NULL) {
 394  397                  if (xdrs->x_op == XDR_DECODE) {
 395  398                          fhp = (int32_t *)&ra->ra_fhandle;
 396  399                          *fhp++ = *ptr++;
 397  400                          *fhp++ = *ptr++;
 398  401                          *fhp++ = *ptr++;
 399  402                          *fhp++ = *ptr++;
 400  403                          *fhp++ = *ptr++;
 401  404                          *fhp++ = *ptr++;
 402  405                          *fhp++ = *ptr++;
 403  406                          *fhp = *ptr++;
 404  407                          ra->ra_offset = IXDR_GET_INT32(ptr);
 405  408                          ra->ra_count = IXDR_GET_INT32(ptr);
 406  409                          ra->ra_totcount = IXDR_GET_INT32(ptr);
 407  410                  } else {
 408  411                          fhp = (int32_t *)&ra->ra_fhandle;
 409  412                          *ptr++ = *fhp++;
 410  413                          *ptr++ = *fhp++;
 411  414                          *ptr++ = *fhp++;
 412  415                          *ptr++ = *fhp++;
 413  416                          *ptr++ = *fhp++;
 414  417                          *ptr++ = *fhp++;
 415  418                          *ptr++ = *fhp++;
 416  419                          *ptr++ = *fhp;
 417  420                          IXDR_PUT_INT32(ptr, ra->ra_offset);
 418  421                          IXDR_PUT_INT32(ptr, ra->ra_count);
 419  422                          IXDR_PUT_INT32(ptr, ra->ra_totcount);
 420  423                  }
 421  424          } else {
 422  425                  if (!xdr_fhandle(xdrs, &ra->ra_fhandle) ||
 423  426                      !xdr_u_int(xdrs, &ra->ra_offset) ||
 424  427                      !xdr_u_int(xdrs, &ra->ra_count) ||
 425  428                      !xdr_u_int(xdrs, &ra->ra_totcount)) {
 426  429                          return (FALSE);
 427  430                  }
 428  431          }
 429  432  
 430  433          if (ra->ra_count > NFS_MAXDATA)
 431  434                  return (FALSE);
 432  435  
 433  436          ra->ra_wlist = NULL;
 434  437          ra->ra_conn = NULL;
 435  438  
 436  439          /* If this is xdrrdma_sizeof, record the expect response size */
 437  440          if (xdrs->x_ops == xops && xdrs->x_op == XDR_ENCODE) {
 438  441                  rci.rci_type = RCI_WRITE_ADDR_CHUNK;
 439  442                  rci.rci_len = ra->ra_count;
 440  443                  (void) XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
 441  444          }
 442  445          /* Nothing special to do, return */
 443  446          if (xdrs->x_ops != &xdrrdma_ops || xdrs->x_op == XDR_FREE)
 444  447                  return (TRUE);
 445  448  
 446  449          if (xdrs->x_op == XDR_ENCODE) {
 447  450                  /* Place the target data location into the RDMA header */
 448  451                  rci.rci_type = RCI_WRITE_ADDR_CHUNK;
 449  452                  rci.rci_a.rci_addr = ra->ra_data;
 450  453                  rci.rci_len = ra->ra_count;
 451  454                  rci.rci_clpp = &ra->ra_wlist;
 452  455  
 453  456                  return (XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci));
 454  457          }
 455  458  
 456  459          /* XDR_DECODE case */
 457  460          (void) XDR_CONTROL(xdrs, XDR_RDMA_GET_WCINFO, &rwci);
 458  461          ra->ra_wlist = rwci.rwci_wlist;
 459  462          ra->ra_conn = rwci.rwci_conn;
 460  463  
 461  464          return (TRUE);
 462  465  }
 463  466  
 464  467  
 465  468  /*
 466  469   * Status OK portion of remote read reply
 467  470   */
 468  471  bool_t
 469  472  xdr_rrok(XDR *xdrs, struct nfsrrok *rrok)
 470  473  {
 471  474          bool_t ret;
 472  475          mblk_t *mp;
 473  476          struct xdr_ops *xops = xdrrdma_xops();
 474  477  
 475  478          if (xdr_fattr(xdrs, &rrok->rrok_attr) == FALSE)
 476  479                  return (FALSE);
 477  480  
 478  481          /* deal with RDMA separately */
 479  482          if (xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) {
 480  483                  if (xdrs->x_op == XDR_ENCODE &&
 481  484                      rrok->rrok_mp != NULL) {
 482  485                          ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
 483  486                              &rrok->rrok_count, NFS_MAXDATA);
 484  487                          return (ret);
 485  488                  }
 486  489  
 487  490                  if (xdrs->x_op == XDR_ENCODE) {
 488  491                          if (xdr_u_int(xdrs, &rrok->rrok_count) == FALSE) {
 489  492                                  return (FALSE);
 490  493                          }
 491  494                          /*
 492  495                           * If read data sent by wlist (RDMA_WRITE), don't do
 493  496                           * xdr_bytes() below.   RDMA_WRITE transfers the data.
 494  497                           */
 495  498                          if (rrok->rrok_wlist) {
 496  499                                  if (rrok->rrok_count != 0) {
 497  500                                          return (xdrrdma_send_read_data(
 498  501                                              xdrs, rrok->rrok_count,
 499  502                                              rrok->rrok_wlist));
 500  503                                  }
 501  504                                  return (TRUE);
 502  505                          }
 503  506                          if (rrok->rrok_count == 0) {
 504  507                                  return (TRUE);
 505  508                          }
 506  509                  } else {
 507  510                          struct clist *cl;
 508  511                          uint32_t count;
 509  512  
 510  513                          XDR_CONTROL(xdrs, XDR_RDMA_GET_WLIST, &cl);
 511  514  
 512  515                          if (cl) {
 513  516                                  if (!xdr_u_int(xdrs, &count))
 514  517                                          return (FALSE);
 515  518                                  if (count == 0) {
 516  519                                          rrok->rrok_wlist_len = 0;
 517  520                                          rrok->rrok_count = 0;
 518  521                                  } else {
 519  522                                          rrok->rrok_wlist_len = clist_len(cl);
 520  523                                          if (rrok->rrok_wlist_len !=
 521  524                                              roundup(count,
 522  525                                              BYTES_PER_XDR_UNIT)) {
 523  526                                                  rrok->rrok_wlist_len = 0;
 524  527                                                  rrok->rrok_count = 0;
 525  528                                                  return (FALSE);
 526  529                                          }
 527  530                                          rrok->rrok_count = count;
 528  531                                  }
 529  532                                  return (TRUE);
 530  533                          }
 531  534                  }
 532  535                  ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
 533  536                      &rrok->rrok_count, NFS_MAXDATA);
 534  537  
 535  538                  return (ret);
 536  539          }
 537  540  
 538  541          if (xdrs->x_op == XDR_ENCODE) {
 539  542                  int i, rndup;
 540  543  
 541  544                  mp = rrok->rrok_mp;
 542  545                  if (mp != NULL && xdrs->x_ops == &xdrmblk_ops) {
 543  546                          mp->b_wptr += rrok->rrok_count;
 544  547                          rndup = BYTES_PER_XDR_UNIT -
 545  548                              (rrok->rrok_count % BYTES_PER_XDR_UNIT);
 546  549                          if (rndup != BYTES_PER_XDR_UNIT)
 547  550                                  for (i = 0; i < rndup; i++)
 548  551                                          *mp->b_wptr++ = '\0';
 549  552                          if (xdrmblk_putmblk(xdrs, mp,
 550  553                              rrok->rrok_count) == TRUE) {
 551  554                                  rrok->rrok_mp = NULL;
 552  555                                  return (TRUE);
 553  556                          }
 554  557                  }
 555  558  
 556  559                  /*
 557  560                   * Fall thru for the xdr_bytes()
 558  561                   *
 559  562                   * Note: the mblk mp will be freed in rfs_rdfree
 560  563                   */
 561  564          }
 562  565  
 563  566          ret = xdr_bytes(xdrs, (char **)&rrok->rrok_data,
 564  567              &rrok->rrok_count, NFS_MAXDATA);
 565  568  
 566  569          return (ret);
 567  570  }
 568  571  
 569  572  static struct xdr_discrim rdres_discrim[2] = {
 570  573          { NFS_OK, xdr_rrok },
 571  574          { __dontcare__, NULL_xdrproc_t }
 572  575  };
 573  576  
 574  577  /*
 575  578   * Reply from remote read
 576  579   */
 577  580  bool_t
 578  581  xdr_rdresult(XDR *xdrs, struct nfsrdresult *rr)
 579  582  {
 580  583          return (xdr_union(xdrs, (enum_t *)&(rr->rr_status),
 581  584              (caddr_t)&(rr->rr_ok), rdres_discrim, xdr_void));
 582  585  }
 583  586  
 584  587  /*
 585  588   * File attributes which can be set
 586  589   */
 587  590  bool_t
 588  591  xdr_sattr(XDR *xdrs, struct nfssattr *sa)
 589  592  {
 590  593          if (xdr_u_int(xdrs, &sa->sa_mode) &&
 591  594              xdr_u_int(xdrs, &sa->sa_uid) &&
 592  595              xdr_u_int(xdrs, &sa->sa_gid) &&
 593  596              xdr_u_int(xdrs, &sa->sa_size) &&
 594  597              xdr_nfs2_timeval(xdrs, &sa->sa_atime) &&
 595  598              xdr_nfs2_timeval(xdrs, &sa->sa_mtime)) {
 596  599                  return (TRUE);
 597  600          }
 598  601          return (FALSE);
 599  602  }
 600  603  
 601  604  static struct xdr_discrim attrstat_discrim[2] = {
 602  605          { (int)NFS_OK, xdr_fattr },
 603  606          { __dontcare__, NULL_xdrproc_t }
 604  607  };
 605  608  
 606  609  /*
 607  610   * Reply status with file attributes
 608  611   */
 609  612  bool_t
 610  613  xdr_attrstat(XDR *xdrs, struct nfsattrstat *ns)
 611  614  {
 612  615          return (xdr_union(xdrs, (enum_t *)&(ns->ns_status),
 613  616              (caddr_t)&(ns->ns_attr), attrstat_discrim, xdr_void));
 614  617  }
 615  618  
 616  619  /*
 617  620   * Fast reply status with file attributes
 618  621   */
 619  622  bool_t
 620  623  xdr_fastattrstat(XDR *xdrs, struct nfsattrstat *ns)
 621  624  {
 622  625  #if defined(_LITTLE_ENDIAN)
 623  626          /*
 624  627           * we deal with the discriminator;  it's an enum
 625  628           */
 626  629          if (!xdr_fastenum(xdrs, (enum_t *)&ns->ns_status))
 627  630                  return (FALSE);
 628  631  
 629  632          if (ns->ns_status == NFS_OK)
 630  633                  return (xdr_fastfattr(xdrs, &ns->ns_attr));
 631  634  #elif defined(_BIG_ENDIAN)
 632  635          if (ns->ns_status == NFS_OK)
 633  636                  return (TRUE);
 634  637  #endif
 635  638          return (xdr_fastshorten(xdrs, sizeof (*ns)));
 636  639  }
 637  640  
 638  641  /*
 639  642   * NFS_OK part of read sym link reply union
 640  643   */
 641  644  bool_t
 642  645  xdr_srok(XDR *xdrs, struct nfssrok *srok)
 643  646  {
 644  647          /*
 645  648           * It is just as efficient to xdr_bytes
 646  649           * an array of unknown length as to inline copy it.
 647  650           */
 648  651          return (xdr_bytes(xdrs, &srok->srok_data, &srok->srok_count,
 649  652              NFS_MAXPATHLEN));
 650  653  }
 651  654  
 652  655  static struct xdr_discrim rdlnres_discrim[2] = {
 653  656          { (int)NFS_OK, xdr_srok },
 654  657          { __dontcare__, NULL_xdrproc_t }
 655  658  };
 656  659  
 657  660  /*
 658  661   * Result of reading symbolic link
 659  662   */
 660  663  bool_t
 661  664  xdr_rdlnres(XDR *xdrs, struct nfsrdlnres *rl)
 662  665  {
 663  666          return (xdr_union(xdrs, (enum_t *)&(rl->rl_status),
 664  667              (caddr_t)&(rl->rl_srok), rdlnres_discrim, xdr_void));
 665  668  }
 666  669  
 667  670  /*
 668  671   * Arguments to readdir
 669  672   */
 670  673  bool_t
 671  674  xdr_rddirargs(XDR *xdrs, struct nfsrddirargs *rda)
 672  675  {
 673  676          int32_t *ptr;
 674  677          int32_t *fhp;
 675  678          rdma_chunkinfo_t rci;
 676  679          struct xdr_ops *xops = xdrrdma_xops();
 677  680  
 678  681          if (xdrs->x_op == XDR_FREE)
 679  682                  return (TRUE);
 680  683  
 681  684          ptr = XDR_INLINE(xdrs,
 682  685              RNDUP(sizeof (fhandle_t)) + 2 * BYTES_PER_XDR_UNIT);
 683  686  
 684  687          if ((xdrs->x_ops == &xdrrdma_ops || xdrs->x_ops == xops) &&
 685  688              xdrs->x_op == XDR_ENCODE) {
 686  689                  rci.rci_type = RCI_REPLY_CHUNK;
 687  690                  rci.rci_len = rda->rda_count;
 688  691                  XDR_CONTROL(xdrs, XDR_RDMA_ADD_CHUNK, &rci);
 689  692          }
 690  693  
 691  694          if (ptr != NULL) {
 692  695                  if (xdrs->x_op == XDR_DECODE) {
 693  696                          fhp = (int32_t *)&rda->rda_fh;
 694  697                          *fhp++ = *ptr++;
 695  698                          *fhp++ = *ptr++;
 696  699                          *fhp++ = *ptr++;
 697  700                          *fhp++ = *ptr++;
 698  701                          *fhp++ = *ptr++;
 699  702                          *fhp++ = *ptr++;
 700  703                          *fhp++ = *ptr++;
 701  704                          *fhp = *ptr++;
 702  705                          rda->rda_offset = IXDR_GET_U_INT32(ptr);
 703  706                          rda->rda_count = IXDR_GET_U_INT32(ptr);
 704  707                  } else {
 705  708                          fhp = (int32_t *)&rda->rda_fh;
 706  709                          *ptr++ = *fhp++;
 707  710                          *ptr++ = *fhp++;
 708  711                          *ptr++ = *fhp++;
 709  712                          *ptr++ = *fhp++;
 710  713                          *ptr++ = *fhp++;
 711  714                          *ptr++ = *fhp++;
 712  715                          *ptr++ = *fhp++;
 713  716                          *ptr++ = *fhp;
 714  717                          IXDR_PUT_U_INT32(ptr, rda->rda_offset);
 715  718                          IXDR_PUT_U_INT32(ptr, rda->rda_count);
 716  719                  }
 717  720                  return (TRUE);
 718  721          }
 719  722  
 720  723          if (xdr_fhandle(xdrs, &rda->rda_fh) &&
 721  724              xdr_u_int(xdrs, &rda->rda_offset) &&
 722  725              xdr_u_int(xdrs, &rda->rda_count)) {
 723  726                  return (TRUE);
 724  727          }
 725  728          return (FALSE);
 726  729  }
 727  730  
 728  731  
 729  732  /*
 730  733   * Directory read reply:
 731  734   * union (enum status) {
 732  735   *      NFS_OK: entlist;
 733  736   *              boolean eof;
 734  737   *      default:
 735  738   * }
 736  739   *
 737  740   * Directory entries
 738  741   *      struct  direct {
 739  742   *              off_t   d_off;                  * offset of next entry *
 740  743   *              u_int   d_fileno;               * inode number of entry *
 741  744   *              u_short d_reclen;               * length of this record *
 742  745   *              u_short d_namlen;               * length of string in d_name *
 743  746   *              char    d_name[MAXNAMLEN + 1];  * name no longer than this *
 744  747   *      };
 745  748   * are on the wire as:
 746  749   * union entlist (boolean valid) {
 747  750   *      TRUE:   struct otw_dirent;
 748  751   *              u_int nxtoffset;
 749  752   *              union entlist;
 750  753   *      FALSE:
 751  754   * }
 752  755   * where otw_dirent is:
 753  756   *      struct dirent {
 754  757   *              u_int   de_fid;
 755  758   *              string  de_name<NFS_MAXNAMELEN>;
 756  759   *      }
 757  760   */
 758  761  
 759  762  #ifdef nextdp
 760  763  #undef  nextdp
 761  764  #endif
 762  765  #define nextdp(dp)      ((struct dirent64 *)((char *)(dp) + (dp)->d_reclen))
 763  766  #ifdef roundup
  
    | 
      ↓ open down ↓ | 
    729 lines elided | 
    
      ↑ open up ↑ | 
  
 764  767  #undef  roundup
 765  768  #endif
 766  769  #define roundup(x, y)   ((((x) + ((y) - 1)) / (y)) * (y))
 767  770  
 768  771  /*
 769  772   * ENCODE ONLY
 770  773   */
 771  774  bool_t
 772  775  xdr_putrddirres(XDR *xdrs, struct nfsrddirres *rd)
 773  776  {
 774      -        struct dirent64 *dp;
 775      -        char *name;
 776      -        int size;
 777      -        uint_t namlen;
 778  777          bool_t true = TRUE;
 779  778          bool_t false = FALSE;
 780      -        int entrysz;
 781      -        int tofit;
 782      -        int bufsize;
 783      -        uint32_t ino, off;
      779 +        struct nfsentry *entry;
 784  780  
 785  781          if (xdrs->x_op != XDR_ENCODE)
 786  782                  return (FALSE);
 787  783          if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
 788  784                  return (FALSE);
 789  785          if (rd->rd_status != NFS_OK)
 790  786                  return (TRUE);
 791  787  
 792      -        bufsize = 1 * BYTES_PER_XDR_UNIT;
 793      -        for (size = rd->rd_size, dp = rd->rd_entries;
 794      -            size > 0;
 795      -            size -= dp->d_reclen, dp = nextdp(dp)) {
 796      -                if (dp->d_reclen == 0 /* || DIRSIZ(dp) > dp->d_reclen */)
 797      -                        return (FALSE);
 798      -                if (dp->d_ino == 0)
 799      -                        continue;
 800      -                ino = (uint32_t)dp->d_ino; /* for LP64 we clip the bits */
 801      -                if (dp->d_ino != (ino64_t)ino)  /* and they better be zeros */
 802      -                        return (FALSE);
 803      -                off = (uint32_t)dp->d_off;
 804      -                name = dp->d_name;
 805      -                namlen = (uint_t)strlen(name);
 806      -                entrysz = (1 + 1 + 1 + 1) * BYTES_PER_XDR_UNIT +
 807      -                    roundup(namlen, BYTES_PER_XDR_UNIT);
 808      -                tofit = entrysz + 2 * BYTES_PER_XDR_UNIT;
 809      -                if (bufsize + tofit > rd->rd_bufsize) {
 810      -                        rd->rd_eof = FALSE;
 811      -                        break;
 812      -                }
      788 +        for (entry = rd->rd_entries; entry != NULL; entry = entry->nextentry) {
 813  789                  if (!xdr_bool(xdrs, &true) ||
 814      -                    !xdr_u_int(xdrs, &ino) ||
 815      -                    !xdr_bytes(xdrs, &name, &namlen, NFS_MAXNAMLEN) ||
 816      -                    !xdr_u_int(xdrs, &off)) {
      790 +                    !xdr_u_int(xdrs, &entry->fileid) ||
      791 +                    !xdr_string(xdrs, &entry->name, NFS_MAXNAMLEN) ||
      792 +                    !xdr_u_int(xdrs, &entry->cookie)) {
 817  793                          return (FALSE);
 818  794                  }
 819      -                bufsize += entrysz;
 820  795          }
 821  796          if (!xdr_bool(xdrs, &false))
 822  797                  return (FALSE);
 823  798          if (!xdr_bool(xdrs, &rd->rd_eof))
 824  799                  return (FALSE);
 825  800          return (TRUE);
 826  801  }
 827  802  
 828  803  /*
 829  804   * DECODE ONLY
 830  805   */
 831  806  bool_t
 832  807  xdr_getrddirres(XDR *xdrs, struct nfsrddirres *rd)
 833  808  {
 834  809          struct dirent64 *dp;
 835  810          uint_t namlen;
 836  811          int size;
 837  812          bool_t valid;
 838  813          uint32_t offset;
 839  814          uint_t fileid, this_reclen;
  
    | 
      ↓ open down ↓ | 
    10 lines elided | 
    
      ↑ open up ↑ | 
  
 840  815  
 841  816          if (xdrs->x_op != XDR_DECODE)
 842  817                  return (FALSE);
 843  818  
 844  819          if (!xdr_enum(xdrs, (enum_t *)&rd->rd_status))
 845  820                  return (FALSE);
 846  821          if (rd->rd_status != NFS_OK)
 847  822                  return (TRUE);
 848  823  
 849  824          size = rd->rd_size;
 850      -        dp = rd->rd_entries;
      825 +        dp = rd->rd_dirents;
 851  826          offset = rd->rd_offset;
 852  827          for (;;) {
 853  828                  if (!xdr_bool(xdrs, &valid))
 854  829                          return (FALSE);
 855  830                  if (!valid)
 856  831                          break;
 857  832                  if (!xdr_u_int(xdrs, &fileid) ||
 858  833                      !xdr_u_int(xdrs, &namlen))
 859  834                          return (FALSE);
 860  835                  this_reclen = DIRENT64_RECLEN(namlen);
 861  836                  if (this_reclen > size) {
 862  837                          rd->rd_eof = FALSE;
 863  838                          goto bufovflw;
 864  839                  }
 865  840                  if (!xdr_opaque(xdrs, dp->d_name, namlen)||
 866  841                      !xdr_u_int(xdrs, &offset)) {
 867  842                          return (FALSE);
 868  843                  }
 869  844                  bzero(&dp->d_name[namlen],
  
    | 
      ↓ open down ↓ | 
    9 lines elided | 
    
      ↑ open up ↑ | 
  
 870  845                      DIRENT64_NAMELEN(this_reclen) - namlen);
 871  846                  dp->d_ino = (ino64_t)fileid;
 872  847                  dp->d_reclen = this_reclen;
 873  848                  dp->d_off = (off64_t)offset;
 874  849                  size -= dp->d_reclen;
 875  850                  dp = nextdp(dp);
 876  851          }
 877  852          if (!xdr_bool(xdrs, &rd->rd_eof))
 878  853                  return (FALSE);
 879  854  bufovflw:
 880      -        rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_entries));
      855 +        rd->rd_size = (uint32_t)((char *)dp - (char *)(rd->rd_dirents));
 881  856          rd->rd_offset = offset;
 882  857          return (TRUE);
 883  858  }
 884  859  
 885  860  /*
 886  861   * Arguments for directory operations
 887  862   */
 888  863  bool_t
 889  864  xdr_diropargs(XDR *xdrs, struct nfsdiropargs *da)
 890  865  {
 891  866          int32_t *ptr;
 892  867          int32_t *fhp;
 893  868          uint32_t size;
 894  869          uint32_t nodesize;
 895  870          int i;
 896  871          int rndup;
 897  872          char *cptr;
 898  873  
 899  874          if (xdrs->x_op == XDR_DECODE) {
 900  875                  da->da_fhandle = &da->da_fhandle_buf;
 901  876                  ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
 902  877                      1 * BYTES_PER_XDR_UNIT);
 903  878                  if (ptr != NULL) {
 904  879                          fhp = (int32_t *)da->da_fhandle;
 905  880                          *fhp++ = *ptr++;
 906  881                          *fhp++ = *ptr++;
 907  882                          *fhp++ = *ptr++;
 908  883                          *fhp++ = *ptr++;
 909  884                          *fhp++ = *ptr++;
 910  885                          *fhp++ = *ptr++;
 911  886                          *fhp++ = *ptr++;
 912  887                          *fhp = *ptr++;
 913  888                          size = IXDR_GET_U_INT32(ptr);
 914  889                          if (size > NFS_MAXNAMLEN)
 915  890                                  return (FALSE);
 916  891                          nodesize = size + 1;
 917  892                          if (nodesize == 0)
 918  893                                  return (TRUE);
 919  894                          if (da->da_name == NULL) {
 920  895                                  da->da_name = kmem_alloc(nodesize, KM_NOSLEEP);
 921  896                                  if (da->da_name == NULL)
 922  897                                          return (FALSE);
 923  898                                  da->da_flags |= DA_FREENAME;
 924  899                          }
 925  900                          ptr = XDR_INLINE(xdrs, RNDUP(size));
 926  901                          if (ptr == NULL) {
 927  902                                  if (!xdr_opaque(xdrs, da->da_name, size)) {
 928  903                                          if (da->da_flags & DA_FREENAME) {
 929  904                                                  kmem_free(da->da_name,
 930  905                                                      nodesize);
 931  906                                                  da->da_name = NULL;
 932  907                                          }
 933  908                                          return (FALSE);
 934  909                                  }
 935  910                                  da->da_name[size] = '\0';
 936  911                                  if (strlen(da->da_name) != size) {
 937  912                                          if (da->da_flags & DA_FREENAME) {
 938  913                                                  kmem_free(da->da_name,
 939  914                                                      nodesize);
 940  915                                                  da->da_name = NULL;
 941  916                                          }
 942  917                                          return (FALSE);
 943  918                                  }
 944  919                                  return (TRUE);
 945  920                          }
 946  921                          bcopy(ptr, da->da_name, size);
 947  922                          da->da_name[size] = '\0';
 948  923                          if (strlen(da->da_name) != size) {
 949  924                                  if (da->da_flags & DA_FREENAME) {
 950  925                                          kmem_free(da->da_name, nodesize);
 951  926                                          da->da_name = NULL;
 952  927                                  }
 953  928                                  return (FALSE);
 954  929                          }
 955  930                          return (TRUE);
 956  931                  }
 957  932                  if (da->da_name == NULL)
 958  933                          da->da_flags |= DA_FREENAME;
 959  934          }
 960  935  
 961  936          if (xdrs->x_op == XDR_ENCODE) {
 962  937                  size = (uint32_t)strlen(da->da_name);
 963  938                  if (size > NFS_MAXNAMLEN)
 964  939                          return (FALSE);
 965  940                  ptr = XDR_INLINE(xdrs, (int)(RNDUP(sizeof (fhandle_t)) +
 966  941                      1 * BYTES_PER_XDR_UNIT + RNDUP(size)));
 967  942                  if (ptr != NULL) {
 968  943                          fhp = (int32_t *)da->da_fhandle;
 969  944                          *ptr++ = *fhp++;
 970  945                          *ptr++ = *fhp++;
 971  946                          *ptr++ = *fhp++;
 972  947                          *ptr++ = *fhp++;
 973  948                          *ptr++ = *fhp++;
 974  949                          *ptr++ = *fhp++;
 975  950                          *ptr++ = *fhp++;
 976  951                          *ptr++ = *fhp;
 977  952                          IXDR_PUT_U_INT32(ptr, (uint32_t)size);
 978  953                          bcopy(da->da_name, ptr, size);
 979  954                          rndup = BYTES_PER_XDR_UNIT -
 980  955                              (size % BYTES_PER_XDR_UNIT);
 981  956                          if (rndup != BYTES_PER_XDR_UNIT) {
 982  957                                  cptr = (char *)ptr + size;
 983  958                                  for (i = 0; i < rndup; i++)
 984  959                                          *cptr++ = '\0';
 985  960                          }
 986  961                          return (TRUE);
 987  962                  }
 988  963          }
 989  964  
 990  965          if (xdrs->x_op == XDR_FREE) {
 991  966                  if (da->da_name == NULL)
 992  967                          return (TRUE);
 993  968                  size = (uint32_t)strlen(da->da_name);
 994  969                  if (size > NFS_MAXNAMLEN)
 995  970                          return (FALSE);
 996  971                  if (da->da_flags & DA_FREENAME)
 997  972                          kmem_free(da->da_name, size + 1);
 998  973                  da->da_name = NULL;
 999  974                  return (TRUE);
1000  975          }
1001  976  
1002  977          if (xdr_fhandle(xdrs, da->da_fhandle) &&
1003  978              xdr_string(xdrs, &da->da_name, NFS_MAXNAMLEN)) {
1004  979                  return (TRUE);
1005  980          }
1006  981          return (FALSE);
1007  982  }
1008  983  
1009  984  /*
1010  985   * NFS_OK part of directory operation result
1011  986   */
1012  987  bool_t
1013  988  xdr_drok(XDR *xdrs, struct nfsdrok *drok)
1014  989  {
1015  990          int32_t *ptr;
1016  991          int32_t *fhp;
1017  992          struct nfsfattr *na;
1018  993  
1019  994          if (xdrs->x_op == XDR_FREE)
1020  995                  return (TRUE);
1021  996  
1022  997          ptr = XDR_INLINE(xdrs,
1023  998              RNDUP(sizeof (fhandle_t)) + 17 * BYTES_PER_XDR_UNIT);
1024  999          if (ptr != NULL) {
1025 1000                  if (xdrs->x_op == XDR_DECODE) {
1026 1001                          fhp = (int32_t *)&drok->drok_fhandle;
1027 1002                          *fhp++ = *ptr++;
1028 1003                          *fhp++ = *ptr++;
1029 1004                          *fhp++ = *ptr++;
1030 1005                          *fhp++ = *ptr++;
1031 1006                          *fhp++ = *ptr++;
1032 1007                          *fhp++ = *ptr++;
1033 1008                          *fhp++ = *ptr++;
1034 1009                          *fhp = *ptr++;
1035 1010                          na = &drok->drok_attr;
1036 1011                          na->na_type = IXDR_GET_ENUM(ptr, enum nfsftype);
1037 1012                          na->na_mode = IXDR_GET_U_INT32(ptr);
1038 1013                          na->na_nlink = IXDR_GET_U_INT32(ptr);
1039 1014                          na->na_uid = IXDR_GET_U_INT32(ptr);
1040 1015                          na->na_gid = IXDR_GET_U_INT32(ptr);
1041 1016                          na->na_size = IXDR_GET_U_INT32(ptr);
1042 1017                          na->na_blocksize = IXDR_GET_U_INT32(ptr);
1043 1018                          na->na_rdev = IXDR_GET_U_INT32(ptr);
1044 1019                          na->na_blocks = IXDR_GET_U_INT32(ptr);
1045 1020                          na->na_fsid = IXDR_GET_U_INT32(ptr);
1046 1021                          na->na_nodeid = IXDR_GET_U_INT32(ptr);
1047 1022                          na->na_atime.tv_sec = IXDR_GET_U_INT32(ptr);
1048 1023                          na->na_atime.tv_usec = IXDR_GET_U_INT32(ptr);
1049 1024                          na->na_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
1050 1025                          na->na_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
1051 1026                          na->na_ctime.tv_sec = IXDR_GET_U_INT32(ptr);
1052 1027                          na->na_ctime.tv_usec = IXDR_GET_U_INT32(ptr);
1053 1028                  } else {
1054 1029                          fhp = (int32_t *)&drok->drok_fhandle;
1055 1030                          *ptr++ = *fhp++;
1056 1031                          *ptr++ = *fhp++;
1057 1032                          *ptr++ = *fhp++;
1058 1033                          *ptr++ = *fhp++;
1059 1034                          *ptr++ = *fhp++;
1060 1035                          *ptr++ = *fhp++;
1061 1036                          *ptr++ = *fhp++;
1062 1037                          *ptr++ = *fhp;
1063 1038                          na = &drok->drok_attr;
1064 1039                          IXDR_PUT_ENUM(ptr, na->na_type);
1065 1040                          IXDR_PUT_U_INT32(ptr, na->na_mode);
1066 1041                          IXDR_PUT_U_INT32(ptr, na->na_nlink);
1067 1042                          IXDR_PUT_U_INT32(ptr, na->na_uid);
1068 1043                          IXDR_PUT_U_INT32(ptr, na->na_gid);
1069 1044                          IXDR_PUT_U_INT32(ptr, na->na_size);
1070 1045                          IXDR_PUT_U_INT32(ptr, na->na_blocksize);
1071 1046                          IXDR_PUT_U_INT32(ptr, na->na_rdev);
1072 1047                          IXDR_PUT_U_INT32(ptr, na->na_blocks);
1073 1048                          IXDR_PUT_U_INT32(ptr, na->na_fsid);
1074 1049                          IXDR_PUT_U_INT32(ptr, na->na_nodeid);
1075 1050                          IXDR_PUT_U_INT32(ptr, na->na_atime.tv_sec);
1076 1051                          IXDR_PUT_U_INT32(ptr, na->na_atime.tv_usec);
1077 1052                          IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_sec);
1078 1053                          IXDR_PUT_U_INT32(ptr, na->na_mtime.tv_usec);
1079 1054                          IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_sec);
1080 1055                          IXDR_PUT_U_INT32(ptr, na->na_ctime.tv_usec);
1081 1056                  }
1082 1057                  return (TRUE);
1083 1058          }
1084 1059  
1085 1060          if (xdr_fhandle(xdrs, &drok->drok_fhandle) &&
1086 1061              xdr_fattr(xdrs, &drok->drok_attr)) {
1087 1062                  return (TRUE);
1088 1063          }
1089 1064          return (FALSE);
1090 1065  }
1091 1066  
1092 1067  #ifdef _LITTLE_ENDIAN
1093 1068  bool_t
1094 1069  xdr_fastdrok(XDR *xdrs, struct nfsdrok *drok)
1095 1070  {
1096 1071          struct nfsfattr *na;
1097 1072  
1098 1073          if (xdrs->x_op == XDR_FREE)
1099 1074                  return (TRUE);
1100 1075          if (xdrs->x_op == XDR_DECODE)
1101 1076                  return (FALSE);
1102 1077  
1103 1078          na = &drok->drok_attr;
1104 1079          na->na_type = (enum nfsftype)htonl(na->na_type);
1105 1080          na->na_mode = (uint32_t)htonl(na->na_mode);
1106 1081          na->na_nlink = (uint32_t)htonl(na->na_nlink);
1107 1082          na->na_uid = (uint32_t)htonl(na->na_uid);
1108 1083          na->na_gid = (uint32_t)htonl(na->na_gid);
1109 1084          na->na_size = (uint32_t)htonl(na->na_size);
1110 1085          na->na_blocksize = (uint32_t)htonl(na->na_blocksize);
1111 1086          na->na_rdev = (uint32_t)htonl(na->na_rdev);
1112 1087          na->na_blocks = (uint32_t)htonl(na->na_blocks);
1113 1088          na->na_fsid = (uint32_t)htonl(na->na_fsid);
1114 1089          na->na_nodeid = (uint32_t)htonl(na->na_nodeid);
1115 1090          na->na_atime.tv_sec = htonl(na->na_atime.tv_sec);
1116 1091          na->na_atime.tv_usec = htonl(na->na_atime.tv_usec);
1117 1092          na->na_mtime.tv_sec = htonl(na->na_mtime.tv_sec);
1118 1093          na->na_mtime.tv_usec = htonl(na->na_mtime.tv_usec);
1119 1094          na->na_ctime.tv_sec = htonl(na->na_ctime.tv_sec);
1120 1095          na->na_ctime.tv_usec = htonl(na->na_ctime.tv_usec);
1121 1096          return (TRUE);
1122 1097  }
1123 1098  #endif
1124 1099  
1125 1100  static struct xdr_discrim diropres_discrim[2] = {
1126 1101          { NFS_OK, xdr_drok },
1127 1102          { __dontcare__, NULL_xdrproc_t }
1128 1103  };
1129 1104  
1130 1105  /*
1131 1106   * Results from directory operation
1132 1107   */
1133 1108  bool_t
1134 1109  xdr_diropres(XDR *xdrs, struct nfsdiropres *dr)
1135 1110  {
1136 1111          return (xdr_union(xdrs, (enum_t *)&(dr->dr_status),
1137 1112              (caddr_t)&(dr->dr_drok), diropres_discrim, xdr_void));
1138 1113  }
1139 1114  
1140 1115  /*
1141 1116   * Results from directory operation
1142 1117   */
1143 1118  bool_t
1144 1119  xdr_fastdiropres(XDR *xdrs, struct nfsdiropres *dr)
1145 1120  {
1146 1121  #if defined(_LITTLE_ENDIAN)
1147 1122          /*
1148 1123           * we deal with the discriminator;  it's an enum
1149 1124           */
1150 1125          if (!xdr_fastenum(xdrs, (enum_t *)&dr->dr_status))
1151 1126                  return (FALSE);
1152 1127  
1153 1128          if (dr->dr_status == NFS_OK)
1154 1129                  return (xdr_fastdrok(xdrs, &dr->dr_drok));
1155 1130  #elif defined(_BIG_ENDIAN)
1156 1131          if (dr->dr_status == NFS_OK)
1157 1132                  return (TRUE);
1158 1133  #endif
1159 1134          return (xdr_fastshorten(xdrs, sizeof (*dr)));
1160 1135  }
1161 1136  
1162 1137  /*
1163 1138   * Time Structure, unsigned
1164 1139   */
1165 1140  bool_t
1166 1141  xdr_nfs2_timeval(XDR *xdrs, struct nfs2_timeval *tv)
1167 1142  {
1168 1143          if (xdr_u_int(xdrs, &tv->tv_sec) &&
1169 1144              xdr_u_int(xdrs, &tv->tv_usec))
1170 1145                  return (TRUE);
1171 1146          return (FALSE);
1172 1147  }
1173 1148  
1174 1149  /*
1175 1150   * arguments to setattr
1176 1151   */
1177 1152  bool_t
1178 1153  xdr_saargs(XDR *xdrs, struct nfssaargs *argp)
1179 1154  {
1180 1155          int32_t *ptr;
1181 1156          int32_t *arg;
1182 1157          struct nfssattr *sa;
1183 1158  
1184 1159          if (xdrs->x_op == XDR_FREE)
1185 1160                  return (TRUE);
1186 1161  
1187 1162          ptr = XDR_INLINE(xdrs,
1188 1163              RNDUP(sizeof (fhandle_t)) + 8 * BYTES_PER_XDR_UNIT);
1189 1164          if (ptr != NULL) {
1190 1165                  if (xdrs->x_op == XDR_DECODE) {
1191 1166                          arg = (int32_t *)&argp->saa_fh;
1192 1167                          *arg++ = *ptr++;
1193 1168                          *arg++ = *ptr++;
1194 1169                          *arg++ = *ptr++;
1195 1170                          *arg++ = *ptr++;
1196 1171                          *arg++ = *ptr++;
1197 1172                          *arg++ = *ptr++;
1198 1173                          *arg++ = *ptr++;
1199 1174                          *arg = *ptr++;
1200 1175                          sa = &argp->saa_sa;
1201 1176                          sa->sa_mode = IXDR_GET_U_INT32(ptr);
1202 1177                          sa->sa_uid = IXDR_GET_U_INT32(ptr);
1203 1178                          sa->sa_gid = IXDR_GET_U_INT32(ptr);
1204 1179                          sa->sa_size = IXDR_GET_U_INT32(ptr);
1205 1180                          sa->sa_atime.tv_sec = IXDR_GET_U_INT32(ptr);
1206 1181                          sa->sa_atime.tv_usec = IXDR_GET_U_INT32(ptr);
1207 1182                          sa->sa_mtime.tv_sec = IXDR_GET_U_INT32(ptr);
1208 1183                          sa->sa_mtime.tv_usec = IXDR_GET_U_INT32(ptr);
1209 1184                  } else {
1210 1185                          arg = (int32_t *)&argp->saa_fh;
1211 1186                          *ptr++ = *arg++;
1212 1187                          *ptr++ = *arg++;
1213 1188                          *ptr++ = *arg++;
1214 1189                          *ptr++ = *arg++;
1215 1190                          *ptr++ = *arg++;
1216 1191                          *ptr++ = *arg++;
1217 1192                          *ptr++ = *arg++;
1218 1193                          *ptr++ = *arg;
1219 1194                          sa = &argp->saa_sa;
1220 1195                          IXDR_PUT_U_INT32(ptr, sa->sa_mode);
1221 1196                          IXDR_PUT_U_INT32(ptr, sa->sa_uid);
1222 1197                          IXDR_PUT_U_INT32(ptr, sa->sa_gid);
1223 1198                          IXDR_PUT_U_INT32(ptr, sa->sa_size);
1224 1199                          IXDR_PUT_U_INT32(ptr, sa->sa_atime.tv_sec);
1225 1200                          IXDR_PUT_U_INT32(ptr, sa->sa_atime.tv_usec);
1226 1201                          IXDR_PUT_U_INT32(ptr, sa->sa_mtime.tv_sec);
1227 1202                          IXDR_PUT_U_INT32(ptr, sa->sa_mtime.tv_usec);
1228 1203                  }
1229 1204                  return (TRUE);
1230 1205          }
1231 1206  
1232 1207          if (xdr_fhandle(xdrs, &argp->saa_fh) &&
1233 1208              xdr_sattr(xdrs, &argp->saa_sa)) {
1234 1209                  return (TRUE);
1235 1210          }
1236 1211          return (FALSE);
1237 1212  }
1238 1213  
1239 1214  
1240 1215  /*
1241 1216   * arguments to create and mkdir
1242 1217   */
1243 1218  bool_t
1244 1219  xdr_creatargs(XDR *xdrs, struct nfscreatargs *argp)
1245 1220  {
1246 1221          argp->ca_sa = &argp->ca_sa_buf;
1247 1222  
1248 1223          if (xdrs->x_op == XDR_DECODE)
1249 1224                  argp->ca_sa = &argp->ca_sa_buf;
1250 1225          if (xdr_diropargs(xdrs, &argp->ca_da) &&
1251 1226              xdr_sattr(xdrs, argp->ca_sa)) {
1252 1227                  return (TRUE);
1253 1228          }
1254 1229          return (FALSE);
1255 1230  }
1256 1231  
1257 1232  /*
1258 1233   * arguments to link
1259 1234   */
1260 1235  bool_t
1261 1236  xdr_linkargs(XDR *xdrs, struct nfslinkargs *argp)
1262 1237  {
1263 1238          if (xdrs->x_op == XDR_DECODE)
1264 1239                  argp->la_from = &argp->la_from_buf;
1265 1240          if (xdr_fhandle(xdrs, argp->la_from) &&
1266 1241              xdr_diropargs(xdrs, &argp->la_to)) {
1267 1242                  return (TRUE);
1268 1243          }
1269 1244          return (FALSE);
1270 1245  }
1271 1246  
1272 1247  /*
1273 1248   * arguments to rename
1274 1249   */
1275 1250  bool_t
1276 1251  xdr_rnmargs(XDR *xdrs, struct nfsrnmargs *argp)
1277 1252  {
1278 1253          if (xdr_diropargs(xdrs, &argp->rna_from) &&
1279 1254              xdr_diropargs(xdrs, &argp->rna_to))
1280 1255                  return (TRUE);
1281 1256          return (FALSE);
1282 1257  }
1283 1258  
1284 1259  
1285 1260  /*
1286 1261   * arguments to symlink
1287 1262   */
1288 1263  bool_t
1289 1264  xdr_slargs(XDR *xdrs, struct nfsslargs *argp)
1290 1265  {
1291 1266          if (xdrs->x_op == XDR_FREE) {
1292 1267                  if (!xdr_diropargs(xdrs, &argp->sla_from))
1293 1268                          return (FALSE);
1294 1269                  if ((argp->sla_tnm_flags & SLA_FREETNM) &&
1295 1270                      !xdr_string(xdrs, &argp->sla_tnm, (uint_t)NFS_MAXPATHLEN))
1296 1271                          return (FALSE);
1297 1272                  return (TRUE);
1298 1273          }
1299 1274  
1300 1275          if (xdrs->x_op == XDR_DECODE) {
1301 1276                  argp->sla_sa = &argp->sla_sa_buf;
1302 1277                  if (argp->sla_tnm == NULL)
1303 1278                          argp->sla_tnm_flags |= SLA_FREETNM;
1304 1279          }
1305 1280  
1306 1281          if (xdr_diropargs(xdrs, &argp->sla_from) &&
1307 1282              xdr_string(xdrs, &argp->sla_tnm, (uint_t)NFS_MAXPATHLEN) &&
1308 1283              xdr_sattr(xdrs, argp->sla_sa)) {
1309 1284                  return (TRUE);
1310 1285          }
1311 1286          return (FALSE);
1312 1287  }
1313 1288  
1314 1289  
1315 1290  /*
1316 1291   * NFS_OK part of statfs operation
1317 1292   */
1318 1293  bool_t
1319 1294  xdr_fsok(XDR *xdrs, struct nfsstatfsok *fsok)
1320 1295  {
1321 1296          int32_t *ptr;
1322 1297  
1323 1298          if (xdrs->x_op == XDR_FREE)
1324 1299                  return (TRUE);
1325 1300  
1326 1301          ptr = XDR_INLINE(xdrs, 5 * BYTES_PER_XDR_UNIT);
1327 1302          if (ptr != NULL) {
1328 1303                  if (xdrs->x_op == XDR_DECODE) {
1329 1304                          fsok->fsok_tsize = IXDR_GET_INT32(ptr);
1330 1305                          fsok->fsok_bsize = IXDR_GET_INT32(ptr);
1331 1306                          fsok->fsok_blocks = IXDR_GET_INT32(ptr);
1332 1307                          fsok->fsok_bfree = IXDR_GET_INT32(ptr);
1333 1308                          fsok->fsok_bavail = IXDR_GET_INT32(ptr);
1334 1309                  } else {
1335 1310                          IXDR_PUT_INT32(ptr, fsok->fsok_tsize);
1336 1311                          IXDR_PUT_INT32(ptr, fsok->fsok_bsize);
1337 1312                          IXDR_PUT_INT32(ptr, fsok->fsok_blocks);
1338 1313                          IXDR_PUT_INT32(ptr, fsok->fsok_bfree);
1339 1314                          IXDR_PUT_INT32(ptr, fsok->fsok_bavail);
1340 1315                  }
1341 1316                  return (TRUE);
1342 1317          }
1343 1318  
1344 1319          if (xdr_u_int(xdrs, &fsok->fsok_tsize) &&
1345 1320              xdr_u_int(xdrs, &fsok->fsok_bsize) &&
1346 1321              xdr_u_int(xdrs, &fsok->fsok_blocks) &&
1347 1322              xdr_u_int(xdrs, &fsok->fsok_bfree) &&
1348 1323              xdr_u_int(xdrs, &fsok->fsok_bavail)) {
1349 1324                  return (TRUE);
1350 1325          }
1351 1326          return (FALSE);
1352 1327  }
1353 1328  
1354 1329  #ifdef _LITTLE_ENDIAN
1355 1330  bool_t
1356 1331  xdr_fastfsok(XDR *xdrs, struct nfsstatfsok *fsok)
1357 1332  {
1358 1333  
1359 1334          if (xdrs->x_op == XDR_FREE)
1360 1335                  return (TRUE);
1361 1336          if (xdrs->x_op == XDR_DECODE)
1362 1337                  return (FALSE);
1363 1338  
1364 1339          fsok->fsok_tsize = htonl(fsok->fsok_tsize);
1365 1340          fsok->fsok_bsize = htonl(fsok->fsok_bsize);
1366 1341          fsok->fsok_blocks = htonl(fsok->fsok_blocks);
1367 1342          fsok->fsok_bfree = htonl(fsok->fsok_bfree);
1368 1343          fsok->fsok_bavail = htonl(fsok->fsok_bavail);
1369 1344          return (TRUE);
1370 1345  }
1371 1346  #endif
1372 1347  
1373 1348  static struct xdr_discrim statfs_discrim[2] = {
1374 1349          { NFS_OK, xdr_fsok },
1375 1350          { __dontcare__, NULL_xdrproc_t }
1376 1351  };
1377 1352  
1378 1353  /*
1379 1354   * Results of statfs operation
1380 1355   */
1381 1356  bool_t
1382 1357  xdr_statfs(XDR *xdrs, struct nfsstatfs *fs)
1383 1358  {
1384 1359          return (xdr_union(xdrs, (enum_t *)&(fs->fs_status),
1385 1360              (caddr_t)&(fs->fs_fsok), statfs_discrim, xdr_void));
1386 1361  }
1387 1362  
1388 1363  /*
1389 1364   * Results of statfs operation
1390 1365   */
1391 1366  bool_t
1392 1367  xdr_faststatfs(XDR *xdrs, struct nfsstatfs *fs)
1393 1368  {
1394 1369  #if defined(_LITTLE_ENDIAN)
1395 1370          /*
1396 1371           * we deal with the discriminator;  it's an enum
1397 1372           */
1398 1373          if (!xdr_fastenum(xdrs, (enum_t *)&fs->fs_status))
1399 1374                  return (FALSE);
1400 1375  
1401 1376          if (fs->fs_status == NFS_OK)
1402 1377                  return (xdr_fastfsok(xdrs, &fs->fs_fsok));
1403 1378  #elif defined(_BIG_ENDIAN)
1404 1379          if (fs->fs_status == NFS_OK)
1405 1380                  return (TRUE);
1406 1381  #endif
1407 1382          return (xdr_fastshorten(xdrs, sizeof (*fs)));
1408 1383  }
1409 1384  
1410 1385  #ifdef _LITTLE_ENDIAN
1411 1386  /*
1412 1387   * XDR enumerations
1413 1388   */
1414 1389  #ifndef lint
1415 1390  static enum sizecheck { SIZEVAL } sizecheckvar; /* used to find the size of */
1416 1391                                                  /* an enum */
1417 1392  #endif
1418 1393  bool_t
1419 1394  xdr_fastenum(XDR *xdrs, enum_t *ep)
1420 1395  {
1421 1396          if (xdrs->x_op == XDR_FREE)
1422 1397                  return (TRUE);
1423 1398          if (xdrs->x_op == XDR_DECODE)
1424 1399                  return (FALSE);
1425 1400  
1426 1401  #ifndef lint
1427 1402          /*
1428 1403           * enums are treated as ints
1429 1404           */
1430 1405          if (sizeof (sizecheckvar) == sizeof (int32_t)) {
1431 1406                  *ep = (enum_t)htonl((int32_t)(*ep));
1432 1407          } else if (sizeof (sizecheckvar) == sizeof (short)) {
1433 1408                  *ep = (enum_t)htons((short)(*ep));
1434 1409          } else {
1435 1410                  return (FALSE);
1436 1411          }
1437 1412          return (TRUE);
1438 1413  #else
1439 1414          (void) (xdr_short(xdrs, (short *)ep));
1440 1415          return (xdr_int(xdrs, (int *)ep));
1441 1416  #endif
1442 1417  }
1443 1418  #endif
1444 1419  
1445 1420  static bool_t
1446 1421  xdr_fastshorten(XDR *xdrs, uint_t ressize)
1447 1422  {
1448 1423          uint_t curpos;
1449 1424  
1450 1425          curpos = XDR_GETPOS(xdrs);
1451 1426          ressize -= BYTES_PER_XDR_UNIT;
1452 1427          curpos -= ressize;
1453 1428          return (XDR_SETPOS(xdrs, curpos));
1454 1429  }
  
    | 
      ↓ open down ↓ | 
    564 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX