1*13230298Sriastradh /* $NetBSD: nfsnode.h,v 1.77 2024/12/07 02:05:55 riastradh Exp $ */ 2fccfa11aScgd 3266a376bSmycroft /* 4cde1d475Smycroft * Copyright (c) 1989, 1993 5cde1d475Smycroft * The Regents of the University of California. All rights reserved. 6266a376bSmycroft * 7266a376bSmycroft * This code is derived from software contributed to Berkeley by 8266a376bSmycroft * Rick Macklem at The University of Guelph. 9266a376bSmycroft * 10266a376bSmycroft * Redistribution and use in source and binary forms, with or without 11266a376bSmycroft * modification, are permitted provided that the following conditions 12266a376bSmycroft * are met: 13266a376bSmycroft * 1. Redistributions of source code must retain the above copyright 14266a376bSmycroft * notice, this list of conditions and the following disclaimer. 15266a376bSmycroft * 2. Redistributions in binary form must reproduce the above copyright 16266a376bSmycroft * notice, this list of conditions and the following disclaimer in the 17266a376bSmycroft * documentation and/or other materials provided with the distribution. 18aad01611Sagc * 3. Neither the name of the University nor the names of its contributors 19266a376bSmycroft * may be used to endorse or promote products derived from this software 20266a376bSmycroft * without specific prior written permission. 21266a376bSmycroft * 22266a376bSmycroft * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23266a376bSmycroft * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24266a376bSmycroft * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25266a376bSmycroft * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26266a376bSmycroft * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27266a376bSmycroft * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28266a376bSmycroft * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29266a376bSmycroft * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30266a376bSmycroft * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31266a376bSmycroft * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32266a376bSmycroft * SUCH DAMAGE. 33266a376bSmycroft * 345ac7df1cSfvdl * @(#)nfsnode.h 8.9 (Berkeley) 5/14/95 35266a376bSmycroft */ 36266a376bSmycroft 375ac7df1cSfvdl 385ac7df1cSfvdl #ifndef _NFS_NFSNODE_H_ 395ac7df1cSfvdl #define _NFS_NFSNODE_H_ 405ac7df1cSfvdl 41*13230298Sriastradh #include <sys/types.h> 42*13230298Sriastradh 43f1439806Syamt #include <sys/condvar.h> 446d6b5c51Syamt #include <sys/mutex.h> 45*13230298Sriastradh #include <sys/queue.h> 46*13230298Sriastradh #include <sys/timespec.h> 476d6b5c51Syamt 485ac7df1cSfvdl #include <nfs/nfs.h> 49*13230298Sriastradh #include <nfs/nfsproto.h> 50*13230298Sriastradh 5164c6d1d2Schs #include <miscfs/genfs/genfs.h> 5264c6d1d2Schs #include <miscfs/genfs/genfs_node.h> 535ac7df1cSfvdl 54cde1d475Smycroft /* 557f7d814eSfvdl * Definitions for the directory cache. Because directory cookies 567f7d814eSfvdl * are an opaque 64 bit entity, we need to provide some sort of 577f7d814eSfvdl * mapping between cookies and logical blocknumbers. Also, 587f7d814eSfvdl * we should store the cookies from the server somewhere, 597f7d814eSfvdl * to be able to satisfy VOP_READDIR requests for cookies. 607f7d814eSfvdl * We can't store the cookies in the dirent structure, as some 617f7d814eSfvdl * other systems. 627f7d814eSfvdl * 637f7d814eSfvdl * Each offset is hashed into a per-nfsnode hashtable. An entry 647f7d814eSfvdl * found therein contains information about the (faked up) 657f7d814eSfvdl * logical blocknumber, and also a pointer to a buffer where 667f7d814eSfvdl * the cookies are stored. 675ac7df1cSfvdl */ 685ac7df1cSfvdl 697f7d814eSfvdl LIST_HEAD(nfsdirhashhead, nfsdircache); 707f7d814eSfvdl TAILQ_HEAD(nfsdirchainhead, nfsdircache); 717f7d814eSfvdl 727f7d814eSfvdl struct nfsdircache { 731cf3a3dbSfvdl off_t dc_cookie; /* Own offset (key) */ 741cf3a3dbSfvdl off_t dc_blkcookie; /* Offset of block we're in */ 751cf3a3dbSfvdl LIST_ENTRY(nfsdircache) dc_hash; /* Hash chain */ 761cf3a3dbSfvdl TAILQ_ENTRY(nfsdircache) dc_chain; /* Least recently entered chn */ 77e11d5e7cSyamt u_int32_t dc_cookie32; /* Key for 64<->32 xlate case */ 781cf3a3dbSfvdl int dc_entry; /* Entry number within block */ 79e11d5e7cSyamt int dc_refcnt; /* Reference count */ 80e11d5e7cSyamt int dc_flags; /* NFSDC_ flags */ 815ac7df1cSfvdl }; 825ac7df1cSfvdl 83e11d5e7cSyamt #define NFSDC_INVALID 1 84e11d5e7cSyamt 85a9fa9f07Syamt /* 86a9fa9f07Syamt * NFSDC_BLKNO: get buffer cache index 87a9fa9f07Syamt */ 88a9fa9f07Syamt #define NFSDC_BLKNO(ndp) ((daddr_t)(ndp)->dc_blkcookie) 897f7d814eSfvdl 905ac7df1cSfvdl /* 91266a376bSmycroft * The nfsnode is the nfs equivalent to ufs's inode. Any similarity 92266a376bSmycroft * is purely coincidental. 93266a376bSmycroft * There is a unique nfsnode allocated for each active file, 94266a376bSmycroft * each current directory, each mounted-on file, text file, and the root. 95266a376bSmycroft * An nfsnode is 'named' by its file handle. (nget/nfs_node.c) 96266a376bSmycroft */ 97c819fadcSyamt 98c819fadcSyamt struct nfsnode_spec { 99c819fadcSyamt struct timespec nspec_mtim; /* local mtime */ 100c819fadcSyamt struct timespec nspec_atim; /* local atime */ 101c819fadcSyamt }; 102c819fadcSyamt 103c819fadcSyamt struct nfsnode_reg { 1046f8dc150Sandvar off_t nreg_pushedlo; /* 1st blk in committed range */ 105c819fadcSyamt off_t nreg_pushedhi; /* Last block in range */ 106c819fadcSyamt off_t nreg_pushlo; /* 1st block in commit range */ 107c819fadcSyamt off_t nreg_pushhi; /* Last block in range */ 1086d6b5c51Syamt kmutex_t nreg_commitlock; /* Serialize commits XXX */ 109c819fadcSyamt int nreg_commitflags; 110c819fadcSyamt int nreg_error; /* Save write error value */ 111c819fadcSyamt }; 112c819fadcSyamt 113c819fadcSyamt struct nfsnode_dir { 114c819fadcSyamt off_t ndir_direof; /* EOF offset cache */ 115c819fadcSyamt nfsuint64 ndir_cookieverf; /* Cookie verifier */ 116c819fadcSyamt struct nfsdirhashhead *ndir_dircache; /* offset -> cache hash heads */ 117c819fadcSyamt struct nfsdirchainhead ndir_dirchain; /* Chain of dir cookies */ 11868c07138Syamt struct timespec ndir_nctime; /* Last name cache entry */ 119c819fadcSyamt unsigned ndir_dircachesize; /* Size of dir cookie cache */ 120c819fadcSyamt }; 121c819fadcSyamt 122266a376bSmycroft struct nfsnode { 12364c6d1d2Schs struct genfs_node n_gnode; 124cde1d475Smycroft u_quad_t n_size; /* Current size of file */ 125c819fadcSyamt 1265ac7df1cSfvdl union { 127c819fadcSyamt struct nfsnode_spec nu_spec; 128c819fadcSyamt struct nfsnode_reg nu_reg; 129c819fadcSyamt struct nfsnode_dir nu_dir; 1301cf3a3dbSfvdl } n_un1; 131c819fadcSyamt 132c819fadcSyamt #define n_mtim n_un1.nu_spec.nspec_mtim 133c819fadcSyamt #define n_atim n_un1.nu_spec.nspec_atim 134c819fadcSyamt 135c819fadcSyamt #define n_pushedlo n_un1.nu_reg.nreg_pushedlo 136c819fadcSyamt #define n_pushedhi n_un1.nu_reg.nreg_pushedhi 137c819fadcSyamt #define n_pushlo n_un1.nu_reg.nreg_pushlo 138c819fadcSyamt #define n_pushhi n_un1.nu_reg.nreg_pushhi 139c819fadcSyamt #define n_commitlock n_un1.nu_reg.nreg_commitlock 140c819fadcSyamt #define n_commitflags n_un1.nu_reg.nreg_commitflags 141c819fadcSyamt #define n_error n_un1.nu_reg.nreg_error 142c819fadcSyamt 143c819fadcSyamt #define n_direofoffset n_un1.nu_dir.ndir_direof 144c819fadcSyamt #define n_cookieverf n_un1.nu_dir.ndir_cookieverf 145c819fadcSyamt #define n_dircache n_un1.nu_dir.ndir_dircache 146c819fadcSyamt #define n_dirchain n_un1.nu_dir.ndir_dirchain 147c819fadcSyamt #define n_nctime n_un1.nu_dir.ndir_nctime 148c819fadcSyamt #define n_dircachesize n_un1.nu_dir.ndir_dircachesize 149c819fadcSyamt 1501cf3a3dbSfvdl union { 151c819fadcSyamt struct sillyrename *nf_silly; /* !VDIR: silly rename struct */ 152c819fadcSyamt unsigned *ndir_dirgens; /* 32<->64bit xlate gen. no. */ 153c819fadcSyamt } n_un2; 154c819fadcSyamt 155c819fadcSyamt #define n_sillyrename n_un2.nf_silly 156c819fadcSyamt #define n_dirgens n_un2.ndir_dirgens 157c819fadcSyamt 1581cf3a3dbSfvdl nfsfh_t *n_fhp; /* NFS File Handle */ 1591cf3a3dbSfvdl struct vattr *n_vattr; /* Vnode attribute cache */ 1601cf3a3dbSfvdl struct vnode *n_vnode; /* associated vnode */ 1611cf3a3dbSfvdl struct lockf *n_lockf; /* Locking record of file */ 1621cf3a3dbSfvdl time_t n_attrstamp; /* Attr. cache timestamp */ 163c2025ab0Syamt struct timespec n_mtime; /* Prev modify time. */ 1641cf3a3dbSfvdl time_t n_ctime; /* Prev create time. */ 1655ac7df1cSfvdl short n_fhsize; /* size in bytes, of fh */ 1665ac7df1cSfvdl short n_flag; /* Flag for locking.. */ 1675ac7df1cSfvdl nfsfh_t n_fh; /* Small File Handle */ 1685a730090Sfvdl time_t n_accstamp; /* Access cache timestamp */ 1695a730090Sfvdl uid_t n_accuid; /* Last access requester */ 1705a730090Sfvdl int n_accmode; /* Mode last requested */ 1715a730090Sfvdl int n_accerror; /* Error last returned */ 172fc9422c9Selad kauth_cred_t n_rcred; 173fc9422c9Selad kauth_cred_t n_wcred; 174266a376bSmycroft }; 175266a376bSmycroft 176de98f081Sfvdl /* 177de98f081Sfvdl * Values for n_commitflags 178de98f081Sfvdl */ 179de98f081Sfvdl #define NFS_COMMIT_PUSH_VALID 0x0001 /* push range valid */ 180de98f081Sfvdl #define NFS_COMMIT_PUSHED_VALID 0x0002 /* pushed range valid */ 181de98f081Sfvdl 182cde1d475Smycroft /* 183cde1d475Smycroft * Flags for n_flag 184cde1d475Smycroft */ 185cde1d475Smycroft #define NFLUSHWANT 0x0001 /* Want wakeup from a flush in prog. */ 186cde1d475Smycroft #define NFLUSHINPROG 0x0002 /* Avoid multiple calls to vinvalbuf() */ 187cde1d475Smycroft #define NMODIFIED 0x0004 /* Might have a modified buffer in bio */ 188cde1d475Smycroft #define NWRITEERR 0x0008 /* Flag write errors so close will know */ 189cde1d475Smycroft #define NACC 0x0100 /* Special file accessed */ 190cde1d475Smycroft #define NUPD 0x0200 /* Special file updated */ 191cde1d475Smycroft #define NCHG 0x0400 /* Special file times changed */ 192e5bd47dcSyamt #define NTRUNCDELAYED 0x1000 /* Should be truncated later; 193e5bd47dcSyamt implies stale cache */ 19433164bffSyamt #define NREMOVED 0x2000 /* Has been removed */ 1954fd5a025Syamt #define NUSEOPENCRED 0x4000 /* Try open cred first rather than owner's */ 19672d6e88aSyamt #define NEOFVALID 0x8000 /* dir: n_direofoffset is valid */ 19772d6e88aSyamt 19872d6e88aSyamt #define NFS_EOFVALID(ndp) ((ndp)->n_flag & NEOFVALID) 199266a376bSmycroft 200266a376bSmycroft /* 201266a376bSmycroft * Convert between nfsnode pointers and vnode pointers 202266a376bSmycroft */ 203266a376bSmycroft #define VTONFS(vp) ((struct nfsnode *)(vp)->v_data) 204aeda8d3bSchs #define NFSTOV(np) ((np)->n_vnode) 205266a376bSmycroft 20697c7bbe6Syamt #ifdef _KERNEL 20797c7bbe6Syamt 208ed795a66Schristos #include <sys/workqueue.h> 209ed795a66Schristos /* 210ed795a66Schristos * Silly rename structure that hangs off the nfsnode until the name 211ed795a66Schristos * can be removed by nfs_inactive() 212ed795a66Schristos */ 213ed795a66Schristos struct sillyrename { 214ed795a66Schristos struct work s_work; 215ed795a66Schristos kauth_cred_t s_cred; 216ed795a66Schristos struct vnode *s_dvp; 217ed795a66Schristos long s_namlen; 218ed795a66Schristos char s_name[20]; 219ed795a66Schristos }; 220ed795a66Schristos 221266a376bSmycroft /* 2222cca2b56Syamt * Per-nfsiod datas 223cde1d475Smycroft */ 2249b96b4abSyamt struct nfs_iod { 225aca67640Syamt kmutex_t nid_lock; 226aca67640Syamt kcondvar_t nid_cv; 227c379ad65Syamt LIST_ENTRY(nfs_iod) nid_idle; 2289b96b4abSyamt struct nfsmount *nid_mount; 22997c7bbe6Syamt bool nid_exiting; 230c379ad65Syamt 231c379ad65Syamt LIST_ENTRY(nfs_iod) nid_all; 2329b96b4abSyamt }; 233cde1d475Smycroft 234c379ad65Syamt LIST_HEAD(nfs_iodlist, nfs_iod); 2358e473ee7Syamt extern kmutex_t nfs_iodlist_lock; 236c379ad65Syamt extern struct nfs_iodlist nfs_iodlist_idle; 237c379ad65Syamt extern struct nfs_iodlist nfs_iodlist_all; 2380a3d351aSchristos extern u_long nfsdirhashmask; 2390a3d351aSchristos 240cde1d475Smycroft /* 241266a376bSmycroft * Prototypes for NFS vnode operations 242266a376bSmycroft */ 24302cdf4d2Sdsl int nfs_lookup(void *); 24402cdf4d2Sdsl int nfs_create(void *); 24502cdf4d2Sdsl int nfs_mknod(void *); 24602cdf4d2Sdsl int nfs_open(void *); 24702cdf4d2Sdsl int nfs_close(void *); 24802cdf4d2Sdsl int nfsspec_close(void *); 24902cdf4d2Sdsl int nfsfifo_close(void *); 25002cdf4d2Sdsl int nfs_access(void *); 25102cdf4d2Sdsl int nfsspec_access(void *); 25202cdf4d2Sdsl int nfs_getattr(void *); 25302cdf4d2Sdsl int nfs_setattr(void *); 25402cdf4d2Sdsl int nfs_read(void *); 25502cdf4d2Sdsl int nfs_write(void *); 25602cdf4d2Sdsl int nfsspec_read(void *); 25702cdf4d2Sdsl int nfsspec_write(void *); 25802cdf4d2Sdsl int nfsfifo_read(void *); 25902cdf4d2Sdsl int nfsfifo_write(void *); 26002cdf4d2Sdsl int nfs_fsync(void *); 26102cdf4d2Sdsl int nfs_remove(void *); 26202cdf4d2Sdsl int nfs_link(void *); 26302cdf4d2Sdsl int nfs_rename(void *); 26402cdf4d2Sdsl int nfs_mkdir(void *); 26502cdf4d2Sdsl int nfs_rmdir(void *); 26602cdf4d2Sdsl int nfs_symlink(void *); 26702cdf4d2Sdsl int nfs_readdir(void *); 26802cdf4d2Sdsl int nfs_readlink(void *); 26902cdf4d2Sdsl int nfs_inactive(void *); 27002cdf4d2Sdsl int nfs_reclaim(void *); 27102cdf4d2Sdsl int nfs_unlock(void *); 27202cdf4d2Sdsl int nfs_bmap(void *); 27302cdf4d2Sdsl int nfs_strategy(void *); 27402cdf4d2Sdsl int nfs_print(void *); 27502cdf4d2Sdsl int nfs_pathconf(void *); 27602cdf4d2Sdsl int nfs_advlock(void *); 27702cdf4d2Sdsl int nfs_getpages(void *); 27802cdf4d2Sdsl int nfs_kqfilter(void *); 2795ac7df1cSfvdl 28002cdf4d2Sdsl extern int (**nfsv2_vnodeop_p)(void *); 281e4c93ec8Schristos 282a4cbf5b0Syamt #define NFS_INVALIDATE_ATTRCACHE(np) (np)->n_attrstamp = 0 283a4cbf5b0Syamt 284f76f1f89Sjtc #endif /* _KERNEL */ 2855ac7df1cSfvdl 286*13230298Sriastradh #endif /* _NFS_NFSNODE_H_ */ 287