Print this page
    
Revert exi_zone to exi_zoneid, and install exi_ne backpointer
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/nfs/export.h
          +++ new/usr/src/uts/common/nfs/export.h
   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.
  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  /*
  23   23   * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  25   25   * Copyright 2016 Jason King.
  26   26   * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  27   27   */
  28   28  
  29   29  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  30   30  /*        All Rights Reserved   */
  31   31  
  32   32  #ifndef _NFS_EXPORT_H
  33   33  #define _NFS_EXPORT_H
  34   34  
  35   35  #include <nfs/nfs_sec.h>
  36   36  #include <nfs/auth.h>
  37   37  #include <sys/vnode.h>
  38   38  #include <nfs/nfs4.h>
  39   39  #include <sys/kiconv.h>
  40   40  #include <sys/avl.h>
  41   41  #include <sys/zone.h>
  42   42  
  43   43  #ifdef _KERNEL
  44   44  #include <sys/pkp_hash.h> /* for PKP_HASH_SIZE */
  45   45  #endif /* _KERNEL */
  46   46  
  47   47  #ifdef  __cplusplus
  48   48  extern "C" {
  49   49  #endif
  50   50  
  51   51  /*
  52   52   * nfs pseudo flavor number is owned by IANA. Need to make sure the
  53   53   * Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
  54   54   * new IANA defined pseudo flavor numbers. The chance for the overlap
  55   55   * is very small since the growth of new flavor numbers is expected
  56   56   * to be limited.
  57   57   */
  58   58  #define NFS_FLAVOR_NOMAP        999999  /* no nfs flavor mapping */
  59   59  
  60   60  /*
  61   61   * As duplicate flavors can be passed into exportfs in the arguments, we
  62   62   * allocate a cleaned up array with non duplicate flavors on the stack.
  63   63   * So we need to know how much to allocate.
  64   64   */
  65   65  #define MAX_FLAVORS             6       /* none, sys, dh, krb5, krb5i krb5p */
  66   66  
  67   67  /*
  68   68   * Note: exported_lock is currently used to ensure the integrity of
  69   69   * the secinfo fields.
  70   70   */
  71   71  struct secinfo {
  72   72          seconfig_t      s_secinfo;      /* /etc/nfssec.conf entry */
  73   73          unsigned int    s_flags;        /* flags (see below) */
  74   74          int32_t         s_refcnt;       /* reference count for tracking */
  75   75                                          /* how many children (self included) */
  76   76                                          /* use this flavor. */
  77   77          int             s_window;       /* window */
  78   78          uint_t          s_rootid;       /* UID to use for authorized roots */
  79   79          int             s_rootcnt;      /* count of root names */
  80   80          caddr_t         *s_rootnames;   /* array of root names */
  81   81                                          /* they are strings for AUTH_DES and */
  82   82                                          /* rpc_gss_principal_t for RPCSEC_GSS */
  83   83  };
  84   84  
  85   85  #ifdef _SYSCALL32
  86   86  struct secinfo32 {
  87   87          seconfig32_t    s_secinfo;      /* /etc/nfssec.conf entry */
  88   88          uint32_t        s_flags;        /* flags (see below) */
  89   89          int32_t         s_refcnt;       /* reference count for tracking */
  90   90                                          /* how many children (self included) */
  91   91                                          /* use this flavor. */
  92   92          int32_t         s_window;       /* window */
  93   93          uint32_t        s_rootid;       /* UID to use for authorized roots */
  94   94          int32_t         s_rootcnt;      /* count of root names */
  95   95          caddr32_t       s_rootnames;    /* array of root names */
  96   96                                          /* they are strings for AUTH_DES and */
  97   97                                          /* rpc_gss_principal_t for RPCSEC_GSS */
  98   98  };
  99   99  #endif /* _SYSCALL32 */
 100  100  
 101  101  /*
 102  102   * security negotiation related
 103  103   */
 104  104  
 105  105  #define SEC_QUERY       0x01    /* query sec modes */
 106  106  
 107  107  struct sec_ol {
 108  108          int             sec_flags;      /* security nego flags */
 109  109          uint_t          sec_index;      /* index into sec flavor array */
 110  110  };
 111  111  
 112  112  /*
 113  113   * Per-mode flags (secinfo.s_flags)
 114  114   */
 115  115  #define M_RO            0x01    /* exported ro to all */
 116  116  #define M_ROL           0x02    /* exported ro to all listed */
 117  117  #define M_RW            0x04    /* exported rw to all */
 118  118  #define M_RWL           0x08    /* exported ro to all listed */
 119  119  #define M_ROOT          0x10    /* root list is defined */
 120  120  #define M_4SEC_EXPORTED 0x20    /* this is an explicitly shared flavor */
 121  121  #define M_NONE          0x40    /* none list is defined */
 122  122  #define M_MAP           0x80    /* uidmap and/or gidmap is defined */
 123  123  
 124  124  /* invalid secinfo reference count */
 125  125  #define SEC_REF_INVALID(p) ((p)->s_refcnt < 1)
 126  126  
 127  127  /* last secinfo reference */
 128  128  #define SEC_REF_LAST(p) ((p)->s_refcnt == 1)
 129  129  
 130  130  /* sec flavor explicitly shared for the exported node */
 131  131  #define SEC_REF_EXPORTED(p) ((p)->s_flags & M_4SEC_EXPORTED)
 132  132  
 133  133  /* the only reference count left is for referring itself */
 134  134  #define SEC_REF_SELF(p) (SEC_REF_LAST(p) && SEC_REF_EXPORTED(p))
 135  135  
 136  136  /*
 137  137   * The export information passed to exportfs() (Version 2)
 138  138   */
 139  139  #define EX_CURRENT_VERSION 2    /* current version of exportdata struct */
 140  140  
 141  141  struct exportdata {
 142  142          int             ex_version;     /* structure version */
 143  143          char            *ex_path;       /* exported path */
 144  144          size_t          ex_pathlen;     /* path length */
 145  145          int             ex_flags;       /* flags */
 146  146          unsigned int    ex_anon;        /* uid for unauthenticated requests */
 147  147          int             ex_seccnt;      /* count of security modes */
 148  148          struct secinfo  *ex_secinfo;    /* security mode info */
 149  149          char            *ex_index;      /* index file for public filesystem */
 150  150          char            *ex_log_buffer; /* path to logging buffer file */
 151  151          size_t          ex_log_bufferlen;       /* buffer file path len */
 152  152          char            *ex_tag;        /* tag used to identify log config */
 153  153          size_t          ex_taglen;      /* tag length */
 154  154  };
 155  155  
 156  156  #ifdef _SYSCALL32
 157  157  struct exportdata32 {
 158  158          int32_t         ex_version;     /* structure version */
 159  159          caddr32_t       ex_path;        /* exported path */
 160  160          int32_t         ex_pathlen;     /* path length */
 161  161          int32_t         ex_flags;       /* flags */
 162  162          uint32_t        ex_anon;        /* uid for unauthenticated requests */
 163  163          int32_t         ex_seccnt;      /* count of security modes */
 164  164          caddr32_t       ex_secinfo;     /* security mode info */
 165  165          caddr32_t       ex_index;       /* index file for public filesystem */
 166  166          caddr32_t       ex_log_buffer;  /* path to logging buffer file */
 167  167          int32_t         ex_log_bufferlen;       /* buffer file path len */
 168  168          caddr32_t       ex_tag;         /* tag used to identify log config */
 169  169          int32_t         ex_taglen;      /* tag length */
 170  170  };
 171  171  #endif /* _SYSCALL32 */
 172  172  
 173  173  /*
 174  174   * exported vfs flags.
 175  175   */
 176  176  
 177  177  #define EX_NOSUID       0x01    /* exported with unsetable set[ug]ids */
 178  178  #define EX_ACLOK        0x02    /* exported with maximal access if acl exists */
 179  179  #define EX_PUBLIC       0x04    /* exported with public filehandle */
 180  180  #define EX_NOSUB        0x08    /* no nfs_getfh or MCL below export point */
 181  181  #define EX_INDEX        0x10    /* exported with index file specified */
 182  182  #define EX_LOG          0x20    /* logging enabled */
 183  183  #define EX_LOG_ALLOPS   0x40    /* logging of all RPC operations enabled */
 184  184                                  /* by default only operations which affect */
 185  185                                  /* transaction logging are enabled */
 186  186  #define EX_PSEUDO       0x80    /* pseudo filesystem export */
 187  187  #ifdef VOLATILE_FH_TEST
 188  188  #define EX_VOLFH        0x100   /* XXX nfsv4 fh may expire anytime */
 189  189  #define EX_VOLRNM       0x200   /* XXX nfsv4 fh expire at rename */
 190  190  #define EX_VOLMIG       0x400   /* XXX nfsv4 fh expire at migration */
 191  191  #define EX_NOEXPOPEN    0x800   /* XXX nfsv4 fh no expire with open */
 192  192  #endif /* VOLATILE_FH_TEST */
 193  193  
 194  194  #define EX_CHARMAP      0x1000  /* NFS may need a character set conversion */
 195  195  #define EX_NOACLFAB     0x2000  /* If set, NFSv2 and v3 servers won't */
 196  196                                  /* fabricate an aclent_t ACL on file systems */
 197  197                                  /* that don't support aclent_t ACLs */
 198  198  #define EX_NOHIDE       0x4000  /* traversable from exported parent */
 199  199  
 200  200  #ifdef  _KERNEL
 201  201  
 202  202  #define RPC_IDEMPOTENT  0x1     /* idempotent or not */
 203  203  /*
 204  204   * Be very careful about which NFS procedures get the RPC_ALLOWANON bit.
 205  205   * Right now, if this bit is on, we ignore the results of per NFS request
 206  206   * access control.
 207  207   */
 208  208  #define RPC_ALLOWANON   0x2     /* allow anonymous access */
 209  209  #define RPC_MAPRESP     0x4     /* use mapped response buffer */
 210  210  #define RPC_AVOIDWORK   0x8     /* do work avoidance for dups */
 211  211  #define RPC_PUBLICFH_OK 0x10    /* allow use of public filehandle */
 212  212  
 213  213  /*
 214  214   * RPC_ALL is an or of all above bits to be used with "don't care"
 215  215   * nfsv4 ops. The flags of an nfsv4 request is the bit-AND of the
 216  216   * per-op flags.
 217  217   */
 218  218  #define RPC_ALL (RPC_IDEMPOTENT|RPC_ALLOWANON|RPC_AVOIDWORK|RPC_PUBLICFH_OK)
 219  219  
 220  220  
 221  221  #ifdef VOLATILE_FH_TEST
 222  222  struct ex_vol_rename {
 223  223          nfs_fh4_fmt_t vrn_fh_fmt;
 224  224          struct ex_vol_rename *vrn_next;
 225  225  };
 226  226  #endif /* VOLATILE_FH_TEST */
 227  227  
 228  228  /*
 229  229   * An auth cache client entry.  This is the umbrella structure and contains all
 230  230   * related auth_cache entries in the authc_tree AVL tree.
 231  231   */
 232  232  struct auth_cache_clnt {
 233  233          avl_node_t              authc_link;
 234  234          struct netbuf           authc_addr;     /* address of the client */
 235  235          krwlock_t               authc_lock;     /* protects authc_tree */
 236  236          avl_tree_t              authc_tree;     /* auth_cache entries */
 237  237  };
 238  238  
 239  239  /*
 240  240   * An auth cache entry can exist in 6 states.
 241  241   *
 242  242   * A NEW entry was recently allocated and added to the cache.  It does not
 243  243   * contain the valid auth state yet.
 244  244   *
 245  245   * A WAITING entry is one which is actively engaging the user land mountd code
 246  246   * to authenticate or re-authenticate it.  The auth state might not be valid
 247  247   * yet.  The other threads should wait on auth_cv until the retrieving thread
 248  248   * finishes the retrieval and changes the auth cache entry to FRESH, or NEW (in
 249  249   * a case this entry had no valid auth state yet).
 250  250   *
 251  251   * A REFRESHING entry is one which is actively engaging the user land mountd
 252  252   * code to re-authenticate the cache entry.  There is currently no other thread
 253  253   * waiting for the results of the refresh.
 254  254   *
 255  255   * A FRESH entry is one which is valid (it is either newly retrieved or has
 256  256   * been refreshed at least once).
 257  257   *
 258  258   * A STALE entry is one which has been detected to be too old.  The transition
 259  259   * from FRESH to STALE prevents multiple threads from submitting refresh
 260  260   * requests.
 261  261   *
 262  262   * An INVALID entry is one which was either STALE or REFRESHING and was deleted
 263  263   * out of the encapsulating exi.  Since we can't delete it yet, we mark it as
 264  264   * INVALID, which lets the refresh thread know not to work on it and free it
 265  265   * instead.
 266  266   *
 267  267   * Note that the auth state of the entry is valid, even if the entry is STALE.
 268  268   * Just as you can eat stale bread, you can consume a stale cache entry. The
 269  269   * only time the contents change could be during the transition from REFRESHING
 270  270   * or WAITING to FRESH.
 271  271   *
 272  272   * Valid state transitions:
 273  273   *
 274  274   *          alloc
 275  275   *            |
 276  276   *            v
 277  277   *         +-----+
 278  278   *    +--->| NEW |------>free
 279  279   *    |    +-----+
 280  280   *    |       |
 281  281   *    |       v
 282  282   *    |  +---------+
 283  283   *    +<-| WAITING |
 284  284   *    ^  +---------+
 285  285   *    |       |
 286  286   *    |       v
 287  287   *    |       +<--------------------------+<---------------+
 288  288   *    |       |                           ^                |
 289  289   *    |       v                           |                |
 290  290   *    |   +-------+    +-------+    +------------+    +---------+
 291  291   *    +---| FRESH |--->| STALE |--->| REFRESHING |--->| WAITING |
 292  292   *        +-------+    +-------+    +------------+    +---------+
 293  293   *            |            |              |
 294  294   *            |            v              |
 295  295   *            v       +---------+         |
 296  296   *          free<-----| INVALID |<--------+
 297  297   *                    +---------+
 298  298   */
 299  299  typedef enum auth_state {
 300  300          NFS_AUTH_FRESH,
 301  301          NFS_AUTH_STALE,
 302  302          NFS_AUTH_REFRESHING,
 303  303          NFS_AUTH_INVALID,
 304  304          NFS_AUTH_NEW,
 305  305          NFS_AUTH_WAITING
 306  306  } auth_state_t;
 307  307  
 308  308  /*
 309  309   * An authorization cache entry
 310  310   *
 311  311   * Either the state in auth_state will protect the
 312  312   * contents or auth_lock must be held.
 313  313   */
 314  314  struct auth_cache {
 315  315          avl_node_t              auth_link;
 316  316          struct auth_cache_clnt  *auth_clnt;
 317  317          int                     auth_flavor;
 318  318          cred_t                  *auth_clnt_cred;
 319  319          uid_t                   auth_srv_uid;
 320  320          gid_t                   auth_srv_gid;
 321  321          uint_t                  auth_srv_ngids;
 322  322          gid_t                   *auth_srv_gids;
 323  323          int                     auth_access;
 324  324          time_t                  auth_time;
 325  325          time_t                  auth_freshness;
 326  326          auth_state_t            auth_state;
 327  327          kmutex_t                auth_lock;
 328  328          kcondvar_t              auth_cv;
 329  329  };
 330  330  
 331  331  #define AUTH_TABLESIZE  32
 332  332  
 333  333  /*
 334  334   * Structure containing log file meta-data.
 335  335   */
 336  336  struct log_file {
 337  337          unsigned int    lf_flags;       /* flags (see below) */
 338  338          int             lf_writers;     /* outstanding writers */
 339  339          int             lf_refcnt;      /* references to this struct */
 340  340          caddr_t         lf_path;        /* buffer file location */
 341  341          vnode_t         *lf_vp;         /* vnode for the buffer file */
 342  342          kmutex_t        lf_lock;
 343  343          kcondvar_t      lf_cv_waiters;
 344  344  };
 345  345  
 346  346  /*
 347  347   * log_file and log_buffer flags.
 348  348   */
 349  349  #define L_WAITING       0x01            /* flush of in-core data to stable */
 350  350                                          /* storage in progress */
 351  351  #define L_PRINTED       0x02            /* error message printed to console */
 352  352  #define L_ERROR         0x04            /* error condition detected */
 353  353  
 354  354  /*
 355  355   * The logging buffer information.
 356  356   * This structure may be shared by multiple exportinfo structures,
 357  357   * if they share the same buffer file.
 358  358   * This structure contains the basic information about the buffer, such
 359  359   * as it's location in the filesystem.
 360  360   *
 361  361   * 'lb_lock' protects all the fields in this structure except for 'lb_path',
 362  362   * and 'lb_next'.
 363  363   * 'lb_path' is a write-once/read-many field which needs no locking, it is
 364  364   * set before the structure is linked to any exportinfo structure.
 365  365   * 'lb_next' is protected by the log_buffer_list_lock.
 366  366   */
 367  367  struct log_buffer {
 368  368          unsigned int    lb_flags;       /* L_ONLIST set? */
 369  369          int             lb_refcnt;      /* references to this struct */
 370  370          unsigned int    lb_rec_id;      /* used to generate unique id */
 371  371          caddr_t         lb_path;        /* buffer file pathname */
 372  372          struct log_file *lb_logfile;    /* points to log_file structure */
 373  373          kmutex_t        lb_lock;
 374  374          struct log_buffer       *lb_next;
 375  375          kcondvar_t      lb_cv_waiters;
 376  376          caddr_t         lb_records;     /* linked list of records to write */
 377  377          int             lb_num_recs;    /* # of records to write */
 378  378          ssize_t         lb_size_queued; /* number of bytes queued for write */
 379  379  };
 380  380  
 381  381  #define LOG_BUFFER_HOLD(lbp)    { \
 382  382          mutex_enter(&(lbp)->lb_lock); \
 383  383          (lbp)->lb_refcnt++; \
 384  384          mutex_exit(&(lbp)->lb_lock); \
 385  385  }
 386  386  
 387  387  #define LOG_BUFFER_RELE(lbp)    { \
 388  388          log_buffer_rele(lbp); \
 389  389  }
 390  390  
 391  391  /*
 392  392   * Structure for character set conversion mapping based on client address.
 393  393   */
 394  394  struct charset_cache {
 395  395          struct charset_cache *next;
 396  396          kiconv_t        inbound;
 397  397          kiconv_t        outbound;
 398  398          struct sockaddr client_addr;
 399  399  };
 400  400  
 401  401  /* Forward declarations */
 402  402  struct exportinfo;
 403  403  struct exp_visible;
 404  404  struct svc_req;
 405  405  
 406  406  /*
 407  407   * Treenodes are used to build tree representing every node which is part
 408  408   * of nfs server pseudo namespace. They are connected with both exportinfo
 409  409   * and exp_visible struct. They were introduced to avoid lookup of ".."
 410  410   * in the underlying file system during unshare, which was failing if the
 411  411   * file system was forcibly unmounted or if the directory was removed.
 412  412   * One exp_visible_t can be shared via several treenode_t, i.e.
 413  413   * different tree_vis can point to the same exp_visible_t.
 414  414   * This will happen if some directory is on two different shared paths:
 415  415   * E.g. after share /tmp/a/b1 and share /tmp/a/b2 there will be two treenodes
 416  416   * corresponding to /tmp/a and both will have same value in tree_vis.
 417  417   *
 418  418   *
 419  419   *
 420  420   *     NEW DATA STRUCT         ORIGINAL DATA STRUCT
 421  421   *
 422  422   * ns_root +---+               +----------+
 423  423   *         | / |               |PSEUDO EXP|-->+---+   +---+   +---+
 424  424   *         +---+---------  ----+----------+   | a |-->| k |-->| b |
 425  425   *          /\                                +---+   +---+   +---+
 426  426   *         /  \                                .       .       .
 427  427   *     +---+...\.........  .....................       .       .
 428  428   *    *| a |    \              +----------+            .       .
 429  429   *     +---+-----\-------  ----|REAL EXP a|            .       .
 430  430   *       /        \            +----------+            .       .
 431  431   *      /        +===+...  .............................       .
 432  432   *     /        *| k |         +----------+                    .
 433  433   *    /          +===+---  ----|REAL EXP k|                    .
 434  434   *   /                         +----------+                    .
 435  435   *  +===+................  .....................................
 436  436   * *| b |                      +----------+
 437  437   *  +===+----------------  ----|REAL EXP b|-->+---+
 438  438   *     \                       +----------+   | d |
 439  439   *     +===+.............  ...................+---+
 440  440   *     | d |                   +----------+
 441  441   *     +===+-------------  ----|PSEUDO EXP|-->+---+   +---+
 442  442   *     /                       +----------+   | e |-->| g |
 443  443   * +---+.................  ...................+---+   +---+
 444  444   * | e |                                              .
 445  445   * +---+                                              .
 446  446   *    \                                               .
 447  447   *    +---+..............  ............................
 448  448   *   *| g |                    +----------+
 449  449   *    +---+--------------  ----|REAL EXP g|
 450  450   *                             +----------+
 451  451   *
 452  452   *
 453  453   *
 454  454   * +===+               +---+                    +---+
 455  455   * | b |..mountpoint   | e |..directory/file   *| a |..node is shared
 456  456   * +===+  (VROOT)      +---+                    +---+
 457  457   *
 458  458   *
 459  459   * Bi-directional interconnect:
 460  460   * treenode_t::tree_exi ---------  exportinfo_t::exi_tree
 461  461   * One-way direction connection:
 462  462   * treenode_t::tree_vis .........> exp_visible_t
 463  463   */
 464  464  /* Access to treenode_t is under protection of exported_lock RW_LOCK */
 465  465  typedef struct treenode {
  
    | 
      ↓ open down ↓ | 
    465 lines elided | 
    
      ↑ open up ↑ | 
  
 466  466          /* support for generic n-ary trees */
 467  467          struct treenode *tree_parent;
 468  468          struct treenode *tree_child_first;
 469  469          struct treenode *tree_sibling; /* next sibling */
 470  470          /* private, nfs specific part */
 471  471          struct exportinfo  *tree_exi;
 472  472          struct exp_visible *tree_vis;
 473  473  } treenode_t;
 474  474  
 475  475  /*
      476 + * Now that we have links to chase, we can get the zone rootvp just from
      477 + * an export.  No current-zone-context needed.
      478 + */
      479 +#define EXI_TO_ZONEROOTVP(exi) ((exi)->exi_ne->exi_root->exi_vp)
      480 +
      481 +/*
 476  482   * TREE_ROOT checks if the node corresponds to a filesystem root or
 477  483   * the zone's root directory.
 478  484   * TREE_EXPORTED checks if the node is explicitly shared
 479  485   */
 480  486  
 481  487  #define TREE_ROOT(t) \
 482  488          ((t)->tree_exi != NULL && \
 483  489          (((t)->tree_exi->exi_vp->v_flag & VROOT) || \
 484      -        VN_CMP((t)->tree_exi->exi_zone->zone_rootvp, (t)->tree_exi->exi_vp)))
      490 +        VN_CMP(EXI_TO_ZONEROOTVP((t)->tree_exi), (t)->tree_exi->exi_vp)))
 485  491  
 486  492  #define TREE_EXPORTED(t) \
 487  493          ((t)->tree_exi && !PSEUDO((t)->tree_exi))
 488  494  
 489  495  #define EXPTABLESIZE   256
 490  496  
 491  497  struct exp_hash {
 492  498          struct exportinfo       *prev;  /* ptr to the previous exportinfo */
 493  499          struct exportinfo       *next;  /* ptr to the next exportinfo */
 494  500          struct exportinfo       **bckt; /* backpointer to the hash bucket */
 495  501  };
 496  502  
 497  503  /*
 498  504   * A node associated with an export entry on the
 499  505   * list of exported filesystems.
 500  506   *
 501  507   * exi_count+exi_lock protects an individual exportinfo from being freed
 502  508   * when in use.
 503  509   *
 504  510   * You must have the writer lock on exported_lock to add/delete an exportinfo
 505  511   * structure to/from the list.
 506  512   *
 507  513   * exi_volatile_dev maps to VSW_VOLATILEDEV.  It means that the
 508  514   * underlying fs devno can change on each mount.  When set, the server
 509  515   * should not use va_fsid for a GETATTR(FATTR4_FSID) reply.  It must
 510  516   * use exi_fsid because it is guaranteed to be persistent.  This isn't
 511  517   * in any way related to NFS4 volatile filehandles.
 512  518   *
 513  519   * The exi_cache_lock protects the exi_cache AVL trees.
 514  520   */
 515  521  struct exportinfo {
  
    | 
      ↓ open down ↓ | 
    21 lines elided | 
    
      ↑ open up ↑ | 
  
 516  522          struct exportdata       exi_export;
 517  523          fsid_t                  exi_fsid;
 518  524          struct fid              exi_fid;
 519  525          struct exp_hash         fid_hash;
 520  526          struct exp_hash         path_hash;
 521  527          struct treenode         *exi_tree;
 522  528          fhandle_t               exi_fh;
 523  529          krwlock_t               exi_cache_lock;
 524  530          kmutex_t                exi_lock;
 525  531          uint_t                  exi_count;
      532 +        zoneid_t                exi_zoneid;
 526  533          vnode_t                 *exi_vp;
 527  534          vnode_t                 *exi_dvp;
 528  535          avl_tree_t              *exi_cache[AUTH_TABLESIZE];
 529  536          struct log_buffer       *exi_logbuffer;
 530  537          struct exp_visible      *exi_visible;
 531  538          struct charset_cache    *exi_charset;
 532  539          unsigned                exi_volatile_dev:1;
 533  540          unsigned                exi_moved:1;
 534  541          int                     exi_id;
 535  542          avl_node_t              exi_id_link;
 536  543          /*
 537      -         * Soft-reference/backpointer to the zone.  The ZSD callbacks we have
 538      -         * invoke cleanup code that crosses into OTHER cleanup functions that
 539      -         * may assume same-zone context and attempt to find their own ZSD,
 540      -         * using "curzone" when in fact "curzone" is global when called from
 541      -         * NFS's ZSD cleanup (see lm_unexport->nlm_unexport for an example).
 542      -         *
 543      -         * During ZSD shutdown or destroy callbacks, the zone structure
 544      -         * does not have its mutex held, and it has just-enough references
 545      -         * to not free from underneath us.  This field is not a proper
 546      -         * referenced-held zone pointer, and only ZSD callbacks should use
 547      -         * it.
      544 +         * Soft-reference/backpointer to zone's nfs_export_t.
      545 +         * This allows us access to the zone's rootvp (stored in
      546 +         * exi_ne->exi_root->exi_vp) even if the current thread isn't in
      547 +         * same-zone context.
 548  548           */
 549      -        struct zone             *exi_zone;
      549 +        struct nfs_export       *exi_ne;
 550  550  #ifdef VOLATILE_FH_TEST
 551  551          uint32_t                exi_volatile_id;
 552  552          struct ex_vol_rename    *exi_vol_rename;
 553  553          kmutex_t                exi_vol_rename_lock;
 554  554  #endif /* VOLATILE_FH_TEST -- keep last! */
 555  555  };
 556      -#define exi_zoneid exi_zone->zone_id
 557  556  
 558  557  typedef struct exportinfo exportinfo_t;
 559  558  typedef struct exportdata exportdata_t;
 560  559  typedef struct secinfo secinfo_t;
 561  560  
 562  561  /*
 563  562   * exp_visible is a visible list per filesystem. It is for filesystems
 564  563   * that may need a limited view of its contents. A pseudo export and
 565  564   * a real export at the mount point (VROOT) which has a subtree shared
 566  565   * has a visible list.
 567  566   *
 568  567   * The exi_visible field is NULL for normal, non-pseudo filesystems
 569  568   * which do not have any subtree exported. If the field is non-null,
 570  569   * it points to a list of visible entries, identified by vis_fid and/or
 571  570   * vis_ino. The presence of a "visible" list means that if this export
 572  571   * can only have a limited view, it can only view the entries in the
 573  572   * exp_visible list. The directories in the fid list comprise paths that
 574  573   * lead to exported directories.
 575  574   *
 576  575   * The vis_count field records the number of paths in this filesystem
 577  576   * that use this directory. The vis_exported field is non-zero if the
 578  577   * entry is an exported directory (leaf node).
 579  578   *
 580  579   * exp_visible itself is not reference counted. Each exp_visible is
 581  580   * referenced twice:
 582  581   * 1) from treenode::tree_vis
 583  582   * 2) linked from exportinfo::exi_visible
 584  583   * The 'owner' of exp_visible is the exportinfo structure. exp_visible should
 585  584   * be always freed only from exportinfo_t, never from treenode::tree_vis.
 586  585   */
 587  586  
 588  587  struct exp_visible {
 589  588          vnode_t                 *vis_vp;
 590  589          fid_t                   vis_fid;
 591  590          u_longlong_t            vis_ino;
 592  591          int                     vis_count;
 593  592          int                     vis_exported;
 594  593          struct exp_visible      *vis_next;
 595  594          struct secinfo          *vis_secinfo;
 596  595          int                     vis_seccnt;
 597  596          timespec_t              vis_change;
 598  597  };
 599  598  typedef struct exp_visible exp_visible_t;
 600  599  
 601  600  #define PSEUDO(exi)     ((exi)->exi_export.ex_flags & EX_PSEUDO)
 602  601  #define EXP_LINKED(exi) ((exi)->fid_hash.bckt != NULL)
 603  602  
 604  603  #define EQFSID(fsidp1, fsidp2)  \
 605  604          (((fsidp1)->val[0] == (fsidp2)->val[0]) && \
 606  605              ((fsidp1)->val[1] == (fsidp2)->val[1]))
 607  606  
 608  607  #define EQFID(fidp1, fidp2)     \
 609  608          ((fidp1)->fid_len == (fidp2)->fid_len && \
 610  609              bcmp((char *)(fidp1)->fid_data, (char *)(fidp2)->fid_data, \
 611  610              (uint_t)(fidp1)->fid_len) == 0)
 612  611  
 613  612  #define exportmatch(exi, fsid, fid)     \
 614  613          (EQFSID(&(exi)->exi_fsid, (fsid)) && EQFID(&(exi)->exi_fid, (fid)))
 615  614  
 616  615  /*
 617  616   * Returns true iff exported filesystem is read-only to the given host.
 618  617   *
 619  618   * Note:  this macro should be as fast as possible since it's called
 620  619   * on each NFS modification request.
 621  620   */
 622  621  #define rdonly(ro, vp)  ((ro) || vn_is_readonly(vp))
 623  622  #define rdonly4(req, cs)  \
 624  623          (vn_is_readonly((cs)->vp) || \
 625  624              (nfsauth4_access((cs)->exi, (cs)->vp, (req), (cs)->basecr, NULL, \
 626  625              NULL, NULL, NULL) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
 627  626  
 628  627  extern int      nfsauth4_access(struct exportinfo *, vnode_t *,
 629  628      struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **);
 630  629  extern int      nfsauth4_secinfo_access(struct exportinfo *,
 631  630      struct svc_req *, int, int, cred_t *);
 632  631  extern int      nfsauth_cache_clnt_compar(const void *, const void *);
 633  632  extern int      nfs_fhbcmp(char *, char *, int);
 634  633  extern void     nfs_exportinit(void);
 635  634  extern void     nfs_exportfini(void);
 636  635  extern void     nfs_export_zone_init(nfs_globals_t *);
 637  636  extern void     nfs_export_zone_fini(nfs_globals_t *);
 638  637  extern void     nfs_export_zone_shutdown(nfs_globals_t *);
 639  638  extern int      nfs_export_get_rootfh(nfs_globals_t *);
 640  639  extern int      chk_clnt_sec(struct exportinfo *, struct svc_req *);
 641  640  extern int      makefh(fhandle_t *, struct vnode *, struct exportinfo *);
 642  641  extern int      makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
 643  642  extern int      makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
 644  643  extern int      makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
 645  644  extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
 646  645  extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
 647  646  extern struct   exportinfo *checkexport(fsid_t *, struct fid *);
 648  647  extern struct   exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *);
 649  648  extern void     exi_hold(struct exportinfo *);
 650  649  extern void     exi_rele(struct exportinfo *);
 651  650  extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
 652  651      int *, bool_t);
 653  652  extern int      nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
 654  653                          struct exportinfo **);
 655  654  extern vnode_t *untraverse(vnode_t *);
 656  655  extern int      vn_is_nfs_reparse(vnode_t *, cred_t *);
 657  656  extern int      client_is_downrev(struct svc_req *);
 658  657  extern char    *build_symlink(vnode_t *, cred_t *, size_t *);
 659  658  
 660  659  extern fhandle_t nullfh2;       /* for comparing V2 filehandles */
 661  660  
 662  661  typedef struct nfs_export {
 663  662          /* Root of nfs pseudo namespace */
 664  663          treenode_t *ns_root;
 665  664  
 666  665          nfs_globals_t           *ne_globals;    /* "up" pointer */
 667  666  
  
    | 
      ↓ open down ↓ | 
    101 lines elided | 
    
      ↑ open up ↑ | 
  
 668  667          struct exportinfo *exptable_path_hash[PKP_HASH_SIZE];
 669  668          struct exportinfo *exptable[EXPTABLESIZE];
 670  669  
 671  670          /*
 672  671           * Read/Write lock that protects the exportinfo list.  This lock
 673  672           * must be held when searching or modifiying the exportinfo list.
 674  673           */
 675  674          krwlock_t exported_lock;
 676  675  
 677  676          /* "public" and default (root) location for public filehandle */
 678      -        struct exportinfo *exi_public, *exi_root;
      677 +        struct exportinfo *exi_public;
      678 +        struct exportinfo *exi_root;
 679  679          /* For checking default public file handle */
 680  680          fid_t exi_rootfid;
 681  681          /* For comparing V2 filehandles */
 682  682          fhandle_t nullfh2;
 683  683  
 684  684          /* The change attribute value of the root of nfs pseudo namespace */
 685  685          timespec_t ns_root_change;
 686  686  } nfs_export_t;
 687  687  
 688  688  /*
 689  689   * Functions that handle the NFSv4 server namespace
 690  690   */
 691  691  extern exportinfo_t *vis2exi(treenode_t *);
 692  692  extern int      treeclimb_export(struct exportinfo *);
 693  693  extern void     treeclimb_unexport(nfs_export_t *, struct exportinfo *);
 694  694  extern int      nfs_visible(struct exportinfo *, vnode_t *, int *);
 695  695  extern int      nfs_visible_inode(struct exportinfo *, ino64_t,
 696  696                      struct exp_visible **);
 697  697  extern int      has_visible(struct exportinfo *, vnode_t *);
 698  698  extern void     free_visible(struct exp_visible *);
 699  699  extern int      nfs_exported(struct exportinfo *, vnode_t *);
 700  700  extern struct exportinfo *pseudo_exportfs(nfs_export_t *, vnode_t *, fid_t *,
 701  701                      struct exp_visible *, struct exportdata *);
 702  702  extern int      vop_fid_pseudo(vnode_t *, fid_t *);
 703  703  extern int      nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
 704  704  extern bool_t   nfs_visible_change(struct exportinfo *, vnode_t *,
 705  705                      timespec_t *);
 706  706  extern void     tree_update_change(nfs_export_t *, treenode_t *, timespec_t *);
 707  707  extern void     rfs4_clean_state_exi(nfs_export_t *, struct exportinfo *);
 708  708  
 709  709  /*
 710  710   * Functions that handle the NFSv4 server namespace security flavors
 711  711   * information.
 712  712   */
 713  713  extern void     srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
 714  714  extern void     srv_secinfo_list_free(struct secinfo *, int);
 715  715  
 716  716  extern nfs_export_t *nfs_get_export();
 717  717  extern void     export_link(nfs_export_t *, struct exportinfo *);
 718  718  extern void     export_unlink(nfs_export_t *, struct exportinfo *);
 719  719  
 720  720  /*
 721  721   * exi_id support
 722  722   */
 723  723  extern kmutex_t  nfs_exi_id_lock;
 724  724  extern avl_tree_t exi_id_tree;
 725  725  extern int exi_id_get_next(void);
 726  726  
 727  727  /*
 728  728   * Two macros for identifying public filehandles.
 729  729   * A v2 public filehandle is 32 zero bytes.
 730  730   * A v3 public filehandle is zero length.
 731  731   */
 732  732  #define PUBLIC_FH2(fh) \
 733  733          ((fh)->fh_fsid.val[1] == 0 && \
 734  734          bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
 735  735  
 736  736  #define PUBLIC_FH3(fh) \
 737  737          ((fh)->fh3_length == 0)
 738  738  
 739  739  extern int      makefh4(nfs_fh4 *, struct vnode *, struct exportinfo *);
 740  740  extern vnode_t *nfs4_fhtovp(nfs_fh4 *, struct exportinfo *, nfsstat4 *);
 741  741  
 742  742  #endif /* _KERNEL */
 743  743  
 744  744  #ifdef  __cplusplus
 745  745  }
 746  746  #endif
 747  747  
 748  748  #endif  /* _NFS_EXPORT_H */
  
    | 
      ↓ open down ↓ | 
    60 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX