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  * TREE_ROOT checks if the node corresponds to a filesystem root or
 477  * the zone's root directory.
 478  * TREE_EXPORTED checks if the node is explicitly shared
 479  */
 480 
 481 #define TREE_ROOT(t) \
 482         ((t)->tree_exi != NULL && \
 483         (((t)->tree_exi->exi_vp->v_flag & VROOT) || \
 484         VN_CMP((t)->tree_exi->exi_zone->zone_rootvp, (t)->tree_exi->exi_vp)))
 485 
 486 #define TREE_EXPORTED(t) \
 487         ((t)->tree_exi && !PSEUDO((t)->tree_exi))
 488 
 489 #define EXPTABLESIZE   256
 490 
 491 struct exp_hash {
 492         struct exportinfo       *prev;  /* ptr to the previous exportinfo */
 493         struct exportinfo       *next;  /* ptr to the next exportinfo */
 494         struct exportinfo       **bckt; /* backpointer to the hash bucket */
 495 };
 496 
 497 /*
 498  * A node associated with an export entry on the
 499  * list of exported filesystems.
 500  *
 501  * exi_count+exi_lock protects an individual exportinfo from being freed
 502  * when in use.
 503  *
 504  * You must have the writer lock on exported_lock to add/delete an exportinfo
 
 506  *
 507  * exi_volatile_dev maps to VSW_VOLATILEDEV.  It means that the
 508  * underlying fs devno can change on each mount.  When set, the server
 509  * should not use va_fsid for a GETATTR(FATTR4_FSID) reply.  It must
 510  * use exi_fsid because it is guaranteed to be persistent.  This isn't
 511  * in any way related to NFS4 volatile filehandles.
 512  *
 513  * The exi_cache_lock protects the exi_cache AVL trees.
 514  */
 515 struct exportinfo {
 516         struct exportdata       exi_export;
 517         fsid_t                  exi_fsid;
 518         struct fid              exi_fid;
 519         struct exp_hash         fid_hash;
 520         struct exp_hash         path_hash;
 521         struct treenode         *exi_tree;
 522         fhandle_t               exi_fh;
 523         krwlock_t               exi_cache_lock;
 524         kmutex_t                exi_lock;
 525         uint_t                  exi_count;
 526         vnode_t                 *exi_vp;
 527         vnode_t                 *exi_dvp;
 528         avl_tree_t              *exi_cache[AUTH_TABLESIZE];
 529         struct log_buffer       *exi_logbuffer;
 530         struct exp_visible      *exi_visible;
 531         struct charset_cache    *exi_charset;
 532         unsigned                exi_volatile_dev:1;
 533         unsigned                exi_moved:1;
 534         int                     exi_id;
 535         avl_node_t              exi_id_link;
 536         /*
 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.
 548          */
 549         struct zone             *exi_zone;
 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 #define exi_zoneid exi_zone->zone_id
 557 
 558 typedef struct exportinfo exportinfo_t;
 559 typedef struct exportdata exportdata_t;
 560 typedef struct secinfo secinfo_t;
 561 
 562 /*
 563  * exp_visible is a visible list per filesystem. It is for filesystems
 564  * that may need a limited view of its contents. A pseudo export and
 565  * a real export at the mount point (VROOT) which has a subtree shared
 566  * has a visible list.
 567  *
 568  * The exi_visible field is NULL for normal, non-pseudo filesystems
 569  * which do not have any subtree exported. If the field is non-null,
 570  * it points to a list of visible entries, identified by vis_fid and/or
 571  * vis_ino. The presence of a "visible" list means that if this export
 572  * can only have a limited view, it can only view the entries in the
 573  * exp_visible list. The directories in the fid list comprise paths that
 574  * lead to exported directories.
 575  *
 576  * The vis_count field records the number of paths in this filesystem
 
 658 extern char    *build_symlink(vnode_t *, cred_t *, size_t *);
 659 
 660 extern fhandle_t nullfh2;       /* for comparing V2 filehandles */
 661 
 662 typedef struct nfs_export {
 663         /* Root of nfs pseudo namespace */
 664         treenode_t *ns_root;
 665 
 666         nfs_globals_t           *ne_globals;    /* "up" pointer */
 667 
 668         struct exportinfo *exptable_path_hash[PKP_HASH_SIZE];
 669         struct exportinfo *exptable[EXPTABLESIZE];
 670 
 671         /*
 672          * Read/Write lock that protects the exportinfo list.  This lock
 673          * must be held when searching or modifiying the exportinfo list.
 674          */
 675         krwlock_t exported_lock;
 676 
 677         /* "public" and default (root) location for public filehandle */
 678         struct exportinfo *exi_public, *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 *);
 
 | 
 
 
 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
 
 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  *
 575  * The vis_count field records the number of paths in this filesystem
 
 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 *);
 
 |