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