Print this page
11083 support NFS server in zone
Portions contributed by: Dan Kruchinin <dan.kruchinin@nexenta.com>
Portions contributed by: Stepan Zastupov <stepan.zastupov@gmail.com>
Portions contributed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Portions contributed by: Mike Zeller <mike@mikezeller.net>
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Portions contributed by: Gordon Ross <gordon.w.ross@gmail.com>
Portions contributed by: Vitaliy Gusev <gusev.vitaliy@gmail.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Jason King <jbk@joyent.com>
Reviewed by: C Fraire <cfraire@me.com>
Change-Id: I22f289d357503f9b48a0bc2482cc4328a6d43d16

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/nfs/export.h
          +++ new/usr/src/uts/common/nfs/export.h
↓ open down ↓ 15 lines elided ↑ open up ↑
  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 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  26   27   */
  27   28  
  28   29  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  29   30  /*        All Rights Reserved   */
  30   31  
  31   32  #ifndef _NFS_EXPORT_H
  32   33  #define _NFS_EXPORT_H
  33   34  
  34   35  #include <nfs/nfs_sec.h>
  35   36  #include <nfs/auth.h>
  36   37  #include <sys/vnode.h>
  37   38  #include <nfs/nfs4.h>
  38   39  #include <sys/kiconv.h>
  39   40  #include <sys/avl.h>
       41 +#include <sys/zone.h>
  40   42  
       43 +#ifdef _KERNEL
       44 +#include <sys/pkp_hash.h> /* for PKP_HASH_SIZE */
       45 +#endif /* _KERNEL */
       46 +
  41   47  #ifdef  __cplusplus
  42   48  extern "C" {
  43   49  #endif
  44   50  
  45   51  /*
  46   52   * nfs pseudo flavor number is owned by IANA. Need to make sure the
  47   53   * Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
  48   54   * new IANA defined pseudo flavor numbers. The chance for the overlap
  49   55   * is very small since the growth of new flavor numbers is expected
  50   56   * to be limited.
↓ open down ↓ 409 lines elided ↑ open up ↑
 460  466          /* support for generic n-ary trees */
 461  467          struct treenode *tree_parent;
 462  468          struct treenode *tree_child_first;
 463  469          struct treenode *tree_sibling; /* next sibling */
 464  470          /* private, nfs specific part */
 465  471          struct exportinfo  *tree_exi;
 466  472          struct exp_visible *tree_vis;
 467  473  } treenode_t;
 468  474  
 469  475  /*
 470      - * 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.
 471  484   * TREE_EXPORTED checks if the node is explicitly shared
 472  485   */
 473  486  
 474  487  #define TREE_ROOT(t) \
 475      -        ((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)))
 476  491  
 477  492  #define TREE_EXPORTED(t) \
 478  493          ((t)->tree_exi && !PSEUDO((t)->tree_exi))
 479  494  
 480      -/* Root of nfs pseudo namespace */
 481      -extern treenode_t *ns_root;
 482      -
 483  495  #define EXPTABLESIZE   256
 484  496  
 485  497  struct exp_hash {
 486  498          struct exportinfo       *prev;  /* ptr to the previous exportinfo */
 487  499          struct exportinfo       *next;  /* ptr to the next exportinfo */
 488  500          struct exportinfo       **bckt; /* backpointer to the hash bucket */
 489  501  };
 490  502  
 491  503  /*
 492  504   * A node associated with an export entry on the
↓ open down ↓ 17 lines elided ↑ open up ↑
 510  522          struct exportdata       exi_export;
 511  523          fsid_t                  exi_fsid;
 512  524          struct fid              exi_fid;
 513  525          struct exp_hash         fid_hash;
 514  526          struct exp_hash         path_hash;
 515  527          struct treenode         *exi_tree;
 516  528          fhandle_t               exi_fh;
 517  529          krwlock_t               exi_cache_lock;
 518  530          kmutex_t                exi_lock;
 519  531          uint_t                  exi_count;
      532 +        zoneid_t                exi_zoneid;
 520  533          vnode_t                 *exi_vp;
 521  534          vnode_t                 *exi_dvp;
 522  535          avl_tree_t              *exi_cache[AUTH_TABLESIZE];
 523  536          struct log_buffer       *exi_logbuffer;
 524  537          struct exp_visible      *exi_visible;
 525  538          struct charset_cache    *exi_charset;
 526  539          unsigned                exi_volatile_dev:1;
 527  540          unsigned                exi_moved:1;
      541 +        int                     exi_id;
      542 +        avl_node_t              exi_id_link;
      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;
 528  550  #ifdef VOLATILE_FH_TEST
 529  551          uint32_t                exi_volatile_id;
 530  552          struct ex_vol_rename    *exi_vol_rename;
 531  553          kmutex_t                exi_vol_rename_lock;
 532      -#endif /* VOLATILE_FH_TEST */
      554 +#endif /* VOLATILE_FH_TEST -- keep last! */
 533  555  };
 534  556  
 535  557  typedef struct exportinfo exportinfo_t;
 536  558  typedef struct exportdata exportdata_t;
 537  559  typedef struct secinfo secinfo_t;
 538  560  
 539  561  /*
 540  562   * exp_visible is a visible list per filesystem. It is for filesystems
 541  563   * that may need a limited view of its contents. A pseudo export and
 542  564   * a real export at the mount point (VROOT) which has a subtree shared
↓ open down ↓ 58 lines elided ↑ open up ↑
 601  623          (vn_is_readonly((cs)->vp) || \
 602  624              (nfsauth4_access((cs)->exi, (cs)->vp, (req), (cs)->basecr, NULL, \
 603  625              NULL, NULL, NULL) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
 604  626  
 605  627  extern int      nfsauth4_access(struct exportinfo *, vnode_t *,
 606  628      struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **);
 607  629  extern int      nfsauth4_secinfo_access(struct exportinfo *,
 608  630      struct svc_req *, int, int, cred_t *);
 609  631  extern int      nfsauth_cache_clnt_compar(const void *, const void *);
 610  632  extern int      nfs_fhbcmp(char *, char *, int);
 611      -extern int      nfs_exportinit(void);
      633 +extern void     nfs_exportinit(void);
 612  634  extern void     nfs_exportfini(void);
      635 +extern void     nfs_export_zone_init(nfs_globals_t *);
      636 +extern void     nfs_export_zone_fini(nfs_globals_t *);
      637 +extern void     nfs_export_zone_shutdown(nfs_globals_t *);
      638 +extern int      nfs_export_get_rootfh(nfs_globals_t *);
 613  639  extern int      chk_clnt_sec(struct exportinfo *, struct svc_req *);
 614  640  extern int      makefh(fhandle_t *, struct vnode *, struct exportinfo *);
 615  641  extern int      makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
 616  642  extern int      makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
 617  643  extern int      makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
 618  644  extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
 619  645  extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
 620  646  extern struct   exportinfo *checkexport(fsid_t *, struct fid *);
 621  647  extern struct   exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *);
 622  648  extern void     exi_hold(struct exportinfo *);
 623  649  extern void     exi_rele(struct exportinfo *);
 624  650  extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
 625  651      int *, bool_t);
 626  652  extern int      nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
 627  653                          struct exportinfo **);
 628      -extern void     export_link(struct exportinfo *);
 629      -extern void     export_unlink(struct exportinfo *);
 630      -extern vnode_t *untraverse(vnode_t *);
      654 +extern vnode_t *untraverse(vnode_t *, vnode_t *);
 631  655  extern int      vn_is_nfs_reparse(vnode_t *, cred_t *);
 632  656  extern int      client_is_downrev(struct svc_req *);
 633  657  extern char    *build_symlink(vnode_t *, cred_t *, size_t *);
 634  658  
      659 +extern fhandle_t nullfh2;       /* for comparing V2 filehandles */
      660 +
      661 +typedef struct nfs_export {
      662 +        /* Root of nfs pseudo namespace */
      663 +        treenode_t *ns_root;
      664 +
      665 +        nfs_globals_t           *ne_globals;    /* "up" pointer */
      666 +
      667 +        struct exportinfo *exptable_path_hash[PKP_HASH_SIZE];
      668 +        struct exportinfo *exptable[EXPTABLESIZE];
      669 +
      670 +        /*
      671 +         * Read/Write lock that protects the exportinfo list.  This lock
      672 +         * must be held when searching or modifiying the exportinfo list.
      673 +         */
      674 +        krwlock_t exported_lock;
      675 +
      676 +        /* "public" and default (root) location for public filehandle */
      677 +        struct exportinfo *exi_public;
      678 +        struct exportinfo *exi_root;
      679 +        /* For checking default public file handle */
      680 +        fid_t exi_rootfid;
      681 +        /* For comparing V2 filehandles */
      682 +        fhandle_t nullfh2;
      683 +
      684 +        /* The change attribute value of the root of nfs pseudo namespace */
      685 +        timespec_t ns_root_change;
      686 +} nfs_export_t;
      687 +
 635  688  /*
 636  689   * Functions that handle the NFSv4 server namespace
 637  690   */
 638  691  extern exportinfo_t *vis2exi(treenode_t *);
 639  692  extern int      treeclimb_export(struct exportinfo *);
 640      -extern void     treeclimb_unexport(struct exportinfo *);
      693 +extern void     treeclimb_unexport(nfs_export_t *, struct exportinfo *);
 641  694  extern int      nfs_visible(struct exportinfo *, vnode_t *, int *);
 642  695  extern int      nfs_visible_inode(struct exportinfo *, ino64_t,
 643      -    struct exp_visible **);
      696 +                    struct exp_visible **);
 644  697  extern int      has_visible(struct exportinfo *, vnode_t *);
 645  698  extern void     free_visible(struct exp_visible *);
 646  699  extern int      nfs_exported(struct exportinfo *, vnode_t *);
 647      -extern struct exportinfo *pseudo_exportfs(vnode_t *, fid_t *,
 648      -    struct exp_visible *, struct exportdata *);
      700 +extern struct exportinfo *pseudo_exportfs(nfs_export_t *, vnode_t *, fid_t *,
      701 +                    struct exp_visible *, struct exportdata *);
 649  702  extern int      vop_fid_pseudo(vnode_t *, fid_t *);
 650  703  extern int      nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
 651  704  extern bool_t   nfs_visible_change(struct exportinfo *, vnode_t *,
 652      -    timespec_t *);
 653      -extern void     tree_update_change(treenode_t *, timespec_t *);
      705 +                    timespec_t *);
      706 +extern void     tree_update_change(nfs_export_t *, treenode_t *, timespec_t *);
      707 +extern void     rfs4_clean_state_exi(nfs_export_t *, struct exportinfo *);
      708 +
 654  709  /*
 655  710   * Functions that handle the NFSv4 server namespace security flavors
 656  711   * information.
 657  712   */
 658  713  extern void     srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
 659  714  extern void     srv_secinfo_list_free(struct secinfo *, int);
 660  715  
      716 +extern nfs_export_t *nfs_get_export();
      717 +extern void     export_link(nfs_export_t *, struct exportinfo *);
      718 +extern void     export_unlink(nfs_export_t *, struct exportinfo *);
      719 +
 661  720  /*
 662      - * "public" and default (root) location for public filehandle
      721 + * exi_id support
 663  722   */
 664      -extern struct exportinfo *exi_public, *exi_root;
 665      -extern fhandle_t nullfh2;       /* for comparing V2 filehandles */
 666      -extern krwlock_t exported_lock;
 667      -extern struct exportinfo *exptable[];
      723 +extern kmutex_t  nfs_exi_id_lock;
      724 +extern avl_tree_t exi_id_tree;
      725 +extern int exi_id_get_next(void);
 668  726  
 669  727  /*
 670  728   * Two macros for identifying public filehandles.
 671  729   * A v2 public filehandle is 32 zero bytes.
 672  730   * A v3 public filehandle is zero length.
 673  731   */
 674  732  #define PUBLIC_FH2(fh) \
 675  733          ((fh)->fh_fsid.val[1] == 0 && \
 676  734          bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
 677  735  
↓ open down ↓ 13 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX