1 /*         $NetBSD: nfsnode.h,v 1.77 2024/12/07 02:05:55 riastradh Exp $        */
2 
3 /*
4  * Copyright (c) 1989, 1993
5  *        The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Rick Macklem at The University of Guelph.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  *
34  *        @(#)nfsnode.h       8.9 (Berkeley) 5/14/95
35  */
36 
37 
38 #ifndef _NFS_NFSNODE_H_
39 #define   _NFS_NFSNODE_H_
40 
41 #include <sys/types.h>
42 
43 #include <sys/condvar.h>
44 #include <sys/mutex.h>
45 #include <sys/queue.h>
46 #include <sys/timespec.h>
47 
48 #include <nfs/nfs.h>
49 #include <nfs/nfsproto.h>
50 
51 #include <miscfs/genfs/genfs.h>
52 #include <miscfs/genfs/genfs_node.h>
53 
54 /*
55  * Definitions for the directory cache. Because directory cookies
56  * are an opaque 64 bit entity, we need to provide some sort of
57  * mapping between cookies and logical blocknumbers. Also,
58  * we should store the cookies from the server somewhere,
59  * to be able to satisfy VOP_READDIR requests for cookies.
60  * We can't store the cookies in the dirent structure, as some
61  * other systems.
62  *
63  * Each offset is hashed into a per-nfsnode hashtable. An entry
64  * found therein contains information about the (faked up)
65  * logical blocknumber, and also a pointer to a buffer where
66  * the cookies are stored.
67  */
68 
69 LIST_HEAD(nfsdirhashhead, nfsdircache);
70 TAILQ_HEAD(nfsdirchainhead, nfsdircache);
71 
72 struct nfsdircache {
73           off_t               dc_cookie;                    /* Own offset (key) */
74           off_t               dc_blkcookie;                 /* Offset of block we're in */
75           LIST_ENTRY(nfsdircache) dc_hash;        /* Hash chain */
76           TAILQ_ENTRY(nfsdircache) dc_chain;      /* Least recently entered chn */
77           u_int32_t dc_cookie32;                  /* Key for 64<->32 xlate case */
78           int                 dc_entry;           /* Entry number within block */
79           int                 dc_refcnt;                    /* Reference count */
80           int                 dc_flags;           /* NFSDC_ flags */
81 };
82 
83 #define   NFSDC_INVALID       1
84 
85 /*
86  * NFSDC_BLKNO: get buffer cache index
87  */
88 #define   NFSDC_BLKNO(ndp)    ((daddr_t)(ndp)->dc_blkcookie)
89 
90 /*
91  * The nfsnode is the nfs equivalent to ufs's inode. Any similarity
92  * is purely coincidental.
93  * There is a unique nfsnode allocated for each active file,
94  * each current directory, each mounted-on file, text file, and the root.
95  * An nfsnode is 'named' by its file handle. (nget/nfs_node.c)
96  */
97 
98 struct nfsnode_spec {
99           struct timespec     nspec_mtim;         /* local mtime */
100           struct timespec     nspec_atim;         /* local atime */
101 };
102 
103 struct nfsnode_reg {
104           off_t nreg_pushedlo;                    /* 1st blk in committed range */
105           off_t nreg_pushedhi;                    /* Last block in range */
106           off_t nreg_pushlo;            /* 1st block in commit range */
107           off_t nreg_pushhi;            /* Last block in range */
108           kmutex_t nreg_commitlock;     /* Serialize commits XXX */
109           int nreg_commitflags;
110           int nreg_error;                         /* Save write error value */
111 };
112 
113 struct nfsnode_dir {
114           off_t ndir_direof;            /* EOF offset cache */
115           nfsuint64 ndir_cookieverf;    /* Cookie verifier */
116           struct nfsdirhashhead *ndir_dircache; /* offset -> cache hash heads */
117           struct nfsdirchainhead ndir_dirchain; /* Chain of dir cookies */
118           struct timespec ndir_nctime;  /* Last name cache entry */
119           unsigned ndir_dircachesize;   /* Size of dir cookie cache */
120 };
121 
122 struct nfsnode {
123           struct genfs_node   n_gnode;
124           u_quad_t            n_size;             /* Current size of file */
125 
126           union {
127                     struct nfsnode_spec nu_spec;
128                     struct nfsnode_reg  nu_reg;
129                     struct nfsnode_dir  nu_dir;
130           } n_un1;
131 
132 #define n_mtim                n_un1.nu_spec.nspec_mtim
133 #define n_atim                n_un1.nu_spec.nspec_atim
134 
135 #define   n_pushedlo          n_un1.nu_reg.nreg_pushedlo
136 #define   n_pushedhi          n_un1.nu_reg.nreg_pushedhi
137 #define   n_pushlo  n_un1.nu_reg.nreg_pushlo
138 #define   n_pushhi  n_un1.nu_reg.nreg_pushhi
139 #define n_commitlock          n_un1.nu_reg.nreg_commitlock
140 #define n_commitflags         n_un1.nu_reg.nreg_commitflags
141 #define n_error               n_un1.nu_reg.nreg_error
142 
143 #define n_direofoffset        n_un1.nu_dir.ndir_direof
144 #define n_cookieverf          n_un1.nu_dir.ndir_cookieverf
145 #define n_dircache  n_un1.nu_dir.ndir_dircache
146 #define   n_dirchain          n_un1.nu_dir.ndir_dirchain
147 #define   n_nctime  n_un1.nu_dir.ndir_nctime
148 #define   n_dircachesize      n_un1.nu_dir.ndir_dircachesize
149 
150           union {
151                     struct sillyrename *nf_silly; /* !VDIR: silly rename struct */
152                     unsigned *ndir_dirgens;                 /* 32<->64bit xlate gen. no. */
153           } n_un2;
154 
155 #define n_sillyrename         n_un2.nf_silly
156 #define n_dirgens   n_un2.ndir_dirgens
157 
158           nfsfh_t                       *n_fhp;             /* NFS File Handle */
159           struct vattr                  *n_vattr; /* Vnode attribute cache */
160           struct vnode                  *n_vnode; /* associated vnode */
161           struct lockf                  *n_lockf; /* Locking record of file */
162           time_t                        n_attrstamp;        /* Attr. cache timestamp */
163           struct timespec               n_mtime;  /* Prev modify time. */
164           time_t                        n_ctime;  /* Prev create time. */
165           short                         n_fhsize; /* size in bytes, of fh */
166           short                         n_flag;             /* Flag for locking.. */
167           nfsfh_t                       n_fh;               /* Small File Handle */
168           time_t                        n_accstamp;         /* Access cache timestamp */
169           uid_t                         n_accuid; /* Last access requester */
170           int                           n_accmode;          /* Mode last requested */
171           int                           n_accerror;         /* Error last returned */
172           kauth_cred_t                  n_rcred;
173           kauth_cred_t                  n_wcred;
174 };
175 
176 /*
177  * Values for n_commitflags
178  */
179 #define NFS_COMMIT_PUSH_VALID 0x0001              /* push range valid */
180 #define NFS_COMMIT_PUSHED_VALID         0x0002              /* pushed range valid */
181 
182 /*
183  * Flags for n_flag
184  */
185 #define   NFLUSHWANT          0x0001    /* Want wakeup from a flush in prog. */
186 #define   NFLUSHINPROG        0x0002    /* Avoid multiple calls to vinvalbuf() */
187 #define   NMODIFIED 0x0004    /* Might have a modified buffer in bio */
188 #define   NWRITEERR 0x0008    /* Flag write errors so close will know */
189 #define   NACC                0x0100    /* Special file accessed */
190 #define   NUPD                0x0200    /* Special file updated */
191 #define   NCHG                0x0400    /* Special file times changed */
192 #define   NTRUNCDELAYED       0x1000    /* Should be truncated later;
193                                            implies stale cache */
194 #define   NREMOVED  0x2000    /* Has been removed */
195 #define   NUSEOPENCRED        0x4000    /* Try open cred first rather than owner's */
196 #define   NEOFVALID 0x8000    /* dir: n_direofoffset is valid */
197 
198 #define   NFS_EOFVALID(ndp)   ((ndp)->n_flag & NEOFVALID)
199 
200 /*
201  * Convert between nfsnode pointers and vnode pointers
202  */
203 #define VTONFS(vp)  ((struct nfsnode *)(vp)->v_data)
204 #define NFSTOV(np)  ((np)->n_vnode)
205 
206 #ifdef _KERNEL
207 
208 #include <sys/workqueue.h>
209 /*
210  * Silly rename structure that hangs off the nfsnode until the name
211  * can be removed by nfs_inactive()
212  */
213 struct sillyrename {
214           struct work         s_work;
215           kauth_cred_t        s_cred;
216           struct    vnode *s_dvp;
217           long      s_namlen;
218           char      s_name[20];
219 };
220 
221 /*
222  * Per-nfsiod datas
223  */
224 struct nfs_iod {
225           kmutex_t nid_lock;
226           kcondvar_t nid_cv;
227           LIST_ENTRY(nfs_iod) nid_idle;
228           struct nfsmount *nid_mount;
229           bool nid_exiting;
230 
231           LIST_ENTRY(nfs_iod) nid_all;
232 };
233 
234 LIST_HEAD(nfs_iodlist, nfs_iod);
235 extern kmutex_t nfs_iodlist_lock;
236 extern struct nfs_iodlist nfs_iodlist_idle;
237 extern struct nfs_iodlist nfs_iodlist_all;
238 extern u_long nfsdirhashmask;
239 
240 /*
241  * Prototypes for NFS vnode operations
242  */
243 int       nfs_lookup(void *);
244 int       nfs_create(void *);
245 int       nfs_mknod(void *);
246 int       nfs_open(void *);
247 int       nfs_close(void *);
248 int       nfsspec_close(void *);
249 int       nfsfifo_close(void *);
250 int       nfs_access(void *);
251 int       nfsspec_access(void *);
252 int       nfs_getattr(void *);
253 int       nfs_setattr(void *);
254 int       nfs_read(void *);
255 int       nfs_write(void *);
256 int       nfsspec_read(void *);
257 int       nfsspec_write(void *);
258 int       nfsfifo_read(void *);
259 int       nfsfifo_write(void *);
260 int       nfs_fsync(void *);
261 int       nfs_remove(void *);
262 int       nfs_link(void *);
263 int       nfs_rename(void *);
264 int       nfs_mkdir(void *);
265 int       nfs_rmdir(void *);
266 int       nfs_symlink(void *);
267 int       nfs_readdir(void *);
268 int       nfs_readlink(void *);
269 int       nfs_inactive(void *);
270 int       nfs_reclaim(void *);
271 int       nfs_unlock(void *);
272 int       nfs_bmap(void *);
273 int       nfs_strategy(void *);
274 int       nfs_print(void *);
275 int       nfs_pathconf(void *);
276 int       nfs_advlock(void *);
277 int       nfs_getpages(void *);
278 int       nfs_kqfilter(void *);
279 
280 extern int (**nfsv2_vnodeop_p)(void *);
281 
282 #define   NFS_INVALIDATE_ATTRCACHE(np)  (np)->n_attrstamp = 0
283 
284 #endif /* _KERNEL */
285 
286 #endif    /* _NFS_NFSNODE_H_ */
287