#ifndef _NFS4_H
#define _NFS4_H
#include <sys/types.h>
#include <sys/vnode.h>
#include <sys/fem.h>
#include <rpc/rpc.h>
#include <nfs/nfs.h>
#ifdef _KERNEL
#include <nfs/nfs4_kprot.h>
#include <sys/nvpair.h>
#else
#include <rpcsvc/nfs4_prot.h>
#endif
#include <nfs/nfs4_attr.h>
#include <sys/acl.h>
#include <sys/list.h>
#include <nfs/nfs4x.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NFS4_MAX_SECOID4 65536
#define NFS4_MAX_UTF8STRING 65536
#define NFS4_MAX_LINKTEXT4 65536
#define NFS4_MAX_PATHNAME4 65536
struct nfs_fsl_info {
uint_t netbuf_len;
uint_t netnm_len;
uint_t knconf_len;
char *netname;
struct netbuf *addr;
struct knetconfig *knconf;
};
#ifdef _KERNEL
typedef struct nfs4_fhandle {
int fh_len;
char fh_buf[NFS4_FHSIZE];
} nfs4_fhandle_t;
typedef uint8_t nfs4_minor_t;
#define NFS4_MINORVERSION 0
#define CB4_MINORVERSION 0
#define FIRST_NFS4_OP OP_ACCESS
#define LAST_NFS40_OP OP_RELEASE_LOCKOWNER
#define LAST_NFS41_OP OP_RECLAIM_COMPLETE
#define LAST_NFS42_OP OP_CLONE
#define LAST_NFS4_OP LAST_NFS42_OP
#define NFS4_SET_FATTR4_CHANGE(change, ts) \
{ \
change = (ts).tv_sec; \
change <<= 32; \
change |= (uint32_t)((ts).tv_nsec); \
}
extern time_t rfs4_lease_time;
typedef struct rfs4_dbe rfs4_dbe_t;
typedef struct rfs4_table rfs4_table_t;
typedef struct rfs4_index rfs4_index_t;
typedef struct rfs4_database rfs4_database_t;
typedef struct {
rfs4_dbe_t *dbe;
} *rfs4_entry_t;
extern kmem_cache_t *rfs4_client_mem_cache;
extern kmem_cache_t *rfs4_clntIP_mem_cache;
extern kmem_cache_t *rfs4_openown_mem_cache;
extern kmem_cache_t *rfs4_openstID_mem_cache;
extern kmem_cache_t *rfs4_lockstID_mem_cache;
extern kmem_cache_t *rfs4_lockown_mem_cache;
extern kmem_cache_t *rfs4_file_mem_cache;
extern kmem_cache_t *rfs4_delegstID_mem_cache;
extern kmem_cache_t *rfs4_session_mem_cache;
extern rfs4_database_t *rfs4_database_create(uint32_t);
extern void rfs4_database_shutdown(rfs4_database_t *);
extern void rfs4_database_destroy(rfs4_database_t *);
extern void rfs4_database_destroy(rfs4_database_t *);
extern kmem_cache_t *nfs4_init_mem_cache(char *, uint32_t, uint32_t,
uint32_t);
extern rfs4_table_t *rfs4_table_create(rfs4_database_t *, char *,
time_t, uint32_t,
bool_t (*create)(rfs4_entry_t, void *),
void (*destroy)(rfs4_entry_t),
bool_t (*expiry)(rfs4_entry_t),
uint32_t, uint32_t, uint32_t, id_t);
extern void rfs4_table_destroy(rfs4_database_t *, rfs4_table_t *);
extern rfs4_index_t *rfs4_index_create(rfs4_table_t *, char *,
uint32_t (*hash)(void *),
bool_t (compare)(rfs4_entry_t, void *),
void *(*mkkey)(rfs4_entry_t), bool_t);
extern void rfs4_index_destroy(rfs4_index_t *);
typedef enum {RFS4_DBS_VALID, RFS4_DBS_INVALID} rfs4_dbsearch_type_t;
extern rfs4_entry_t rfs4_dbsearch(rfs4_index_t *, void *,
bool_t *, void *, rfs4_dbsearch_type_t);
extern void rfs4_dbe_lock(rfs4_dbe_t *);
extern void rfs4_dbe_unlock(rfs4_dbe_t *);
extern clock_t rfs4_dbe_twait(rfs4_dbe_t *, clock_t);
extern void rfs4_dbe_cv_broadcast(rfs4_dbe_t *);
extern void rfs4_dbe_hold(rfs4_dbe_t *);
extern void rfs4_dbe_hold_nolock(rfs4_dbe_t *);
extern void rfs4_dbe_rele_nolock(rfs4_dbe_t *);
extern void rfs4_dbe_rele(rfs4_dbe_t *);
extern uint32_t rfs4_dbe_refcnt(rfs4_dbe_t *);
extern id_t rfs4_dbe_getid(rfs4_dbe_t *);
extern void rfs4_dbe_invalidate(rfs4_dbe_t *);
extern bool_t rfs4_dbe_is_invalid(rfs4_dbe_t *);
extern time_t rfs4_dbe_get_timerele(rfs4_dbe_t *);
extern void rfs4_dbe_hide(rfs4_dbe_t *);
extern void rfs4_dbe_unhide(rfs4_dbe_t *);
#ifdef DEBUG
extern bool_t rfs4_dbe_islocked(rfs4_dbe_t *);
#endif
extern void rfs4_dbe_walk(rfs4_table_t *,
void (*callout)(rfs4_entry_t, void *), void *);
extern void rfs4_dbsearch_cb(rfs4_index_t *idx, void *key,
int maxcount, void (*callout)(rfs4_entry_t));
#define RFS4_SS_DIRSIZE 64 * 1024
#define NFS4_SS_VERSION 1
typedef struct ss_pn {
char *leaf;
char pn[MAXPATHLEN];
} rfs4_ss_pn_t;
typedef struct rfs4_oldstate {
struct rfs4_oldstate *next;
struct rfs4_oldstate *prev;
rfs4_ss_pn_t *ss_pn;
nfs_client_id4 cl_id4;
} rfs4_oldstate_t;
typedef union {
stateid4 stateid;
struct {
uint32_t chgseq;
uint32_t boottime;
uint32_t type:2;
uint32_t clnodeid:8;
uint32_t ident:22;
pid_t pid;
} bits;
} stateid_t;
typedef enum {OPENID, LOCKID, DELEGID} stateid_type_t;
typedef struct rfs4_state_wait {
uint32_t sw_active;
uint32_t sw_wait_count;
kmutex_t sw_cv_lock[1];
kcondvar_t sw_cv[1];
} rfs4_state_wait_t;
extern void rfs4_sw_enter(rfs4_state_wait_t *);
extern void rfs4_sw_exit(rfs4_state_wait_t *);
typedef enum {
CB_NOCHANGE = 0,
CB_UNINIT = 1,
CB_NONE = 2,
CB_OK = 3,
CB_INPROG = 4,
CB_FAILED = 5,
CB_BAD = 6
} rfs4_cbstate_t;
#define RFS4_CBCH_MAX 10
typedef struct {
rfs4_cbstate_t cb_state;
unsigned cb_notified_of_cb_path_down:1;
time_t cb_timefailed;
int cb_chc_free;
CLIENT *cb_chc[RFS4_CBCH_MAX];
uint32_t cb_ident;
cb_client4 cb_callback;
uint32_t cb_refcnt;
uint32_t cb_badbehavior;
kmutex_t cb_lock[1];
kcondvar_t cb_cv[1];
bool_t cb_nullcaller;
kcondvar_t cb_cv_nullcaller[1];
struct {
bool_t cb_new;
bool_t cb_confirmed;
uint32_t cb_ident;
cb_client4 cb_callback;
} cb_newer;
} rfs4_cbinfo_t;
typedef struct rfs4_servinst {
int dss_npaths;
krwlock_t rwlock;
krwlock_t oldstate_lock;
time_t start_time;
time_t grace_period;
uint_t nreclaim;
rfs4_oldstate_t *oldstate;
struct rfs4_dss_path **dss_paths;
struct rfs4_servinst *next;
struct rfs4_servinst *prev;
} rfs4_servinst_t;
typedef struct rfs4_dss_path {
struct rfs4_dss_path *next;
struct rfs4_dss_path *prev;
char *path;
struct rfs4_servinst *sip;
unsigned index;
} rfs4_dss_path_t;
extern char **rfs4_dss_newpaths;
extern uint_t rfs4_dss_numnewpaths;
extern nvlist_t *rfs4_dss_paths, *rfs4_dss_oldpaths;
typedef struct rfs4_client {
rfs4_dbe_t *rc_dbe;
clientid4 rc_clientid;
nfs_client_id4 rc_nfs_client;
verifier4 rc_confirm_verf;
unsigned rc_need_confirm:1;
unsigned rc_unlksys_completed:1;
unsigned rc_can_reclaim:1;
unsigned rc_ss_remove:1;
unsigned rc_forced_expire:1;
unsigned rc_reclaim_completed:1;
uint_t rc_deleg_revoked;
struct rfs4_client *rc_cp_confirmed;
time_t rc_last_access;
rfs4_cbinfo_t rc_cbinfo;
cred_set_t rc_cr_set;
sysid_t rc_sysidt;
list_t rc_openownerlist;
rfs4_ss_pn_t *rc_ss_pn;
struct sockaddr_storage rc_addr;
rfs4_servinst_t *rc_server_instance;
rfs41_csr_t rc_contrived;
rfs41_sprot_t rc_state_prot;
list_t rc_sessions;
unsigned rc_destroying:1;
} rfs4_client_t;
typedef struct rfs4_clntip {
rfs4_dbe_t *ri_dbe;
struct sockaddr_storage ri_addr;
unsigned ri_no_referrals:1;
} rfs4_clntip_t;
typedef struct rfs4_openowner {
rfs4_dbe_t *ro_dbe;
rfs4_client_t *ro_client;
open_owner4 ro_owner;
unsigned ro_need_confirm:1;
unsigned ro_postpone_confirm:1;
seqid4 ro_open_seqid;
rfs4_state_wait_t ro_sw;
list_t ro_statelist;
list_node_t ro_node;
nfs_fh4 ro_reply_fh;
nfs_resop4 ro_reply;
} rfs4_openowner_t;
typedef struct rfs4_state {
rfs4_dbe_t *rs_dbe;
stateid_t rs_stateid;
rfs4_openowner_t *rs_owner;
struct rfs4_file *rs_finfo;
uint32_t rs_open_access;
uint32_t rs_open_deny;
uint32_t rs_share_access;
uint32_t rs_share_deny;
unsigned rs_closed:1;
list_t rs_lostatelist;
list_node_t rs_node;
} rfs4_state_t;
typedef struct rfs4_lockowner {
rfs4_dbe_t *rl_dbe;
rfs4_client_t *rl_client;
lock_owner4 rl_owner;
pid_t rl_pid;
} rfs4_lockowner_t;
typedef struct rfs4_lo_state {
rfs4_dbe_t *rls_dbe;
rfs4_state_t *rls_state;
stateid_t rls_lockid;
rfs4_lockowner_t *rls_locker;
seqid4 rls_seqid;
unsigned rls_skip_seqid_check:1;
unsigned rls_locks_cleaned:1;
unsigned rls_lock_completed:1;
rfs4_state_wait_t rls_sw;
list_node_t rls_node;
nfs_resop4 rls_reply;
} rfs4_lo_state_t;
typedef struct rfs4_deleg_state {
rfs4_dbe_t *rds_dbe;
open_delegation_type4 rds_dtype;
stateid_t rds_delegid;
time_t rds_time_granted;
time_t rds_time_recalled;
time_t rds_time_revoked;
struct rfs4_file *rds_finfo;
rfs4_client_t *rds_client;
list_node_t rds_node;
} rfs4_deleg_state_t;
typedef struct rfs4_dinfo {
open_delegation_type4 rd_dtype;
time_t rd_time_returned;
time_t rd_time_recalled;
time_t rd_time_lastgrant;
time_t rd_time_lastwrite;
time_t rd_time_rm_delayed;
uint32_t rd_rdgrants;
uint32_t rd_wrgrants;
int32_t rd_recall_count;
kmutex_t rd_recall_lock[1];
kcondvar_t rd_recall_cv[1];
bool_t rd_ever_recalled;
uint32_t rd_hold_grant;
clientid4 rd_conflicted_client;
} rfs4_dinfo_t;
typedef struct rfs4_file {
rfs4_dbe_t *rf_dbe;
vnode_t *rf_vp;
nfs_fh4 rf_filehandle;
list_t rf_delegstatelist;
rfs4_dinfo_t rf_dinfo;
uint32_t rf_share_deny;
uint32_t rf_share_access;
uint32_t rf_access_read;
uint32_t rf_access_write;
uint32_t rf_deny_read;
uint32_t rf_deny_write;
krwlock_t rf_file_rwlock;
} rfs4_file_t;
typedef enum {
SRV_NEVER_DELEGATE = 0,
SRV_NORMAL_DELEGATE = 1
} srv_deleg_policy_t;
extern void rfs4_disable_delegation(void), rfs4_enable_delegation(void);
typedef enum {
DELEG_NONE = 0,
DELEG_READ = 1,
DELEG_WRITE = 2,
DELEG_ANY = -1
} delegreq_t;
#define NFS4_DELEG4TYPE2REQTYPE(x) (delegreq_t)(x)
typedef struct nfs4_srv {
verifier4 write4verf;
kmutex_t deleg_lock;
kmutex_t state_lock;
rfs4_database_t *nfs4_server_state;
kmutex_t servinst_lock;
rfs4_servinst_t *nfs4_cur_servinst;
krwlock_t deleg_policy_lock;
srv_deleg_policy_t nfs4_deleg_policy;
nfs4_minor_t nfs4_minor_max;
int seen_first_compound;
rfs4_dss_path_t *dss_pathlist;
struct rfs4_drc *nfs4_drc;
time_t rfs4_start_time;
krwlock_t rfs4_findclient_lock;
time_t rfs4_client_cache_time;
time_t rfs4_openowner_cache_time;
time_t rfs4_state_cache_time;
time_t rfs4_lo_state_cache_time;
time_t rfs4_lockowner_cache_time;
time_t rfs4_file_cache_time;
time_t rfs4_deleg_state_cache_time;
time_t rfs4_clntip_cache_time;
rfs4_table_t *rfs4_client_tab;
rfs4_index_t *rfs4_clientid_idx;
rfs4_index_t *rfs4_nfsclnt_idx;
rfs4_table_t *rfs4_clntip_tab;
rfs4_index_t *rfs4_clntip_idx;
rfs4_table_t *rfs4_openowner_tab;
rfs4_index_t *rfs4_openowner_idx;
rfs4_table_t *rfs4_state_tab;
rfs4_index_t *rfs4_state_idx;
rfs4_index_t *rfs4_state_owner_file_idx;
rfs4_index_t *rfs4_state_file_idx;
rfs4_table_t *rfs4_lo_state_tab;
rfs4_index_t *rfs4_lo_state_idx;
rfs4_index_t *rfs4_lo_state_owner_idx;
rfs4_table_t *rfs4_lockowner_tab;
rfs4_index_t *rfs4_lockowner_idx;
rfs4_index_t *rfs4_lockowner_pid_idx;
rfs4_table_t *rfs4_file_tab;
rfs4_index_t *rfs4_file_idx;
rfs4_table_t *rfs4_deleg_state_tab;
rfs4_index_t *rfs4_deleg_idx;
rfs4_index_t *rfs4_deleg_state_idx;
rfs4_table_t *rfs4_session_tab;
rfs4_index_t *rfs4_session_idx;
int rfs4_ss_enabled;
} nfs4_srv_t;
#define RFS4_MAX_MEM_CACHE_NAME 48
typedef struct rfs4_db_mem_cache {
char r_db_name[RFS4_MAX_MEM_CACHE_NAME];
kmem_cache_t *r_db_mem_cache;
} rfs4_db_mem_cache_t;
#define RFS4_DB_MEM_CACHE_NUM 9
extern rfs4_db_mem_cache_t rfs4_db_mem_cache_table[RFS4_DB_MEM_CACHE_NUM];
extern srv_deleg_policy_t nfs4_get_deleg_policy();
extern void rfs4_servinst_create(nfs4_srv_t *, int, int, char **);
extern void rfs4_servinst_destroy_all(nfs4_srv_t *);
extern void rfs4_servinst_assign(nfs4_srv_t *, rfs4_client_t *,
rfs4_servinst_t *);
extern rfs4_servinst_t *rfs4_servinst(rfs4_client_t *);
extern int rfs4_clnt_in_grace(rfs4_client_t *);
extern int rfs4_servinst_in_grace(rfs4_servinst_t *);
extern int rfs4_servinst_grace_new(rfs4_servinst_t *);
extern void rfs4_grace_start(rfs4_servinst_t *);
extern void rfs4_grace_start_new(nfs4_srv_t *);
extern void rfs4_grace_reset_all(nfs4_srv_t *);
extern void rfs4_dss_readstate(nfs4_srv_t *, int, char **);
extern void rfs4_free_reply(nfs_resop4 *);
extern void rfs4_copy_reply(nfs_resop4 *, nfs_resop4 *);
extern rfs4_client_t *rfs4_findclient(nfs_client_id4 *,
bool_t *, rfs4_client_t *);
extern rfs4_client_t *rfs4_findclient_by_id(clientid4, bool_t);
extern rfs4_client_t *rfs4_findclient_by_addr(struct sockaddr *);
extern void rfs4_client_rele(rfs4_client_t *);
extern void rfs4_client_close(rfs4_client_t *);
extern void rfs4_client_state_remove(rfs4_client_t *);
extern void rfs4_client_scv_next(rfs4_client_t *);
extern void rfs4_update_lease(rfs4_client_t *);
extern bool_t rfs4_lease_expired(rfs4_client_t *);
extern nfsstat4 rfs4_check_clientid(clientid4 *, int);
extern rfs4_clntip_t *rfs4_find_clntip(struct sockaddr *, bool_t *);
extern void rfs4_invalidate_clntip(struct sockaddr *);
extern rfs4_openowner_t *rfs4_findopenowner(open_owner4 *, bool_t *, seqid4);
extern void rfs4_update_open_sequence(rfs4_openowner_t *);
extern void rfs4_update_open_resp(rfs4_openowner_t *,
nfs_resop4 *, nfs_fh4 *);
extern void rfs4_openowner_rele(rfs4_openowner_t *);
extern void rfs4_free_opens(rfs4_openowner_t *, bool_t, bool_t);
extern rfs4_lockowner_t *rfs4_findlockowner(lock_owner4 *, bool_t *);
extern rfs4_lockowner_t *rfs4_findlockowner_by_pid(pid_t);
extern void rfs4_lockowner_rele(rfs4_lockowner_t *);
extern rfs4_state_t *rfs4_findstate_by_owner_file(rfs4_openowner_t *,
rfs4_file_t *, bool_t *);
extern void rfs4_state_rele(rfs4_state_t *);
extern void rfs4_state_close(rfs4_state_t *, bool_t,
bool_t, cred_t *);
extern void rfs4_release_share_lock_state(rfs4_state_t *,
cred_t *, bool_t);
extern void rfs4_close_all_state(rfs4_file_t *);
extern rfs4_lo_state_t *rfs4_findlo_state_by_owner(rfs4_lockowner_t *,
rfs4_state_t *, bool_t *);
extern void rfs4_lo_state_rele(rfs4_lo_state_t *, bool_t);
extern void rfs4_update_lock_sequence(rfs4_lo_state_t *);
extern void rfs4_update_lock_resp(rfs4_lo_state_t *,
nfs_resop4 *);
extern rfs4_file_t *rfs4_findfile(vnode_t *, nfs_fh4 *, bool_t *);
extern rfs4_file_t *rfs4_findfile_withlock(vnode_t *, nfs_fh4 *,
bool_t *);
extern void rfs4_file_rele(rfs4_file_t *);
extern nfsstat4 rfs4_get_state(stateid4 *, rfs4_state_t **,
rfs4_dbsearch_type_t);
extern nfsstat4 rfs4_get_state_nolock(stateid4 *, rfs4_state_t **,
rfs4_dbsearch_type_t);
extern void rfs4_state_rele_nounlock(rfs4_state_t *);
extern nfsstat4 rfs4_get_deleg_state(stateid4 *,
rfs4_deleg_state_t **);
extern nfsstat4 rfs4_get_lo_state(stateid4 *, rfs4_lo_state_t **,
bool_t);
struct compound_state;
extern nfsstat4 rfs4_check_stateid(int, vnode_t *, stateid4 *,
bool_t, bool_t *, bool_t,
caller_context_t *,
struct compound_state *);
extern int rfs4_check_stateid_seqid(rfs4_state_t *, stateid4 *,
const struct compound_state *);
extern int rfs4_check_lo_stateid_seqid(rfs4_lo_state_t *,
stateid4 *,
const struct compound_state *);
#define NFS4_CHECK_STATEID_OKAY 1
#define NFS4_CHECK_STATEID_OLD 2
#define NFS4_CHECK_STATEID_BAD 3
#define NFS4_CHECK_STATEID_EXPIRED 4
#define NFS4_CHECK_STATEID_REPLAY 5
#define NFS4_CHECK_STATEID_CLOSED 6
#define NFS4_CHECK_STATEID_UNCONFIRMED 7
#define NFS4_DELEGATION_CONFLICT_DELAY (hz/10)
extern void rfs4_cbinfo_free(rfs4_cbinfo_t *);
extern void rfs4_client_setcb(rfs4_client_t *, cb_client4 *,
uint32_t);
extern void rfs4_deleg_cb_check(rfs4_client_t *);
extern nfsstat4 rfs4_vop_getattr(vnode_t *, vattr_t *, int, cred_t *);
extern rfs4_deleg_state_t *rfs4_finddeleg(rfs4_state_t *, bool_t *);
extern rfs4_deleg_state_t *rfs4_finddelegstate(stateid_t *);
extern bool_t rfs4_check_recall(rfs4_state_t *, uint32_t);
extern void rfs4_recall_deleg(rfs4_file_t *,
bool_t, rfs4_client_t *);
extern int rfs4_get_deleg(rfs4_state_t *, open_delegation_type4,
open_delegation_type4 (*policy)(rfs4_state_t *,
open_delegation_type4 dtype));
extern rfs4_deleg_state_t *rfs4_grant_delegation(delegreq_t, rfs4_state_t *,
int *);
extern void rfs4_set_deleg_response(rfs4_deleg_state_t *,
open_delegation4 *, nfsace4 *, int);
extern void rfs4_return_deleg(rfs4_deleg_state_t *, bool_t);
extern bool_t rfs4_is_deleg(rfs4_state_t *);
extern void rfs4_deleg_state_rele(rfs4_deleg_state_t *);
extern bool_t rfs4_check_delegated_byfp(int, rfs4_file_t *,
bool_t, bool_t, bool_t, clientid4 *);
extern void rfs4_clear_dont_grant(rfs4_file_t *);
extern int deleg_rd_open(femarg_t *, int, cred_t *, caller_context_t *);
extern int deleg_wr_open(femarg_t *, int, cred_t *, caller_context_t *);
extern int deleg_wr_read(femarg_t *, uio_t *, int, cred_t *,
caller_context_t *);
extern int deleg_rd_write(femarg_t *, uio_t *, int, cred_t *,
caller_context_t *);
extern int deleg_wr_write(femarg_t *, uio_t *, int, cred_t *,
caller_context_t *);
extern int deleg_rd_setattr(femarg_t *, vattr_t *, int, cred_t *,
caller_context_t *);
extern int deleg_wr_setattr(femarg_t *, vattr_t *, int, cred_t *,
caller_context_t *);
extern int deleg_rd_rwlock(femarg_t *, int, caller_context_t *);
extern int deleg_wr_rwlock(femarg_t *, int, caller_context_t *);
extern int deleg_rd_space(femarg_t *, int, flock64_t *, int, offset_t, cred_t *,
caller_context_t *);
extern int deleg_wr_space(femarg_t *, int, flock64_t *, int, offset_t, cred_t *,
caller_context_t *);
extern int deleg_rd_setsecattr(femarg_t *, vsecattr_t *, int, cred_t *,
caller_context_t *);
extern int deleg_wr_setsecattr(femarg_t *, vsecattr_t *, int, cred_t *,
caller_context_t *);
extern int deleg_rd_vnevent(femarg_t *, vnevent_t, vnode_t *, char *,
caller_context_t *);
extern int deleg_wr_vnevent(femarg_t *, vnevent_t, vnode_t *, char *,
caller_context_t *);
extern void rfs4_mon_hold(void *);
extern void rfs4_mon_rele(void *);
extern fem_t *deleg_rdops;
extern fem_t *deleg_wrops;
extern int rfs4_share(rfs4_state_t *, uint32_t, uint32_t);
extern int rfs4_unshare(rfs4_state_t *);
extern void rfs4_set_deleg_policy(nfs4_srv_t *, srv_deleg_policy_t);
extern void rfs4_hold_deleg_policy(nfs4_srv_t *);
extern void rfs4_rele_deleg_policy(nfs4_srv_t *);
#ifdef DEBUG
#define NFS4_DEBUG(var, args) if (var) cmn_err args
extern int rfs4_debug;
extern int nfs4_client_attr_debug;
extern int nfs4_client_state_debug;
extern int nfs4_client_shadow_debug;
extern int nfs4_client_lock_debug;
extern int nfs4_client_lease_debug;
extern int nfs4_seqid_sync;
extern int nfs4_client_map_debug;
extern int nfs4_client_inactive_debug;
extern int nfs4_client_recov_debug;
extern int nfs4_client_failover_debug;
extern int nfs4_client_call_debug;
extern int nfs4_client_foo_debug;
extern int nfs4_client_zone_debug;
extern int nfs4_lost_rqst_debug;
extern int nfs4_open_stream_debug;
extern int nfs4_client_open_dg;
extern int nfs4_srvmnt_debug;
extern int nfs4_utf8_debug;
void rfs4_dbe_debug(rfs4_dbe_t *e);
#ifdef NFS4_DEBUG_MUTEX
void nfs4_debug_mutex_enter(kmutex_t *, char *, int);
void nfs4_debug_mutex_exit(kmutex_t *, char *, int);
#define mutex_enter(m) nfs4_debug_mutex_enter((m), __FILE__, __LINE__)
#define mutex_exit(m) nfs4_debug_mutex_exit((m), __FILE__, __LINE__)
#endif
#else
#define NFS4_DEBUG(var, args)
#endif
#ifdef VOLATILE_FH_TEST
struct nfs_fh4_fmt {
fhandle4_t fh4_i;
uint32_t fh4_flag;
uint32_t fh4_volatile_id;
};
#else
struct nfs_fh4_fmt {
fhandle4_t fh4_i;
uint32_t fh4_flag;
};
#endif
#define FH4_NAMEDATTR 1
#define FH4_ATTRDIR 2
#define fh4_fsid fh4_i.fhx_fsid
#define fh4_len fh4_i.fhx_len
#define fh4_data fh4_i.fhx_data
#define fh4_xlen fh4_i.fhx_xlen
#define fh4_xdata fh4_i.fhx_xdata
typedef struct nfs_fh4_fmt nfs_fh4_fmt_t;
#define fh4_to_fmt4(fh4p) ((nfs_fh4_fmt_t *)(fh4p)->nfs_fh4_val)
#define get_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) & (flag))
#define set_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) |= (flag))
#define clr_fh4_flag(fh4p, flag) ((fh4_to_fmt4(fh4p)->fh4_flag) &= ~(flag))
#define NFS_FH4_LEN sizeof (nfs_fh4_fmt_t)
#define FH_TO_FMT4(exifh, nfs_fmt) { \
bzero((nfs_fmt), NFS_FH4_LEN); \
(nfs_fmt)->fh4_fsid = (exifh)->fh_fsid; \
(nfs_fmt)->fh4_xlen = (exifh)->fh_xlen; \
bcopy((exifh)->fh_xdata, (nfs_fmt)->fh4_xdata, \
(exifh)->fh_xlen); \
}
#define UTF8STRING_FREE(str) { \
kmem_free((str).utf8string_val, (str).utf8string_len); \
(str).utf8string_val = NULL; \
(str).utf8string_len = 0; \
}
#define NFS4_VOLATILE_FH(mi) \
((mi)->mi_fh_expire_type & \
(FH4_VOLATILE_ANY | FH4_VOL_MIGRATION | FH4_VOL_RENAME))
#define NFS_IS_DOTNAME(name) \
(((name)[0] == '.') && \
(((name)[1] == '\0') || (((name)[1] == '.') && ((name)[2] == '\0'))))
#define NFS4_BITMAP4_BITSPERWORD (sizeof (uint32_t) * 8)
#define CS_ACCESS_OK 0x1
#define CS_ACCESS_DENIED 0x2
#define CS_ACCESS_LIMITED 0x4
struct compound_state {
struct exportinfo *exi;
struct exportinfo *saved_exi;
cred_t *basecr;
caddr_t principal;
int nfsflavor;
cred_t *cr;
bool_t cont;
uint_t access;
bool_t deleg;
vnode_t *vp;
bool_t mandlock;
vnode_t *saved_vp;
nfsstat4 *statusp;
nfs_fh4 fh;
nfs_fh4 saved_fh;
struct svc_req *req;
char fhbuf[NFS4_FHSIZE];
uint8_t minorversion;
rfs4_session_t *sp;
slotid4 slotno;
rfs4_slot_t *slot;
rfs4_client_t *client;
uint16_t op_pos;
uint16_t op_len;
#define RFS4_DISPATCH_DONE (1 << 0)
#define RFS4_CURRENT_STATEID (1 << 1)
#define RFS4_SAVED_STATEID (1 << 2)
uint8_t cs_flags;
bool_t cachethis;
COMPOUND4res *cmpresp;
stateid4 current_stateid;
stateid4 save_stateid;
};
typedef struct compound_state compound_state_t;
static inline bool_t
rfs4_has_session(const compound_state_t *cs)
{
return (cs->slot != NULL);
}
extern stateid4 invalid_stateid;
#define INVALID_STATEID(x) (!memcmp((x), &invalid_stateid, sizeof (stateid4))
enum nfs4_attr_cmd {
NFS4ATTR_SUPPORTED = 0,
NFS4ATTR_GETIT = 1,
NFS4ATTR_SETIT = 2,
NFS4ATTR_VERIT = 3,
NFS4ATTR_FREEIT = 4
};
typedef enum nfs4_attr_cmd nfs4_attr_cmd_t;
struct nfs4_svgetit_arg {
nfs4_attr_cmd_t op;
struct compound_state *cs;
struct statvfs64 *sbp;
uint_t flag;
uint_t xattr;
bool_t rdattr_error_req;
nfsstat4 rdattr_error;
bool_t is_referral;
bool_t mntdfid_set;
fattr4_mounted_on_fileid
mounted_on_fileid;
vattr_t vap[1];
};
struct nfs4_ntov_map {
bitmap4 fbit;
uint_t vbit;
bool_t vfsstat;
bool_t mandatory;
uint_t nval;
int xdr_size;
xdrproc_t xfunc;
int (*sv_getit)(nfs4_attr_cmd_t, struct nfs4_svgetit_arg *,
union nfs4_attr_u *);
char *prtstr;
};
struct nfs4attr_to_vattr {
vnode_t *vp;
vattr_t *vap;
nfs_fh4 *fhp;
nfsstat4 rdattr_error;
uint32_t flag;
fattr4_change change;
fattr4_fsid srv_fsid;
fattr4_mounted_on_fileid mntd_fid;
};
typedef struct nfs4attr_to_vattr ntov4_t;
#define NTOV_FHP_VALID 0x01
#define NTOV_RDATTR_ERROR_VALID 0x02
#define NTOV_CHANGE_VALID 0x04
#define NTOV_SUPP_VALID 0x08
#define NTOV_SRV_FSID_VALID 0x10
#define NTOV_MOUNTED_ON_FILEID_VALID 0x20
#define FATTR4_MANDATTR_MASK ( \
FATTR4_SUPPORTED_ATTRS_MASK | \
FATTR4_TYPE_MASK | \
FATTR4_FH_EXPIRE_TYPE_MASK | \
FATTR4_CHANGE_MASK | \
FATTR4_SIZE_MASK | \
FATTR4_LINK_SUPPORT_MASK | \
FATTR4_SYMLINK_SUPPORT_MASK | \
FATTR4_NAMED_ATTR_MASK | \
FATTR4_FSID_MASK | \
FATTR4_UNIQUE_HANDLES_MASK | \
FATTR4_LEASE_TIME_MASK | \
FATTR4_RDATTR_ERROR_MASK | \
FATTR4_FILEHANDLE_MASK)
struct nfs4attr_to_osattr {
void *attrconv_arg;
uint_t mask;
};
struct mntinfo4;
enum lkp4_attr_setup {
LKP4_NO_ATTRIBUTES = 0,
LKP4_ALL_ATTRIBUTES = 3,
LKP4_LAST_NAMED_ATTR = 5,
LKP4_LAST_ATTRDIR = 6,
LKP4_ALL_ATTR_SECINFO = 7
};
typedef struct lookup4_param {
enum lkp4_attr_setup l4_getattrs;
int header_len;
int trailer_len;
bitmap4 ga_bits;
COMPOUND4args_clnt *argsp;
COMPOUND4res_clnt *resp;
int arglen;
struct mntinfo4 *mi;
} lookup4_param_t;
#define NFS4_FATTR4_FINISH -1
typedef int (*nfs4attr_to_os_t)(int, union nfs4_attr_u *,
struct nfs4attr_to_osattr *);
typedef struct {
int error;
nfsstat4 stat;
enum clnt_stat rpc_status;
} nfs4_error_t;
extern void rfs4_op_readdir(nfs_argop4 *, nfs_resop4 *,
struct svc_req *, struct compound_state *);
extern void nfs_fh4_copy(nfs_fh4 *, nfs_fh4 *);
extern void nfs4_fattr4_free(fattr4 *);
extern int nfs4lookup_setup(char *, lookup4_param_t *, int);
extern void nfs4_getattr_otw_norecovery(vnode_t *,
nfs4_ga_res_t *, nfs4_error_t *, cred_t *, int);
extern int nfs4_getattr_otw(vnode_t *, nfs4_ga_res_t *, cred_t *, int);
extern int nfs4cmpfh(const nfs_fh4 *, const nfs_fh4 *);
extern int nfs4cmpfhandle(nfs4_fhandle_t *, nfs4_fhandle_t *);
extern int nfs4getattr(vnode_t *, struct vattr *, cred_t *);
extern int nfs4_waitfor_purge_complete(vnode_t *);
extern int nfs4_validate_caches(vnode_t *, cred_t *);
extern int nfs4init(int, char *);
extern void nfs4fini(void);
extern int nfs4_vfsinit(void);
extern void nfs4_vfsfini(void);
extern void nfs4_vnops_init(void);
extern void nfs4_vnops_fini(void);
extern void nfs_idmap_init(void);
extern void nfs_idmap_flush(int);
extern void nfs_idmap_fini(void);
extern int nfs4_rnode_init(void);
extern int nfs4_rnode_fini(void);
extern int nfs4_shadow_init(void);
extern int nfs4_shadow_fini(void);
extern int nfs4_acache_init(void);
extern int nfs4_acache_fini(void);
extern int nfs4_subr_init(void);
extern int nfs4_subr_fini(void);
extern void nfs4_acl_init(void);
extern void nfs4_acl_free_cache(vsecattr_t *);
extern int geterrno4(nfsstat4);
extern nfsstat4 puterrno4(int);
extern int nfs4_need_to_bump_seqid(COMPOUND4res_clnt *);
extern int nfs4tsize(void);
extern int checkauth4(struct compound_state *, struct svc_req *);
extern nfsstat4 call_checkauth4(struct compound_state *, struct svc_req *);
extern int is_exported_sec(int, struct exportinfo *);
extern void nfs4_vmask_to_nmask(uint_t, bitmap4 *);
extern void nfs4_vmask_to_nmask_set(uint_t, bitmap4 *);
extern int nfs_idmap_str_uid(utf8string *u8s, uid_t *, bool_t);
extern int nfs_idmap_str_gid(utf8string *u8s, gid_t *, bool_t);
extern int nfs_idmap_uid_str(uid_t, utf8string *u8s, bool_t);
extern int nfs_idmap_gid_str(gid_t gid, utf8string *u8s, bool_t);
extern int nfs4_time_ntov(nfstime4 *, timestruc_t *);
extern int nfs4_time_vton(timestruc_t *, nfstime4 *);
extern char *utf8_to_str(utf8string *, uint_t *, char *);
extern char *utf8_to_fn(utf8string *, uint_t *, char *);
extern utf8string *str_to_utf8(char *, utf8string *);
extern utf8string *utf8_copy(utf8string *, utf8string *);
extern int utf8_compare(const utf8string *, const utf8string *);
extern nfsstat4 utf8_dir_verify(utf8string *);
extern char *utf8_strchr(utf8string *, const char);
extern int ln_ace4_cmp(nfsace4 *, nfsace4 *, int);
extern int vs_aent_to_ace4(vsecattr_t *, vsecattr_t *, int, int);
extern int vs_ace4_to_aent(vsecattr_t *, vsecattr_t *, uid_t, gid_t,
int, int);
extern int vs_ace4_to_acet(vsecattr_t *, vsecattr_t *, uid_t, gid_t,
int);
extern int vs_acet_to_ace4(vsecattr_t *, vsecattr_t *, int);
extern void vs_acet_destroy(vsecattr_t *);
extern void vs_ace4_destroy(vsecattr_t *);
extern void vs_aent_destroy(vsecattr_t *);
extern int vn_find_nfs_record(vnode_t *, nvlist_t **, char **, char **);
extern int vn_is_nfs_reparse(vnode_t *, cred_t *);
extern fs_locations4 *fetch_referral(vnode_t *, cred_t *);
extern char *build_symlink(vnode_t *, cred_t *, size_t *);
extern int stateid4_cmp(stateid4 *, stateid4 *);
extern vtype_t nf4_to_vt[];
extern struct nfs4_ntov_map nfs4_ntov_map[];
extern uint_t nfs4_ntov_map_size;
extern struct vfsops *nfs4_vfsops;
extern struct vnodeops *nfs4_vnodeops;
extern const struct fs_operation_def nfs4_vnodeops_template[];
extern vnodeops_t *nfs4_trigger_vnodeops;
extern const struct fs_operation_def nfs4_trigger_vnodeops_template[];
extern uint_t nfs4_tsize(struct knetconfig *);
extern uint_t rfs4_tsize(struct svc_req *);
extern bool_t xdr_inline_decode_nfs_fh4(uint32_t *, nfs_fh4_fmt_t *,
uint32_t);
extern bool_t xdr_inline_encode_nfs_fh4(uint32_t **, uint32_t *,
nfs_fh4_fmt_t *);
#ifdef DEBUG
extern int rfs4_do_pre_op_attr;
extern int rfs4_do_post_op_attr;
#endif
extern stateid4 clnt_special0;
extern stateid4 clnt_special1;
#define CLNT_ISSPECIAL(id) (stateid4_cmp(id, &clnt_special0) || \
stateid4_cmp(id, &clnt_special1))
extern void rfs4_ss_clid(nfs4_srv_t *nsrv4, rfs4_client_t *);
extern void rfs4_ss_chkclid(nfs4_srv_t *nsrv4, rfs4_client_t *);
nfsstat4 do_rfs4_op_secinfo(struct compound_state *, char *, SECINFO4res *);
extern void rfs4_do_server_start(int, int, nfs4_minor_t, int);
extern void rfs4_compound(COMPOUND4args *, COMPOUND4res *,
compound_state_t *, struct svc_req *, int *);
extern void rfs4_init_compound_state(struct compound_state *);
extern void rfs4_fini_compound_state(struct compound_state *);
struct rpcdisp;
extern int rfs4_dispatch(struct rpcdisp *, struct svc_req *, SVCXPRT *, char *);
extern void rfs4_compound_free(COMPOUND4res *);
extern bool_t rfs4_idempotent_req(const COMPOUND4args *);
extern void rfs4_srvrinit(void);
extern void rfs4_srvrfini(void);
extern void rfs4_srv_zone_init(nfs_globals_t *);
extern void rfs4_srv_zone_fini(nfs_globals_t *);
extern void rfs4_state_g_init(void);
extern void rfs4_state_zone_init(nfs4_srv_t *);
extern void rfs4_state_g_fini(void);
extern void rfs4_state_zone_fini(void);
extern nfs4_srv_t *nfs4_get_srv(void);
void put_stateid4(struct compound_state *, stateid4 *);
void get_stateid4(struct compound_state *, stateid4 *);
#endif
#ifdef __cplusplus
}
#endif
#endif