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


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2016 Jason King.

  26  */
  27 
  28 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  29 /*        All Rights Reserved   */
  30 
  31 #ifndef _NFS_EXPORT_H
  32 #define _NFS_EXPORT_H
  33 
  34 #include <nfs/nfs_sec.h>
  35 #include <nfs/auth.h>
  36 #include <sys/vnode.h>
  37 #include <nfs/nfs4.h>
  38 #include <sys/kiconv.h>
  39 #include <sys/avl.h>

  40 




  41 #ifdef  __cplusplus
  42 extern "C" {
  43 #endif
  44 
  45 /*
  46  * nfs pseudo flavor number is owned by IANA. Need to make sure the
  47  * Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
  48  * new IANA defined pseudo flavor numbers. The chance for the overlap
  49  * is very small since the growth of new flavor numbers is expected
  50  * to be limited.
  51  */
  52 #define NFS_FLAVOR_NOMAP        999999  /* no nfs flavor mapping */
  53 
  54 /*
  55  * As duplicate flavors can be passed into exportfs in the arguments, we
  56  * allocate a cleaned up array with non duplicate flavors on the stack.
  57  * So we need to know how much to allocate.
  58  */
  59 #define MAX_FLAVORS             6       /* none, sys, dh, krb5, krb5i krb5p */
  60 


 450  * +===+  (VROOT)      +---+                    +---+
 451  *
 452  *
 453  * Bi-directional interconnect:
 454  * treenode_t::tree_exi ---------  exportinfo_t::exi_tree
 455  * One-way direction connection:
 456  * treenode_t::tree_vis .........> exp_visible_t
 457  */
 458 /* Access to treenode_t is under protection of exported_lock RW_LOCK */
 459 typedef struct treenode {
 460         /* support for generic n-ary trees */
 461         struct treenode *tree_parent;
 462         struct treenode *tree_child_first;
 463         struct treenode *tree_sibling; /* next sibling */
 464         /* private, nfs specific part */
 465         struct exportinfo  *tree_exi;
 466         struct exp_visible *tree_vis;
 467 } treenode_t;
 468 
 469 /*
 470  * TREE_ROOT checks if the node corresponds to a filesystem root







 471  * TREE_EXPORTED checks if the node is explicitly shared
 472  */
 473 
 474 #define TREE_ROOT(t) \
 475         ((t)->tree_exi && (t)->tree_exi->exi_vp->v_flag & VROOT)


 476 
 477 #define TREE_EXPORTED(t) \
 478         ((t)->tree_exi && !PSEUDO((t)->tree_exi))
 479 
 480 /* Root of nfs pseudo namespace */
 481 extern treenode_t *ns_root;
 482 
 483 #define EXPTABLESIZE   256
 484 
 485 struct exp_hash {
 486         struct exportinfo       *prev;  /* ptr to the previous exportinfo */
 487         struct exportinfo       *next;  /* ptr to the next exportinfo */
 488         struct exportinfo       **bckt; /* backpointer to the hash bucket */
 489 };
 490 
 491 /*
 492  * A node associated with an export entry on the
 493  * list of exported filesystems.
 494  *
 495  * exi_count+exi_lock protects an individual exportinfo from being freed
 496  * when in use.
 497  *
 498  * You must have the writer lock on exported_lock to add/delete an exportinfo
 499  * structure to/from the list.
 500  *
 501  * exi_volatile_dev maps to VSW_VOLATILEDEV.  It means that the
 502  * underlying fs devno can change on each mount.  When set, the server
 503  * should not use va_fsid for a GETATTR(FATTR4_FSID) reply.  It must
 504  * use exi_fsid because it is guaranteed to be persistent.  This isn't
 505  * in any way related to NFS4 volatile filehandles.
 506  *
 507  * The exi_cache_lock protects the exi_cache AVL trees.
 508  */
 509 struct exportinfo {
 510         struct exportdata       exi_export;
 511         fsid_t                  exi_fsid;
 512         struct fid              exi_fid;
 513         struct exp_hash         fid_hash;
 514         struct exp_hash         path_hash;
 515         struct treenode         *exi_tree;
 516         fhandle_t               exi_fh;
 517         krwlock_t               exi_cache_lock;
 518         kmutex_t                exi_lock;
 519         uint_t                  exi_count;

 520         vnode_t                 *exi_vp;
 521         vnode_t                 *exi_dvp;
 522         avl_tree_t              *exi_cache[AUTH_TABLESIZE];
 523         struct log_buffer       *exi_logbuffer;
 524         struct exp_visible      *exi_visible;
 525         struct charset_cache    *exi_charset;
 526         unsigned                exi_volatile_dev:1;
 527         unsigned                exi_moved:1;









 528 #ifdef VOLATILE_FH_TEST
 529         uint32_t                exi_volatile_id;
 530         struct ex_vol_rename    *exi_vol_rename;
 531         kmutex_t                exi_vol_rename_lock;
 532 #endif /* VOLATILE_FH_TEST */
 533 };
 534 
 535 typedef struct exportinfo exportinfo_t;
 536 typedef struct exportdata exportdata_t;
 537 typedef struct secinfo secinfo_t;
 538 
 539 /*
 540  * exp_visible is a visible list per filesystem. It is for filesystems
 541  * that may need a limited view of its contents. A pseudo export and
 542  * a real export at the mount point (VROOT) which has a subtree shared
 543  * has a visible list.
 544  *
 545  * The exi_visible field is NULL for normal, non-pseudo filesystems
 546  * which do not have any subtree exported. If the field is non-null,
 547  * it points to a list of visible entries, identified by vis_fid and/or
 548  * vis_ino. The presence of a "visible" list means that if this export
 549  * can only have a limited view, it can only view the entries in the
 550  * exp_visible list. The directories in the fid list comprise paths that
 551  * lead to exported directories.
 552  *


 591         (EQFSID(&(exi)->exi_fsid, (fsid)) && EQFID(&(exi)->exi_fid, (fid)))
 592 
 593 /*
 594  * Returns true iff exported filesystem is read-only to the given host.
 595  *
 596  * Note:  this macro should be as fast as possible since it's called
 597  * on each NFS modification request.
 598  */
 599 #define rdonly(ro, vp)  ((ro) || vn_is_readonly(vp))
 600 #define rdonly4(req, cs)  \
 601         (vn_is_readonly((cs)->vp) || \
 602             (nfsauth4_access((cs)->exi, (cs)->vp, (req), (cs)->basecr, NULL, \
 603             NULL, NULL, NULL) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
 604 
 605 extern int      nfsauth4_access(struct exportinfo *, vnode_t *,
 606     struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **);
 607 extern int      nfsauth4_secinfo_access(struct exportinfo *,
 608     struct svc_req *, int, int, cred_t *);
 609 extern int      nfsauth_cache_clnt_compar(const void *, const void *);
 610 extern int      nfs_fhbcmp(char *, char *, int);
 611 extern int      nfs_exportinit(void);
 612 extern void     nfs_exportfini(void);




 613 extern int      chk_clnt_sec(struct exportinfo *, struct svc_req *);
 614 extern int      makefh(fhandle_t *, struct vnode *, struct exportinfo *);
 615 extern int      makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
 616 extern int      makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
 617 extern int      makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
 618 extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
 619 extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
 620 extern struct   exportinfo *checkexport(fsid_t *, struct fid *);
 621 extern struct   exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *);
 622 extern void     exi_hold(struct exportinfo *);
 623 extern void     exi_rele(struct exportinfo *);
 624 extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
 625     int *, bool_t);
 626 extern int      nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
 627                         struct exportinfo **);
 628 extern void     export_link(struct exportinfo *);
 629 extern void     export_unlink(struct exportinfo *);
 630 extern vnode_t *untraverse(vnode_t *);
 631 extern int      vn_is_nfs_reparse(vnode_t *, cred_t *);
 632 extern int      client_is_downrev(struct svc_req *);
 633 extern char    *build_symlink(vnode_t *, cred_t *, size_t *);
 634 





























 635 /*
 636  * Functions that handle the NFSv4 server namespace
 637  */
 638 extern exportinfo_t *vis2exi(treenode_t *);
 639 extern int      treeclimb_export(struct exportinfo *);
 640 extern void     treeclimb_unexport(struct exportinfo *);
 641 extern int      nfs_visible(struct exportinfo *, vnode_t *, int *);
 642 extern int      nfs_visible_inode(struct exportinfo *, ino64_t,
 643     struct exp_visible **);
 644 extern int      has_visible(struct exportinfo *, vnode_t *);
 645 extern void     free_visible(struct exp_visible *);
 646 extern int      nfs_exported(struct exportinfo *, vnode_t *);
 647 extern struct exportinfo *pseudo_exportfs(vnode_t *, fid_t *,
 648     struct exp_visible *, struct exportdata *);
 649 extern int      vop_fid_pseudo(vnode_t *, fid_t *);
 650 extern int      nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
 651 extern bool_t   nfs_visible_change(struct exportinfo *, vnode_t *,
 652     timespec_t *);
 653 extern void     tree_update_change(treenode_t *, timespec_t *);


 654 /*
 655  * Functions that handle the NFSv4 server namespace security flavors
 656  * information.
 657  */
 658 extern void     srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
 659 extern void     srv_secinfo_list_free(struct secinfo *, int);
 660 




 661 /*
 662  * "public" and default (root) location for public filehandle
 663  */
 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[];
 668 
 669 /*
 670  * Two macros for identifying public filehandles.
 671  * A v2 public filehandle is 32 zero bytes.
 672  * A v3 public filehandle is zero length.
 673  */
 674 #define PUBLIC_FH2(fh) \
 675         ((fh)->fh_fsid.val[1] == 0 && \
 676         bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
 677 
 678 #define PUBLIC_FH3(fh) \
 679         ((fh)->fh3_length == 0)
 680 
 681 extern int      makefh4(nfs_fh4 *, struct vnode *, struct exportinfo *);
 682 extern vnode_t *nfs4_fhtovp(nfs_fh4 *, struct exportinfo *, nfsstat4 *);
 683 
 684 #endif /* _KERNEL */
 685 
 686 #ifdef  __cplusplus
 687 }


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
  25  * Copyright 2016 Jason King.
  26  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  27  */
  28 
  29 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  30 /*        All Rights Reserved   */
  31 
  32 #ifndef _NFS_EXPORT_H
  33 #define _NFS_EXPORT_H
  34 
  35 #include <nfs/nfs_sec.h>
  36 #include <nfs/auth.h>
  37 #include <sys/vnode.h>
  38 #include <nfs/nfs4.h>
  39 #include <sys/kiconv.h>
  40 #include <sys/avl.h>
  41 #include <sys/zone.h>
  42 
  43 #ifdef _KERNEL
  44 #include <sys/pkp_hash.h> /* for PKP_HASH_SIZE */
  45 #endif /* _KERNEL */
  46 
  47 #ifdef  __cplusplus
  48 extern "C" {
  49 #endif
  50 
  51 /*
  52  * nfs pseudo flavor number is owned by IANA. Need to make sure the
  53  * Solaris specific NFS_FLAVOR_NOMAP number will not overlap with any
  54  * new IANA defined pseudo flavor numbers. The chance for the overlap
  55  * is very small since the growth of new flavor numbers is expected
  56  * to be limited.
  57  */
  58 #define NFS_FLAVOR_NOMAP        999999  /* no nfs flavor mapping */
  59 
  60 /*
  61  * As duplicate flavors can be passed into exportfs in the arguments, we
  62  * allocate a cleaned up array with non duplicate flavors on the stack.
  63  * So we need to know how much to allocate.
  64  */
  65 #define MAX_FLAVORS             6       /* none, sys, dh, krb5, krb5i krb5p */
  66 


 456  * +===+  (VROOT)      +---+                    +---+
 457  *
 458  *
 459  * Bi-directional interconnect:
 460  * treenode_t::tree_exi ---------  exportinfo_t::exi_tree
 461  * One-way direction connection:
 462  * treenode_t::tree_vis .........> exp_visible_t
 463  */
 464 /* Access to treenode_t is under protection of exported_lock RW_LOCK */
 465 typedef struct treenode {
 466         /* support for generic n-ary trees */
 467         struct treenode *tree_parent;
 468         struct treenode *tree_child_first;
 469         struct treenode *tree_sibling; /* next sibling */
 470         /* private, nfs specific part */
 471         struct exportinfo  *tree_exi;
 472         struct exp_visible *tree_vis;
 473 } treenode_t;
 474 
 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 /*
 482  * TREE_ROOT checks if the node corresponds to a filesystem root or
 483  * the zone's root directory.
 484  * TREE_EXPORTED checks if the node is explicitly shared
 485  */
 486 
 487 #define TREE_ROOT(t) \
 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)))
 491 
 492 #define TREE_EXPORTED(t) \
 493         ((t)->tree_exi && !PSEUDO((t)->tree_exi))
 494 



 495 #define EXPTABLESIZE   256
 496 
 497 struct exp_hash {
 498         struct exportinfo       *prev;  /* ptr to the previous exportinfo */
 499         struct exportinfo       *next;  /* ptr to the next exportinfo */
 500         struct exportinfo       **bckt; /* backpointer to the hash bucket */
 501 };
 502 
 503 /*
 504  * A node associated with an export entry on the
 505  * list of exported filesystems.
 506  *
 507  * exi_count+exi_lock protects an individual exportinfo from being freed
 508  * when in use.
 509  *
 510  * You must have the writer lock on exported_lock to add/delete an exportinfo
 511  * structure to/from the list.
 512  *
 513  * exi_volatile_dev maps to VSW_VOLATILEDEV.  It means that the
 514  * underlying fs devno can change on each mount.  When set, the server
 515  * should not use va_fsid for a GETATTR(FATTR4_FSID) reply.  It must
 516  * use exi_fsid because it is guaranteed to be persistent.  This isn't
 517  * in any way related to NFS4 volatile filehandles.
 518  *
 519  * The exi_cache_lock protects the exi_cache AVL trees.
 520  */
 521 struct exportinfo {
 522         struct exportdata       exi_export;
 523         fsid_t                  exi_fsid;
 524         struct fid              exi_fid;
 525         struct exp_hash         fid_hash;
 526         struct exp_hash         path_hash;
 527         struct treenode         *exi_tree;
 528         fhandle_t               exi_fh;
 529         krwlock_t               exi_cache_lock;
 530         kmutex_t                exi_lock;
 531         uint_t                  exi_count;
 532         zoneid_t                exi_zoneid;
 533         vnode_t                 *exi_vp;
 534         vnode_t                 *exi_dvp;
 535         avl_tree_t              *exi_cache[AUTH_TABLESIZE];
 536         struct log_buffer       *exi_logbuffer;
 537         struct exp_visible      *exi_visible;
 538         struct charset_cache    *exi_charset;
 539         unsigned                exi_volatile_dev:1;
 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;
 550 #ifdef VOLATILE_FH_TEST
 551         uint32_t                exi_volatile_id;
 552         struct ex_vol_rename    *exi_vol_rename;
 553         kmutex_t                exi_vol_rename_lock;
 554 #endif /* VOLATILE_FH_TEST -- keep last! */
 555 };
 556 
 557 typedef struct exportinfo exportinfo_t;
 558 typedef struct exportdata exportdata_t;
 559 typedef struct secinfo secinfo_t;
 560 
 561 /*
 562  * exp_visible is a visible list per filesystem. It is for filesystems
 563  * that may need a limited view of its contents. A pseudo export and
 564  * a real export at the mount point (VROOT) which has a subtree shared
 565  * has a visible list.
 566  *
 567  * The exi_visible field is NULL for normal, non-pseudo filesystems
 568  * which do not have any subtree exported. If the field is non-null,
 569  * it points to a list of visible entries, identified by vis_fid and/or
 570  * vis_ino. The presence of a "visible" list means that if this export
 571  * can only have a limited view, it can only view the entries in the
 572  * exp_visible list. The directories in the fid list comprise paths that
 573  * lead to exported directories.
 574  *


 613         (EQFSID(&(exi)->exi_fsid, (fsid)) && EQFID(&(exi)->exi_fid, (fid)))
 614 
 615 /*
 616  * Returns true iff exported filesystem is read-only to the given host.
 617  *
 618  * Note:  this macro should be as fast as possible since it's called
 619  * on each NFS modification request.
 620  */
 621 #define rdonly(ro, vp)  ((ro) || vn_is_readonly(vp))
 622 #define rdonly4(req, cs)  \
 623         (vn_is_readonly((cs)->vp) || \
 624             (nfsauth4_access((cs)->exi, (cs)->vp, (req), (cs)->basecr, NULL, \
 625             NULL, NULL, NULL) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
 626 
 627 extern int      nfsauth4_access(struct exportinfo *, vnode_t *,
 628     struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **);
 629 extern int      nfsauth4_secinfo_access(struct exportinfo *,
 630     struct svc_req *, int, int, cred_t *);
 631 extern int      nfsauth_cache_clnt_compar(const void *, const void *);
 632 extern int      nfs_fhbcmp(char *, char *, int);
 633 extern void     nfs_exportinit(void);
 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 *);
 639 extern int      chk_clnt_sec(struct exportinfo *, struct svc_req *);
 640 extern int      makefh(fhandle_t *, struct vnode *, struct exportinfo *);
 641 extern int      makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
 642 extern int      makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
 643 extern int      makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
 644 extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
 645 extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
 646 extern struct   exportinfo *checkexport(fsid_t *, struct fid *);
 647 extern struct   exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *);
 648 extern void     exi_hold(struct exportinfo *);
 649 extern void     exi_rele(struct exportinfo *);
 650 extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
 651     int *, bool_t);
 652 extern int      nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
 653                         struct exportinfo **);
 654 extern vnode_t *untraverse(vnode_t *, vnode_t *);


 655 extern int      vn_is_nfs_reparse(vnode_t *, cred_t *);
 656 extern int      client_is_downrev(struct svc_req *);
 657 extern char    *build_symlink(vnode_t *, cred_t *, size_t *);
 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 
 688 /*
 689  * Functions that handle the NFSv4 server namespace
 690  */
 691 extern exportinfo_t *vis2exi(treenode_t *);
 692 extern int      treeclimb_export(struct exportinfo *);
 693 extern void     treeclimb_unexport(nfs_export_t *, struct exportinfo *);
 694 extern int      nfs_visible(struct exportinfo *, vnode_t *, int *);
 695 extern int      nfs_visible_inode(struct exportinfo *, ino64_t,
 696                     struct exp_visible **);
 697 extern int      has_visible(struct exportinfo *, vnode_t *);
 698 extern void     free_visible(struct exp_visible *);
 699 extern int      nfs_exported(struct exportinfo *, vnode_t *);
 700 extern struct exportinfo *pseudo_exportfs(nfs_export_t *, vnode_t *, fid_t *,
 701                     struct exp_visible *, struct exportdata *);
 702 extern int      vop_fid_pseudo(vnode_t *, fid_t *);
 703 extern int      nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
 704 extern bool_t   nfs_visible_change(struct exportinfo *, vnode_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 
 709 /*
 710  * Functions that handle the NFSv4 server namespace security flavors
 711  * information.
 712  */
 713 extern void     srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
 714 extern void     srv_secinfo_list_free(struct secinfo *, int);
 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 
 720 /*
 721  * exi_id support
 722  */
 723 extern kmutex_t  nfs_exi_id_lock;
 724 extern avl_tree_t exi_id_tree;
 725 extern int exi_id_get_next(void);

 726 
 727 /*
 728  * Two macros for identifying public filehandles.
 729  * A v2 public filehandle is 32 zero bytes.
 730  * A v3 public filehandle is zero length.
 731  */
 732 #define PUBLIC_FH2(fh) \
 733         ((fh)->fh_fsid.val[1] == 0 && \
 734         bcmp((fh), &nullfh2, sizeof (fhandle_t)) == 0)
 735 
 736 #define PUBLIC_FH3(fh) \
 737         ((fh)->fh3_length == 0)
 738 
 739 extern int      makefh4(nfs_fh4 *, struct vnode *, struct exportinfo *);
 740 extern vnode_t *nfs4_fhtovp(nfs_fh4 *, struct exportinfo *, nfsstat4 *);
 741 
 742 #endif /* _KERNEL */
 743 
 744 #ifdef  __cplusplus
 745 }