/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* onc72V src/oncplus/usr/include/oncplus/nfs/rnode.h 1.49.1.4 */ /* */ /* */ /* */ /* COPYRIGHT International Business Machines Corp. 1996,2020 */ /* All Rights Reserved */ /* */ /* IBM_PROLOG_END_TAG */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ /* The copyright notice above does not evidence any */ /* actual or intended publication of such source code. */ /* * PROPRIETARY NOTICE (Combined) * * This source code is unpublished proprietary information * constituting, or derived under license from AT&T's Unix(r) System V. * * * * Copyright Notice * * Notice of copyright on this source code product does not indicate * publication. * * (c) 1986,1987,1988,1989,1990,1991 Sun Microsystems, Inc. * (c) 1983,1984,1985,1986,1987,1988,1989 AT&T. * All rights reserved. */ #ifndef _NFS_RNODE_H #define _NFS_RNODE_H /* #pragma ident "@(#)rnode.h 1.48 95/03/30 SMI" *//* SVr4.0 1.3 */ /* rnode.h 1.23 88/08/19 SMI */ #ifdef __cplusplus extern "C" { #endif #include #include #include typedef struct access_cache { uint32 known; uint32 allowed; cred_t *cred; cid_t cid; time_t ttl; struct access_cache *next; eye_catch8b_t eyec; } access_cache; /* default time to live value for access_cache. 72 hours */ #define ACCESSTTL 259200 /* default time to live value for access_cache if access failed. 30 seconds */ #define ACCESSFAILTTL 30 #define NFS_FHANDLE_LEN 64 #undef fh_len typedef struct nfs_fhandle { int fh_len; char fh_buf[NFS_FHANDLE_LEN]; } nfs_fhandle; typedef union { offset_t _f; /* Full 64 bit offset value */ struct { long _u; /* upper 32 bits of offset value */ off_t _l; /* lower 32 bits of offset value */ } _p; } lloff_t; typedef struct rddir_cache { lloff_t _cookie; /* cookie used to find this cache entry */ lloff_t _ncookie; /* cookie used to find the next cache entry */ char *entries; /* buffer containing dirent entries */ int eof; /* EOF reached after this request */ int entlen; /* size of dirent entries in buf */ int buflen; /* size of the buffer used to store entries */ int flags; /* control flags, see below */ kcondvar_t cv; /* cv for blocking */ int error; /* error from RPC operation */ int count; /* ref count for the rddir cache entry */ struct rddir_cache *next; /* ptr to next entry in cache */ eye_catch8b_t eyec; /* eye catcher */ } rddir_cache; #define nfs_cookie _cookie._p._l #define nfs_ncookie _ncookie._p._l #define nfs3_cookie _cookie._f #define nfs3_ncookie _ncookie._f #define nfs4_cookie _cookie._f #define nfs4_ncookie _ncookie._f #define RDDIR 0x01 /* readdir operation in progress */ #define RDDIRWAIT 0x02 /* waiting on readdir in progress */ #define RDDIRREQ 0x04 /* a new readdir is required */ #define RDDIRNEW 0x08 /* a new readdir verifier is required */ #define RDDIRDEL 0x10 /* * whoever release the last hold need to free * this readdir entry */ #define RDDIRPOP 0x20 /* populating the rddir cache entry */ /* * Set the maximum number of dir cache elements that can exist * on a given directory as a way to limit memory consumption * of directory cache data at an directory level. For the 32-bit kernel, * use a smaller value due to kernel memory heap limitations. */ #ifdef __64BIT__ #define NFS_READDIR_CACHE_MAX_ENTRIES 256 #else #define NFS_READDIR_CACHE_MAX_ENTRIES 64 #endif typedef struct symlink_cache { char *contents; /* contents of the symbolic link */ int32long64_t len; /* length of the contents */ int32long64_t size; /* size of the allocated buffer */ } symlink_cache; typedef struct commit { offset3 c_commbase; /* base offset to do commit from */ count3 c_commlen; /* len to commit */ kcondvar_t c_cv; /* condvar for waiting for commit */ } commit_t; /* * The various values for the commit states. These are stored in * the p_fsdata byte in the page struct. */ #define C_NOCOMMIT 0 /* no commit is required */ #define C_COMMIT 1 /* a commit is required so do it now */ #define C_DELAYCOMMIT 2 /* a commit is required, but can be delayed */ /* * The lock manager holds state making it possible for the client * and server to be out of sync. For example, if the response from * the server granting a lock request is lost, the server will think * the lock is granted and the client will think the lock is lost. * To deal with this, a list of processes for which the client is * not sure if the server holds a lock is attached to the rnode. * When such a process closes the rnode, an unlock request is sent * to the server to unlock the entire file. * * The list is kept as a singularly linked NULL terminated list. * Because it is only added to under extreme error conditions, the * list shouldn't get very big. DEBUG kernels print a console warning * when the number of entries on a list go beyond nfs_lmpl_high_water * an arbitrary number defined in nfs_add_locking_pid() */ typedef struct lock_manager_pid_list { pid_t lmpl_pid; struct lock_manager_pid_list *lmpl_next; } lmpl_t; /* the following structure is for v4 use */ typedef struct lookup_info { vnode_t *parents; char *name; int error; } lookup_info_t; /* V4 lock owner info */ typedef struct client_locker { int id; cid_t cid; pid_t pid; stateid4 stateid; seqid4 next_seqid; int flags; int sleep; time_t sleep_start; struct client_locker *next; eye_catch8b_t eyec; } client_locker_t; #define LOCK_OWNER_VALID 1 /* Lock owner is in use */ /* Number of lockers to keep hanging around */ #define MAX_RNODE_LOCK_OWNERS 5 /* V4 state information - allocated only when needed */ typedef struct rnode_state { cid_t rs_kcid; /* Corral ID */ int rs_flags; /* State flags */ stateid4 rs_open_stateid; /* stateid for this object */ stateid4 rs_deleg_stateid; /* stateid for delegation */ uint rs_open_owner_index; /* index of open owner */ int rs_open_owner_val; /* value of open owner */ client_locker_t *rs_lock_owners; /* list of lock owners */ int rs_lock_id; /* next lock owner to use */ int rs_num_lockers; /* number of lock owners */ vnode_t *rs_open_dir; /* Parent of opened file */ char *rs_open_name; /* Name of open file */ int rs_open_name_len; /* Length of name */ clientid4 rs_clid; /* Clientid when state set */ time_t rs_close_time; /* Time of last close */ time_t rs_state_time; /* Time of last state change */ int64_t rs_unique_id; /* instance id */ int rs_rdcnt; /* read open count */ int rs_wrcnt; /* write open count */ int rs_excnt; /* exec open count */ int rs_io_count; /* current io count */ cred_t *rs_cred; /* cref for io */ struct rnode_state *rs_next; /* next wpar */ eye_catch8b_t rs_eyec; /* eye catcher */ } rnode_state_t; typedef struct rnodev4 { /* this is the structure which contains all the v4 fields */ verifier4 r_verfv4; /* version 4 write verifier */ verifier4 r_cookieverfv4; /* version 4 readdir cookie verifier */ nfs_fh4 r_fhv4; /* file handle for v4 */ tid_t r_fh_cv4; /* condition variable for fh */ changeid4 r_changev4; /* change id for this object */ time_t r_atimetime4; /* time atime attr becomes invalid */ struct nfs4_fsid *r_fsidpv4; /* fsid pointer */ lookup_info_t r_lookupv4; /* lookup structure for volatile fh */ int r_secv4; /* security flavor for this object */ tid_t r_sec_cv4; /* condition variable for WRONGSEC */ int r_sec_rc4; /* return code for WRONGSEC */ tid_t r_getattr_cv4; /* condition variable for gatattr */ int r_getattr_rc4; /* return code for getattr */ int r_deleg_countv4; /* number of delegations held */ int r_io_countv4; /* number of io's in flight */ tid_t r_dirnew_cv4; /* condition variable for getting new * readdir verifier */ kcondvar_t r_state_cvv4; /* condvar for open/lock */ struct rnode *r_dupv4; /* dup rnode */ struct rnode *r_recallv4; /* Recall list link */ struct rnode *r_reclaimv4; /* Reclaim list link */ int r_state_countv4;/* structs on r_state_info */ rnode_state_t *r_state_infov4;/* Open file state information */ int r_non_named_opensv4;/* Count of non-named opens */ } rnodev4_t; /* V2/3 per-WPAR open counts - used only when WPARs are being used */ typedef struct v3_state_info { cid_t v3s_kcid; int v3s_rdcnt; int v3s_wrcnt; struct v3_state_info *v3s_next; } v3_state_info_t; typedef struct rnodev3 { /* this is the structure which contains all the v2/v3 fields */ writeverf3 r_verf3; cookieverf3 r_cookieverf3; nfs_fhandle r_fh3; int (*r_putapage3) (void); v3_state_info_t *r_v3_state_info3; } rnodev3_t; /* * Remote file information structure. * * The rnode is the "inode" for remote files. It contains all the * information necessary to handle remote file on the client side. * * Note on file sizes: we keep two file sizes in the rnode: the size * according to the client (r_size) and the size according to the server * (r_attr.va_size). They can differ because we modify r_size during a * write system call (nfs_rdwr), before the write request goes over the * wire (before the file is actually modified on the server). If an OTW * request occurs before the cached data is written to the server the file * size returned from the server (r_attr.va_size) may not match r_size. * r_size is the one we use, in general. r_attr.va_size is only used to * determine whether or not our cached data is valid. * * Each rnode has 2 locks associated with it (not including the rnode * hash table and free list locks): * * r_rwlock: Serializes nfs_write and nfs_setattr requests * and allows nfs_read requests to proceed in parallel. * Serializes reads/updates to directories. * * r_statelock: Protects all fields in the rnode except for * those listed below. This lock is intented * to be held for relatively short periods of * time (not accross entire putpage operations, * for example). * * The following members are protected by the mutex nfs_rtable_lock: * r_freef * r_freeb * r_hash * * Note: r_modaddr is only accessed when the r_statelock mutex is held. * Its value is also controlled via r_rwlock. It is assumed that * there will be only 1 writer active at a time, so it safe to * set r_modaddr and release r_statelock as long as the r_rwlock * writer lock is held. * * Lock ordering: * r_rwlock > r_statelock */ typedef struct rnode { struct vmm_client_info vci; /* VMM client info struct */ struct rnode *r_freef; /* free list forward pointer */ struct rnode *r_freeb; /* free list back pointer */ struct rnode *r_hash; /* rnode hash chain */ vnode_t r_vnode; /* vnode for remote file */ struct gnode r_gnode; /* gnode for remote file */ short r_vers; /* which nfs rnode this is. 2/3 or 4 */ short r_error; /* async write error */ int r_rc_err; /* recover error */ krwlock_t r_rwlock; /* serializes write/setattr requests */ kmutex_t r_statelock; /* protects (most of) rnode contents */ kmutex_t r_reflock; /* protects v_count in vnode */ uint32_t r_flags; /* flags, see below */ uint32_t r_flags2; /* more flags, see below */ cred_t *r_cred; /* current credentials */ cred_t *r_altcred; /* saved credentials */ cred_t *r_unlcred; /* unlinked credentials */ char *r_unlname; /* unlinked file name */ vnode_t *r_unldvp; /* parent dir of unlinked file */ offset_t r_size; /* client's view of file size */ struct vattr r_attr; /* cached vnode attributes */ time_t r_attrtime; /* time attributes become invalid */ time_t r_mtime; /* client time file last modified */ u_long r_count; /* # of refs not reflect in v_count */ kcondvar_t r_cv; /* condvar for blocked threads */ long r_seq; /* sequence number for attr changes */ uint32_t r_acc_num; /* number of access cache */ access_cache *r_acc; /* cache of access results */ union { symlink_cache _symlink; /* cached readlink response */ struct { /* this structure are used by random read */ uint32long64_t r_roffp; uint32long64_t r_oreadsp; uint32long64_t r_readsp; uint32long64_t r_nfsrfaultsp; /* # of non-dio (normal) opens */ uint32_t nondio_opencnt; /* # opens for direct I/O, or CIO */ uint32_t dio_opencnt; } _regfile; struct { rddir_cache *r_dircache; rddir_cache *r_dircache_eof; uint32_t r_dircache_count; uint32_t r_lookup_count; uint32_t r_readdir_namlen; } _dir; } _type_f; offset_t r_modaddr; /* address for page in writerp */ commit_t r_commit; /* commit information */ struct acl *r_acl; /* cached security attributes (acls) */ u_long r_aclsz; /* the size of the acl */ struct pcl *r_pcl; /* the permission control list */ u_long r_pclsz; /* the size of the pcl */ vmhandle_t r_file_vh; vmid_t r_file_sid; union { rnodev4_t rnodev4; rnodev3_t rnodev3; } _vers_u; struct rnode *r_key1; /* key1 used for Live Kernel Update */ int r_checkpoint_serial; /* used to see if we need to * checkpoint the rnode */ eye_catch8b_t r_eyec; /* eye catcher */ } rnode_t; /* * The rnode should probably be changed to define these as real * fields using unions to overlap the existing fields that are * being overloaded. * * These have been introduced for performance improvement * version 3 random read. */ #define RTO_ROFFP(rp) (uint32long64_t *)&((rp)->_type_f._regfile.r_roffp) #define RTO_OREADSP(rp) (uint32long64_t *)&((rp)->_type_f._regfile.r_oreadsp) #define RTO_RREADSP(rp) (uint32long64_t *)&((rp)->_type_f._regfile.r_readsp) #define RTO_NFSRFAULTSP(rp) \ (uint32long64_t *)&((rp)->_type_f._regfile.r_nfsrfaultsp) /* * Helpers to access dio/cio related fields. */ #define r_nondiocnt _type_f._regfile.nondio_opencnt #define r_diocnt _type_f._regfile.dio_opencnt /* * helpers for keep track of when to do readdir_plus */ #define r_l_count _type_f._dir.r_lookup_count #define r_rddir_namlen _type_f._dir.r_readdir_namlen /* * Macro for file and directory stuff */ #define r_dir _type_f._dir.r_dircache #define r_dir_count _type_f._dir.r_dircache_count #define r_direof _type_f._dir.r_dircache_eof #define r_vh r_file_vh #define r_sid r_file_sid /* * Macro for v2/v3 stuff */ #define r_verf _vers_u.rnodev3.r_verf3 #define r_cookieverf _vers_u.rnodev3.r_cookieverf3 #define r_fh _vers_u.rnodev3.r_fh3 #define r_putapage _vers_u.rnodev3.r_putapage3 #define r_v3_state_info _vers_u.rnodev3.r_v3_state_info3 #define r_symlink _type_f._symlink /* * Macro for v4 stuff */ #define r_verf4 _vers_u.rnodev4.r_verfv4 #define r_cookieverf4 _vers_u.rnodev4.r_cookieverfv4 #define r_fh4 _vers_u.rnodev4.r_fhv4 #define r_fh4_cv _vers_u.rnodev4.r_fh_cv4 #define r_change _vers_u.rnodev4.r_changev4 #define r_atimetime _vers_u.rnodev4.r_atimetime4 #define r_fsidp _vers_u.rnodev4.r_fsidpv4 #define r_lookup _vers_u.rnodev4.r_lookupv4 #define r_sec _vers_u.rnodev4.r_secv4 #define r_sec_cv _vers_u.rnodev4.r_sec_cv4 #define r_sec_rc _vers_u.rnodev4.r_sec_rc4 #define r_getattr_cv _vers_u.rnodev4.r_getattr_cv4 #define r_getattr_rc _vers_u.rnodev4.r_getattr_rc4 #define r_deleg_count _vers_u.rnodev4.r_deleg_countv4 #define r_io_count _vers_u.rnodev4.r_io_countv4 #define r_dirnew_cv _vers_u.rnodev4.r_dirnew_cv4 #define r_state_cv _vers_u.rnodev4.r_state_cvv4 #define r_dup _vers_u.rnodev4.r_dupv4 #define r_recall _vers_u.rnodev4.r_recallv4 #define r_reclaim _vers_u.rnodev4.r_reclaimv4 #define r_state_count _vers_u.rnodev4.r_state_countv4 #define r_state_info _vers_u.rnodev4.r_state_infov4 #define non_named_opens4 _vers_u.rnodev4.r_non_named_opensv4 /* * Flags */ #define REOF 0x1 /* EOF encountered on readdir */ #define RDIRTY 0x2 /* dirty pages from write operation */ #define RDONTWRITE 0x4 /* don't even attempt to write */ #define RMODINPROGRESS 0x8 /* page modification happening */ #define RTRUNCATE 0x10 /* truncating, don't commit */ #define RHAVEVERF 0x20 /* have a write verifier to compare against */ #define RCOMMIT 0x40 /* commit in progress */ #define RCOMMITWAIT 0x80 /* someone is waiting to do a commit */ #define RHASHED 0x100 /* rnode is in hash queues */ #define ROUTOFSPACE 0x200 /* an out of space error has happened */ #define RSERIALIZE 0x400 /* serialize otw getattrs */ #define RRECOVER 0x800 /* serialize v3 async write recovery */ #define RNOCACHE 0x1000 /* no file caching is to occur */ #define RACLINVALID 0x2000 /* Acl for this rnode has become */ /* invalid because of attr update */ #define RPCLINVALID 0x4000 /* Pcl for this rnode has become */ /* invalid because of attr update */ #define RFHEXPIRED 0x8000 /* the file handle has expired. we are */ /* in the middle of revalidating it */ #define RDIO 0x10000 /* direct IO is in effect */ #define RCIO 0x20000 /* concurrent IO is in effect. CIO also infers * direct IO */ /* flags for version 4 */ #define RWRONGSEC 0x40000 /* In process of determine sec flavor */ #define RREFETCHFH 0x80000 /* need to refetch the filehandl. this is * used only in replication or migration */ #define RFSROOT 0x100000 /* this rnode is the root of a fsid */ #define RDIRNEW 0x200000 /* need a new readdir cookie verifier */ #define RSTATE 0x1000000 /* state change is in progress */ #define RIO 0x2000000 /* I/O is in progress */ #define RDELEG_RET 0x4000000 /* Delegations are being returned */ #define RDELEG_IO 0x8000000 /* IO is ok during state change */ #define RCIOR 0x10000000 /* CIOR is in effect */ #define RNEEDCOMMIT 0x20000000 /* COMMIT needed after write */ /* flags in r_flags2 */ #define RPOSIX 0x1 /* Posix locking on server */ #define RJUKEBOXRECVD 0x2 /* Server has returned JUKEBOX error */ #define RDUP 0x4 /* Duplicate rnode */ #define RDNLCPURGE 0x8 /* dnlc_purge_vp in progress for file */ #define RCHECKHOLD 0x10 /* rnode has extra hold for checkpointing */ /* state flags */ #define RS_OPEN 0x1 /* File is open on the server */ #define RS_DEAD 0x2 /* File is open on client, but not on svr */ #define RS_BADLOCKS 0x4 /* Locking state on the server lost */ #define RS_DELEG_READ 0x10 /* Have read relegation */ #define RS_DELEG_WRITE 0x20 /* Have write delegation */ #define RS_DELEG_XXX 0x400 /* Recall may be in progress */ #define RS_RESTART 0x1000 /* this rnode was restarted */ #define RS_NOSTATE 0x2000 /* Go stateless */ #define RS_FREE 0x4000 /* Go stateless */ #define RS_DELAY 0x10000 /* Delay freeing state info */ #define RS_DELEG (RS_DELEG_READ | RS_DELEG_WRITE) #define RS_HAS_STATE (RS_OPEN | RS_DELEG_READ | RS_DELEG_WRITE) /* * return code from make_rnode4 */ #define RBRANDNEW 0x0 /* * the rnode is brand new. either allocated * from the heap or freelist. */ #define RFREED_REUSED 0x1 /* * the rnode is found in the rtable and has * been inactivated before but all the * attributes are still there. */ #define RREUSE 0x2 /* rnode is found and is active */ #define RMOVED 0x3 /* * no rnode is created because a move was done * after we fetch the move_seq and before * we create the rnode */ /* Helper to see if direct IO should used */ #define RUSE_DIRECTIO(RP) ((RP)->r_flags & (RDIO|RCIO)) /* * Convert between vnode and rnode */ #define RTOV(rp) (&(rp)->r_vnode) #define VTOR(vp) ((rnode_t *)((vp)->v_data)) #define VTOVCI(vp) ((struct vmm_client_info *)((vp)->v_data)) /* same as VTOR since the * vmm_client_info is the * first in the rnode */ #define VTOFH(vp) (RTOFH(VTOR(vp))) #define RTOFH(rp) ((fhandle_t *)(&(rp)->r_fh.fh_buf)) #define VTOFH3(vp) (RTOFH3(VTOR(vp))) #define RTOFH3(rp) ((nfs_fh3 *)(&(rp)->r_fh)) /* * check nfs v4 minor version. * r_minor_vers is the minor version of the rnode. * IS41() will return TRUE if minor version is 1 and FALSE otherwise. */ #define r_minor_vers r_fsidp->f_current->f_srv_objp->s_minor_version #define IS41(rp) ((rp)->r_minor_vers == 1) #ifdef _KERNEL extern void nfs_async_readahead(vnode_t *, u_int, caddr_t, struct seg *, cred_t *, void (*)(vnode_t *, u_int, caddr_t, struct seg *, cred_t *)); extern void nfs_async_readdir(vnode_t *, rddir_cache *, cred_t *, int (*)(vnode_t *, rddir_cache *, cred_t *)); extern int writerp(rnode_t *, int32long64_t, struct uio *); extern int nfs_putpages(vnode_t *, offset_t, u_int, int, cred_t *); extern void nfs_invalidate_pages(vnode_t *, offset_t, cred_t *); extern int rfs2call(mntinfo_t *, int, xdrproc_t, caddr_t, xdrproc_t, caddr_t, cred_t *, int *, enum nfsstat *, cid_t); extern int rfs3call(mntinfo_t *, int, xdrproc_t, caddr_t, xdrproc_t, caddr_t, cred_t *, int *, nfsstat3 *, cid_t); extern vnode_t *makenfsnode(fhandle_t *, struct nfsfattr *, struct vfs *, cred_t *); extern vnode_t *makenfs3node(nfs_fh3 *, fattr3 *, struct vfs *, int, cred_t *); extern void rp_addfree(rnode_t *, cred_t *); extern void rp_addhash(rnode_t *); extern void rp_rmhash(rnode_t *); extern struct mntinfo * unmount_rinactive_block(vnode_t *); extern void unmount_rinactive_unblock(struct mntinfo *); extern void unmount_rinactive_wait(struct mntinfo *); extern int check_rtable(struct vfs *, vnode_t *); extern void purge_rtable(struct vfs *, cred_t *, int); extern int rcheck(struct vfs *); extern int rflush(struct vfs *, int, cred_t *); extern void nfs_printfhandle(nfs_fhandle *); extern void nfs_write_error(vnode_t *, int, int, cred_t *); extern void add_dircache_entry(rnode_t *, rddir_cache *); extern void rddir_cache_freebuf(char *, int); extern void rddir_cache_rele(rddir_cache *); extern char *rddir_cache_allocbuf(int); extern int nfs4_process_readdir_entries(rnode_t *, rddir_cache *, entry4 *, int, ino_t, int, int *, struct ucred *); #ifdef DEBUG extern access_cache *access_cache_alloc(size_t, int); extern void access_cache_free(void *, size_t); extern rddir_cache *rddir_cache_alloc(size_t, int); extern void rddir_cache_free(void *, size_t); extern char *symlink_cache_alloc(size_t, int); extern void symlink_cache_free(void *, size_t); #endif #endif #ifdef __cplusplus } #endif #endif /* _NFS_RNODE_H */