Print this page
Fix NFS design problems re. multiple zone keys
Make NFS server zone-specific data all have the same lifetime
Fix rfs4_clean_state_exi
Fix exi_cache_reclaim
Fix mistakes in zone keys work
More fixes re. exi_zoneid and exi_tree
(danmcd -> Keep some ASSERT()s around for readability.)


 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 */
 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.


 616 /*
 617  * Returns true iff exported filesystem is read-only to the given host.
 618  *
 619  * Note:  this macro should be as fast as possible since it's called
 620  * on each NFS modification request.
 621  */
 622 #define rdonly(ro, vp)  ((ro) || vn_is_readonly(vp))
 623 #define rdonly4(req, cs)  \
 624         (vn_is_readonly((cs)->vp) || \
 625             (nfsauth4_access((cs)->exi, (cs)->vp, (req), (cs)->basecr, NULL, \
 626             NULL, NULL, NULL) & (NFSAUTH_RO | NFSAUTH_LIMITED)))
 627 
 628 extern int      nfsauth4_access(struct exportinfo *, vnode_t *,
 629     struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **);
 630 extern int      nfsauth4_secinfo_access(struct exportinfo *,
 631     struct svc_req *, int, int, cred_t *);
 632 extern int      nfsauth_cache_clnt_compar(const void *, const void *);
 633 extern int      nfs_fhbcmp(char *, char *, int);
 634 extern void     nfs_exportinit(void);
 635 extern void     nfs_exportfini(void);




 636 extern int      chk_clnt_sec(struct exportinfo *, struct svc_req *);
 637 extern int      makefh(fhandle_t *, struct vnode *, struct exportinfo *);
 638 extern int      makefh_ol(fhandle_t *, struct exportinfo *, uint_t);
 639 extern int      makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *);
 640 extern int      makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
 641 extern vnode_t *nfs_fhtovp(fhandle_t *, struct exportinfo *);
 642 extern vnode_t *nfs3_fhtovp(nfs_fh3 *, struct exportinfo *);
 643 extern struct   exportinfo *checkexport(fsid_t *, struct fid *);
 644 extern struct   exportinfo *checkexport4(fsid_t *, struct fid *, vnode_t *);
 645 extern void     exi_hold(struct exportinfo *);
 646 extern void     exi_rele(struct exportinfo *);
 647 extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *,
 648     int *, bool_t);
 649 extern int      nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *,
 650                         struct exportinfo **);
 651 extern vnode_t *untraverse(vnode_t *);
 652 extern int      vn_is_nfs_reparse(vnode_t *, cred_t *);
 653 extern int      client_is_downrev(struct svc_req *);
 654 extern char    *build_symlink(vnode_t *, cred_t *, size_t *);
 655 
 656 extern fhandle_t nullfh2;       /* for comparing V2 filehandles */
 657 
 658 typedef struct nfs_export {
 659         /* Root of nfs pseudo namespace */
 660         treenode_t *ns_root;
 661 


 662         struct exportinfo *exptable_path_hash[PKP_HASH_SIZE];
 663         struct exportinfo *exptable[EXPTABLESIZE];
 664 
 665         /*
 666          * Read/Write lock that protects the exportinfo list.  This lock
 667          * must be held when searching or modifiying the exportinfo list.
 668          */
 669         krwlock_t exported_lock;
 670 
 671         /* "public" and default (root) location for public filehandle */
 672         struct exportinfo *exi_public, *exi_root;
 673         /* For checking default public file handle */
 674         fid_t exi_rootfid;
 675         /* For comparing V2 filehandles */
 676         fhandle_t nullfh2;
 677 
 678         /* The change attribute value of the root of nfs pseudo namespace */
 679         timespec_t ns_root_change;
 680 } nfs_export_t;
 681 
 682 /*
 683  * Functions that handle the NFSv4 server namespace
 684  */
 685 extern exportinfo_t *vis2exi(treenode_t *);
 686 extern int      treeclimb_export(struct exportinfo *);
 687 extern void     treeclimb_unexport(nfs_export_t *, struct exportinfo *);
 688 extern int      nfs_visible(struct exportinfo *, vnode_t *, int *);
 689 extern int      nfs_visible_inode(struct exportinfo *, ino64_t,
 690                     struct exp_visible **);
 691 extern int      has_visible(struct exportinfo *, vnode_t *);
 692 extern void     free_visible(struct exp_visible *);
 693 extern int      nfs_exported(struct exportinfo *, vnode_t *);
 694 extern struct exportinfo *pseudo_exportfs(nfs_export_t *, vnode_t *, fid_t *,
 695                     struct exp_visible *, struct exportdata *);
 696 extern int      vop_fid_pseudo(vnode_t *, fid_t *);
 697 extern int      nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *);
 698 extern bool_t   nfs_visible_change(struct exportinfo *, vnode_t *,
 699                     timespec_t *);
 700 extern void     tree_update_change(nfs_export_t *, treenode_t *, timespec_t *);

 701 
 702 /*
 703  * Functions that handle the NFSv4 server namespace security flavors
 704  * information.
 705  */
 706 extern void     srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *);
 707 extern void     srv_secinfo_list_free(struct secinfo *, int);
 708 
 709 extern nfs_export_t *nfs_get_export();
 710 extern void     export_link(nfs_export_t *, struct exportinfo *);
 711 extern void     export_unlink(nfs_export_t *, struct exportinfo *);
 712 
 713 /*
 714  * exi_id support
 715  */
 716 extern kmutex_t  nfs_exi_id_lock;
 717 extern avl_tree_t exi_id_tree;
 718 extern int exi_id_get_next(void);
 719 
 720 /*




 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.


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