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

*** 21,30 **** --- 21,31 ---- /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright 2016 Jason King. + * Copyright 2018 Nexenta Systems, Inc. All rights reserved. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */
*** 35,45 **** --- 36,51 ---- #include <nfs/auth.h> #include <sys/vnode.h> #include <nfs/nfs4.h> #include <sys/kiconv.h> #include <sys/avl.h> + #include <sys/zone.h> + #ifdef _KERNEL + #include <sys/pkp_hash.h> /* for PKP_HASH_SIZE */ + #endif /* _KERNEL */ + #ifdef __cplusplus extern "C" { #endif /*
*** 465,487 **** struct exportinfo *tree_exi; struct exp_visible *tree_vis; } treenode_t; /* ! * TREE_ROOT checks if the node corresponds to a filesystem root * TREE_EXPORTED checks if the node is explicitly shared */ #define TREE_ROOT(t) \ ! ((t)->tree_exi && (t)->tree_exi->exi_vp->v_flag & VROOT) #define TREE_EXPORTED(t) \ ((t)->tree_exi && !PSEUDO((t)->tree_exi)) - /* Root of nfs pseudo namespace */ - extern treenode_t *ns_root; - #define EXPTABLESIZE 256 struct exp_hash { struct exportinfo *prev; /* ptr to the previous exportinfo */ struct exportinfo *next; /* ptr to the next exportinfo */ --- 471,499 ---- struct exportinfo *tree_exi; struct exp_visible *tree_vis; } treenode_t; /* ! * Now that we have links to chase, we can get the zone rootvp just from ! * an export. No current-zone-context needed. ! */ ! #define EXI_TO_ZONEROOTVP(exi) ((exi)->exi_ne->exi_root->exi_vp) ! ! /* ! * TREE_ROOT checks if the node corresponds to a filesystem root or ! * the zone's root directory. * TREE_EXPORTED checks if the node is explicitly shared */ #define TREE_ROOT(t) \ ! ((t)->tree_exi != NULL && \ ! (((t)->tree_exi->exi_vp->v_flag & VROOT) || \ ! VN_CMP(EXI_TO_ZONEROOTVP((t)->tree_exi), (t)->tree_exi->exi_vp))) #define TREE_EXPORTED(t) \ ((t)->tree_exi && !PSEUDO((t)->tree_exi)) #define EXPTABLESIZE 256 struct exp_hash { struct exportinfo *prev; /* ptr to the previous exportinfo */ struct exportinfo *next; /* ptr to the next exportinfo */
*** 515,537 **** struct treenode *exi_tree; fhandle_t exi_fh; krwlock_t exi_cache_lock; kmutex_t exi_lock; uint_t exi_count; vnode_t *exi_vp; vnode_t *exi_dvp; avl_tree_t *exi_cache[AUTH_TABLESIZE]; struct log_buffer *exi_logbuffer; struct exp_visible *exi_visible; struct charset_cache *exi_charset; unsigned exi_volatile_dev:1; unsigned exi_moved:1; #ifdef VOLATILE_FH_TEST uint32_t exi_volatile_id; struct ex_vol_rename *exi_vol_rename; kmutex_t exi_vol_rename_lock; ! #endif /* VOLATILE_FH_TEST */ }; typedef struct exportinfo exportinfo_t; typedef struct exportdata exportdata_t; typedef struct secinfo secinfo_t; --- 527,559 ---- struct treenode *exi_tree; fhandle_t exi_fh; krwlock_t exi_cache_lock; kmutex_t exi_lock; uint_t exi_count; + zoneid_t exi_zoneid; vnode_t *exi_vp; vnode_t *exi_dvp; avl_tree_t *exi_cache[AUTH_TABLESIZE]; struct log_buffer *exi_logbuffer; struct exp_visible *exi_visible; struct charset_cache *exi_charset; unsigned exi_volatile_dev:1; unsigned exi_moved:1; + int exi_id; + avl_node_t exi_id_link; + /* + * Soft-reference/backpointer to zone's nfs_export_t. + * This allows us access to the zone's rootvp (stored in + * exi_ne->exi_root->exi_vp) even if the current thread isn't in + * same-zone context. + */ + struct nfs_export *exi_ne; #ifdef VOLATILE_FH_TEST uint32_t exi_volatile_id; struct ex_vol_rename *exi_vol_rename; kmutex_t exi_vol_rename_lock; ! #endif /* VOLATILE_FH_TEST -- keep last! */ }; typedef struct exportinfo exportinfo_t; typedef struct exportdata exportdata_t; typedef struct secinfo secinfo_t;
*** 606,617 **** struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **); extern int nfsauth4_secinfo_access(struct exportinfo *, struct svc_req *, int, int, cred_t *); extern int nfsauth_cache_clnt_compar(const void *, const void *); extern int nfs_fhbcmp(char *, char *, int); ! extern int nfs_exportinit(void); extern void nfs_exportfini(void); extern int chk_clnt_sec(struct exportinfo *, struct svc_req *); extern int makefh(fhandle_t *, struct vnode *, struct exportinfo *); extern int makefh_ol(fhandle_t *, struct exportinfo *, uint_t); extern int makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *); extern int makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t); --- 628,643 ---- struct svc_req *, cred_t *, uid_t *, gid_t *, uint_t *, gid_t **); extern int nfsauth4_secinfo_access(struct exportinfo *, struct svc_req *, int, int, cred_t *); extern int nfsauth_cache_clnt_compar(const void *, const void *); extern int nfs_fhbcmp(char *, char *, int); ! extern void nfs_exportinit(void); extern void nfs_exportfini(void); + extern void nfs_export_zone_init(nfs_globals_t *); + extern void nfs_export_zone_fini(nfs_globals_t *); + extern void nfs_export_zone_shutdown(nfs_globals_t *); + extern int nfs_export_get_rootfh(nfs_globals_t *); extern int chk_clnt_sec(struct exportinfo *, struct svc_req *); extern int makefh(fhandle_t *, struct vnode *, struct exportinfo *); extern int makefh_ol(fhandle_t *, struct exportinfo *, uint_t); extern int makefh3(nfs_fh3 *, struct vnode *, struct exportinfo *); extern int makefh3_ol(nfs_fh3 *, struct exportinfo *, uint_t);
*** 623,672 **** extern void exi_rele(struct exportinfo *); extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *, int *, bool_t); extern int nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *, struct exportinfo **); ! extern void export_link(struct exportinfo *); ! extern void export_unlink(struct exportinfo *); ! extern vnode_t *untraverse(vnode_t *); extern int vn_is_nfs_reparse(vnode_t *, cred_t *); extern int client_is_downrev(struct svc_req *); extern char *build_symlink(vnode_t *, cred_t *, size_t *); /* * Functions that handle the NFSv4 server namespace */ extern exportinfo_t *vis2exi(treenode_t *); extern int treeclimb_export(struct exportinfo *); ! extern void treeclimb_unexport(struct exportinfo *); extern int nfs_visible(struct exportinfo *, vnode_t *, int *); extern int nfs_visible_inode(struct exportinfo *, ino64_t, struct exp_visible **); extern int has_visible(struct exportinfo *, vnode_t *); extern void free_visible(struct exp_visible *); extern int nfs_exported(struct exportinfo *, vnode_t *); ! extern struct exportinfo *pseudo_exportfs(vnode_t *, fid_t *, struct exp_visible *, struct exportdata *); extern int vop_fid_pseudo(vnode_t *, fid_t *); extern int nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *); extern bool_t nfs_visible_change(struct exportinfo *, vnode_t *, timespec_t *); ! extern void tree_update_change(treenode_t *, timespec_t *); /* * Functions that handle the NFSv4 server namespace security flavors * information. */ extern void srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *); extern void srv_secinfo_list_free(struct secinfo *, int); /* ! * "public" and default (root) location for public filehandle */ ! extern struct exportinfo *exi_public, *exi_root; ! extern fhandle_t nullfh2; /* for comparing V2 filehandles */ ! extern krwlock_t exported_lock; ! extern struct exportinfo *exptable[]; /* * Two macros for identifying public filehandles. * A v2 public filehandle is 32 zero bytes. * A v3 public filehandle is zero length. --- 649,730 ---- extern void exi_rele(struct exportinfo *); extern struct exportinfo *nfs_vptoexi(vnode_t *, vnode_t *, cred_t *, int *, int *, bool_t); extern int nfs_check_vpexi(vnode_t *, vnode_t *, cred_t *, struct exportinfo **); ! extern vnode_t *untraverse(vnode_t *, vnode_t *); extern int vn_is_nfs_reparse(vnode_t *, cred_t *); extern int client_is_downrev(struct svc_req *); extern char *build_symlink(vnode_t *, cred_t *, size_t *); + extern fhandle_t nullfh2; /* for comparing V2 filehandles */ + + typedef struct nfs_export { + /* Root of nfs pseudo namespace */ + treenode_t *ns_root; + + nfs_globals_t *ne_globals; /* "up" pointer */ + + struct exportinfo *exptable_path_hash[PKP_HASH_SIZE]; + struct exportinfo *exptable[EXPTABLESIZE]; + + /* + * Read/Write lock that protects the exportinfo list. This lock + * must be held when searching or modifiying the exportinfo list. + */ + krwlock_t exported_lock; + + /* "public" and default (root) location for public filehandle */ + struct exportinfo *exi_public; + struct exportinfo *exi_root; + /* For checking default public file handle */ + fid_t exi_rootfid; + /* For comparing V2 filehandles */ + fhandle_t nullfh2; + + /* The change attribute value of the root of nfs pseudo namespace */ + timespec_t ns_root_change; + } nfs_export_t; + /* * Functions that handle the NFSv4 server namespace */ extern exportinfo_t *vis2exi(treenode_t *); extern int treeclimb_export(struct exportinfo *); ! extern void treeclimb_unexport(nfs_export_t *, struct exportinfo *); extern int nfs_visible(struct exportinfo *, vnode_t *, int *); extern int nfs_visible_inode(struct exportinfo *, ino64_t, struct exp_visible **); extern int has_visible(struct exportinfo *, vnode_t *); extern void free_visible(struct exp_visible *); extern int nfs_exported(struct exportinfo *, vnode_t *); ! extern struct exportinfo *pseudo_exportfs(nfs_export_t *, vnode_t *, fid_t *, struct exp_visible *, struct exportdata *); extern int vop_fid_pseudo(vnode_t *, fid_t *); extern int nfs4_vget_pseudo(struct exportinfo *, vnode_t **, fid_t *); extern bool_t nfs_visible_change(struct exportinfo *, vnode_t *, timespec_t *); ! extern void tree_update_change(nfs_export_t *, treenode_t *, timespec_t *); ! extern void rfs4_clean_state_exi(nfs_export_t *, struct exportinfo *); ! /* * Functions that handle the NFSv4 server namespace security flavors * information. */ extern void srv_secinfo_exp2pseu(struct exportdata *, struct exportdata *); extern void srv_secinfo_list_free(struct secinfo *, int); + extern nfs_export_t *nfs_get_export(); + extern void export_link(nfs_export_t *, struct exportinfo *); + extern void export_unlink(nfs_export_t *, struct exportinfo *); + /* ! * exi_id support */ ! extern kmutex_t nfs_exi_id_lock; ! extern avl_tree_t exi_id_tree; ! extern int exi_id_get_next(void); /* * Two macros for identifying public filehandles. * A v2 public filehandle is 32 zero bytes. * A v3 public filehandle is zero length.