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.