Fri Jan 2 12:57:30 2009 UTC ()
- Don't vput() a vnode that we do not hold locked.
- Eliminate one of the few remaining uses of LK_CANRECURSE.


(ad)
diff -r1.107 -r1.108 src/sys/nfs/nfs_node.c
diff -r1.68 -r1.69 src/sys/nfs/nfsnode.h

cvs diff -r1.107 -r1.108 src/sys/nfs/nfs_node.c (switch to unified diff)

--- src/sys/nfs/nfs_node.c 2008/11/19 18:36:09 1.107
+++ src/sys/nfs/nfs_node.c 2009/01/02 12:57:29 1.108
@@ -1,376 +1,389 @@ @@ -1,376 +1,389 @@
1/* $NetBSD: nfs_node.c,v 1.107 2008/11/19 18:36:09 ad Exp $ */ 1/* $NetBSD: nfs_node.c,v 1.108 2009/01/02 12:57:29 ad Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1993 4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph. 8 * Rick Macklem at The University of Guelph.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors 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 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 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 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 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 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 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 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * @(#)nfs_node.c 8.6 (Berkeley) 5/22/95 34 * @(#)nfs_node.c 8.6 (Berkeley) 5/22/95
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.107 2008/11/19 18:36:09 ad Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.108 2009/01/02 12:57:29 ad Exp $");
39 39
40#ifdef _KERNEL_OPT 40#ifdef _KERNEL_OPT
41#include "opt_nfs.h" 41#include "opt_nfs.h"
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/proc.h> 46#include <sys/proc.h>
47#include <sys/mount.h> 47#include <sys/mount.h>
48#include <sys/namei.h> 48#include <sys/namei.h>
49#include <sys/vnode.h> 49#include <sys/vnode.h>
50#include <sys/kernel.h> 50#include <sys/kernel.h>
51#include <sys/pool.h> 51#include <sys/pool.h>
52#include <sys/lock.h> 52#include <sys/lock.h>
53#include <sys/hash.h> 53#include <sys/hash.h>
54#include <sys/kauth.h> 54#include <sys/kauth.h>
55 55
56#include <nfs/rpcv2.h> 56#include <nfs/rpcv2.h>
57#include <nfs/nfsproto.h> 57#include <nfs/nfsproto.h>
58#include <nfs/nfs.h> 58#include <nfs/nfs.h>
59#include <nfs/nfsnode.h> 59#include <nfs/nfsnode.h>
60#include <nfs/nfsmount.h> 60#include <nfs/nfsmount.h>
61#include <nfs/nfs_var.h> 61#include <nfs/nfs_var.h>
62 62
63struct pool nfs_node_pool; 63struct pool nfs_node_pool;
64struct pool nfs_vattr_pool; 64struct pool nfs_vattr_pool;
65 65static struct workqueue *nfs_sillyworkq;
66MALLOC_JUSTDEFINE(M_NFSNODE, "NFS node", "NFS vnode private part"); 
67 66
68extern int prtactive; 67extern int prtactive;
69 68
70void nfs_gop_size(struct vnode *, off_t, off_t *, int); 69static void nfs_gop_size(struct vnode *, off_t, off_t *, int);
71int nfs_gop_alloc(struct vnode *, off_t, off_t, int, kauth_cred_t); 70static int nfs_gop_alloc(struct vnode *, off_t, off_t, int, kauth_cred_t);
72int nfs_gop_write(struct vnode *, struct vm_page **, int, int); 71static int nfs_gop_write(struct vnode *, struct vm_page **, int, int);
 72static void nfs_sillyworker(struct work *, void *);
73 73
74static const struct genfs_ops nfs_genfsops = { 74static const struct genfs_ops nfs_genfsops = {
75 .gop_size = nfs_gop_size, 75 .gop_size = nfs_gop_size,
76 .gop_alloc = nfs_gop_alloc, 76 .gop_alloc = nfs_gop_alloc,
77 .gop_write = nfs_gop_write, 77 .gop_write = nfs_gop_write,
78}; 78};
79 79
80/* 80/*
81 * Reinitialize inode hash table. 81 * Reinitialize inode hash table.
82 */ 82 */
83void 83void
84nfs_node_init() 84nfs_node_init()
85{ 85{
86 malloc_type_attach(M_NFSNODE); 86
87 pool_init(&nfs_node_pool, sizeof(struct nfsnode), 0, 0, 0, "nfsnodepl", 87 pool_init(&nfs_node_pool, sizeof(struct nfsnode), 0, 0, 0, "nfsnodepl",
88 &pool_allocator_nointr, IPL_NONE); 88 &pool_allocator_nointr, IPL_NONE);
89 pool_init(&nfs_vattr_pool, sizeof(struct vattr), 0, 0, 0, "nfsvapl", 89 pool_init(&nfs_vattr_pool, sizeof(struct vattr), 0, 0, 0, "nfsvapl",
90 &pool_allocator_nointr, IPL_NONE); 90 &pool_allocator_nointr, IPL_NONE);
 91 if (workqueue_create(&nfs_sillyworkq, "nfssilly", nfs_sillyworker,
 92 NULL, PRI_NONE, IPL_NONE, 0) != 0) {
 93 panic("nfs_node_init");
 94 }
91} 95}
92 96
93/* 97/*
94 * Free resources previously allocated in nfs_node_reinit(). 98 * Free resources previously allocated in nfs_node_reinit().
95 */ 99 */
96void 100void
97nfs_node_done() 101nfs_node_done()
98{ 102{
 103
99 pool_destroy(&nfs_node_pool); 104 pool_destroy(&nfs_node_pool);
100 pool_destroy(&nfs_vattr_pool); 105 pool_destroy(&nfs_vattr_pool);
101 malloc_type_detach(M_NFSNODE); 106 workqueue_destroy(nfs_sillyworkq);
102} 107}
103 108
104#define RBTONFSNODE(node) \ 109#define RBTONFSNODE(node) \
105 (void *)((uintptr_t)(node) - offsetof(struct nfsnode, n_rbnode)) 110 (void *)((uintptr_t)(node) - offsetof(struct nfsnode, n_rbnode))
106 111
107struct fh_match { 112struct fh_match {
108 nfsfh_t *fhm_fhp; 113 nfsfh_t *fhm_fhp;
109 size_t fhm_fhsize; 114 size_t fhm_fhsize;
110 size_t fhm_fhoffset; 115 size_t fhm_fhoffset;
111}; 116};
112 117
113static int 118static int
114nfs_compare_nodes(const struct rb_node *parent, const struct rb_node *node) 119nfs_compare_nodes(const struct rb_node *parent, const struct rb_node *node)
115{ 120{
116 const struct nfsnode * const pnp = RBTONFSNODE(parent); 121 const struct nfsnode * const pnp = RBTONFSNODE(parent);
117 const struct nfsnode * const np = RBTONFSNODE(node); 122 const struct nfsnode * const np = RBTONFSNODE(node);
118 123
119 if (pnp->n_fhsize != np->n_fhsize) 124 if (pnp->n_fhsize != np->n_fhsize)
120 return np->n_fhsize - pnp->n_fhsize; 125 return np->n_fhsize - pnp->n_fhsize;
121 126
122 return memcmp(np->n_fhp, pnp->n_fhp, np->n_fhsize); 127 return memcmp(np->n_fhp, pnp->n_fhp, np->n_fhsize);
123} 128}
124 129
125static int 130static int
126nfs_compare_node_fh(const struct rb_node *b, const void *key) 131nfs_compare_node_fh(const struct rb_node *b, const void *key)
127{ 132{
128 const struct nfsnode * const pnp = RBTONFSNODE(b); 133 const struct nfsnode * const pnp = RBTONFSNODE(b);
129 const struct fh_match * const fhm = key; 134 const struct fh_match * const fhm = key;
130 135
131 if (pnp->n_fhsize != fhm->fhm_fhsize) 136 if (pnp->n_fhsize != fhm->fhm_fhsize)
132 return fhm->fhm_fhsize - pnp->n_fhsize; 137 return fhm->fhm_fhsize - pnp->n_fhsize;
133 138
134 return memcmp(fhm->fhm_fhp, pnp->n_fhp, pnp->n_fhsize); 139 return memcmp(fhm->fhm_fhp, pnp->n_fhp, pnp->n_fhsize);
135} 140}
136 141
137static const struct rb_tree_ops nfs_node_rbtree_ops = { 142static const struct rb_tree_ops nfs_node_rbtree_ops = {
138 .rbto_compare_nodes = nfs_compare_nodes, 143 .rbto_compare_nodes = nfs_compare_nodes,
139 .rbto_compare_key = nfs_compare_node_fh, 144 .rbto_compare_key = nfs_compare_node_fh,
140}; 145};
141 146
142void 147void
143nfs_rbtinit(struct nfsmount *nmp) 148nfs_rbtinit(struct nfsmount *nmp)
144{ 149{
145 rb_tree_init(&nmp->nm_rbtree, &nfs_node_rbtree_ops); 150 rb_tree_init(&nmp->nm_rbtree, &nfs_node_rbtree_ops);
146} 151}
147 152
148 153
149/* 154/*
150 * Look up a vnode/nfsnode by file handle. 155 * Look up a vnode/nfsnode by file handle.
151 * Callers must check for mount points!! 156 * Callers must check for mount points!!
152 * In all cases, a pointer to a 157 * In all cases, a pointer to a
153 * nfsnode structure is returned. 158 * nfsnode structure is returned.
154 */ 159 */
155int 160int
156nfs_nget1(mntp, fhp, fhsize, npp, lkflags) 161nfs_nget1(mntp, fhp, fhsize, npp, lkflags)
157 struct mount *mntp; 162 struct mount *mntp;
158 nfsfh_t *fhp; 163 nfsfh_t *fhp;
159 int fhsize; 164 int fhsize;
160 struct nfsnode **npp; 165 struct nfsnode **npp;
161 int lkflags; 166 int lkflags;
162{ 167{
163 struct nfsnode *np; 168 struct nfsnode *np;
164 struct vnode *vp; 169 struct vnode *vp;
165 struct nfsmount *nmp = VFSTONFS(mntp); 170 struct nfsmount *nmp = VFSTONFS(mntp);
166 int error; 171 int error;
167 struct fh_match fhm; 172 struct fh_match fhm;
168 struct rb_node *node; 173 struct rb_node *node;
169 174
170 fhm.fhm_fhp = fhp; 175 fhm.fhm_fhp = fhp;
171 fhm.fhm_fhsize = fhsize; 176 fhm.fhm_fhsize = fhsize;
172 177
173loop: 178loop:
174 rw_enter(&nmp->nm_rbtlock, RW_READER); 179 rw_enter(&nmp->nm_rbtlock, RW_READER);
175 node = rb_tree_find_node(&nmp->nm_rbtree, &fhm); 180 node = rb_tree_find_node(&nmp->nm_rbtree, &fhm);
176 if (node != NULL) { 181 if (node != NULL) {
177 np = RBTONFSNODE(node); 182 np = RBTONFSNODE(node);
178 vp = NFSTOV(np); 183 vp = NFSTOV(np);
179 mutex_enter(&vp->v_interlock); 184 mutex_enter(&vp->v_interlock);
180 rw_exit(&nmp->nm_rbtlock); 185 rw_exit(&nmp->nm_rbtlock);
181 error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK | lkflags); 186 error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK | lkflags);
182 if (error == EBUSY) 187 if (error == EBUSY)
183 return error; 188 return error;
184 if (error) 189 if (error)
185 goto loop; 190 goto loop;
186 *npp = np; 191 *npp = np;
187 return(0); 192 return(0);
188 } 193 }
189 rw_exit(&nmp->nm_rbtlock); 194 rw_exit(&nmp->nm_rbtlock);
190 195
191 error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &vp); 196 error = getnewvnode(VT_NFS, mntp, nfsv2_vnodeop_p, &vp);
192 if (error) { 197 if (error) {
193 *npp = 0; 198 *npp = 0;
194 return (error); 199 return (error);
195 } 200 }
196 np = pool_get(&nfs_node_pool, PR_WAITOK); 201 np = pool_get(&nfs_node_pool, PR_WAITOK);
197 memset(np, 0, sizeof *np); 202 memset(np, 0, sizeof *np);
198 np->n_vnode = vp; 203 np->n_vnode = vp;
199 204
200 /* 205 /*
201 * Insert the nfsnode in the hash queue for its new file handle 206 * Insert the nfsnode in the hash queue for its new file handle
202 */ 207 */
203 208
204 if (fhsize > NFS_SMALLFH) { 209 if (fhsize > NFS_SMALLFH) {
205 np->n_fhp = kmem_alloc(fhsize, KM_SLEEP); 210 np->n_fhp = kmem_alloc(fhsize, KM_SLEEP);
206 } else 211 } else
207 np->n_fhp = &np->n_fh; 212 np->n_fhp = &np->n_fh;
208 memcpy(np->n_fhp, fhp, fhsize); 213 memcpy(np->n_fhp, fhp, fhsize);
209 np->n_fhsize = fhsize; 214 np->n_fhsize = fhsize;
210 np->n_accstamp = -1; 215 np->n_accstamp = -1;
211 np->n_vattr = pool_get(&nfs_vattr_pool, PR_WAITOK); 216 np->n_vattr = pool_get(&nfs_vattr_pool, PR_WAITOK);
212 217
213 rw_enter(&nmp->nm_rbtlock, RW_WRITER); 218 rw_enter(&nmp->nm_rbtlock, RW_WRITER);
214 if (NULL != rb_tree_find_node(&nmp->nm_rbtree, &fhm)) { 219 if (NULL != rb_tree_find_node(&nmp->nm_rbtree, &fhm)) {
215 rw_exit(&nmp->nm_rbtlock); 220 rw_exit(&nmp->nm_rbtlock);
216 if (fhsize > NFS_SMALLFH) { 221 if (fhsize > NFS_SMALLFH) {
217 kmem_free(np->n_fhp, fhsize); 222 kmem_free(np->n_fhp, fhsize);
218 } 223 }
219 pool_put(&nfs_vattr_pool, np->n_vattr); 224 pool_put(&nfs_vattr_pool, np->n_vattr);
220 pool_put(&nfs_node_pool, np); 225 pool_put(&nfs_node_pool, np);
221 ungetnewvnode(vp); 226 ungetnewvnode(vp);
222 goto loop; 227 goto loop;
223 } 228 }
224 vp->v_data = np; 229 vp->v_data = np;
225 genfs_node_init(vp, &nfs_genfsops); 230 genfs_node_init(vp, &nfs_genfsops);
226 /* 231 /*
227 * Initalize read/write creds to useful values. VOP_OPEN will 232 * Initalize read/write creds to useful values. VOP_OPEN will
228 * overwrite these. 233 * overwrite these.
229 */ 234 */
230 np->n_rcred = curlwp->l_cred; 235 np->n_rcred = curlwp->l_cred;
231 kauth_cred_hold(np->n_rcred); 236 kauth_cred_hold(np->n_rcred);
232 np->n_wcred = curlwp->l_cred; 237 np->n_wcred = curlwp->l_cred;
233 kauth_cred_hold(np->n_wcred); 238 kauth_cred_hold(np->n_wcred);
234 vlockmgr(&vp->v_lock, LK_EXCLUSIVE); 239 vlockmgr(&vp->v_lock, LK_EXCLUSIVE);
235 NFS_INVALIDATE_ATTRCACHE(np); 240 NFS_INVALIDATE_ATTRCACHE(np);
236 uvm_vnp_setsize(vp, 0); 241 uvm_vnp_setsize(vp, 0);
237 rb_tree_insert_node(&nmp->nm_rbtree, &np->n_rbnode); 242 rb_tree_insert_node(&nmp->nm_rbtree, &np->n_rbnode);
238 rw_exit(&nmp->nm_rbtlock); 243 rw_exit(&nmp->nm_rbtlock);
239 244
240 *npp = np; 245 *npp = np;
241 return (0); 246 return (0);
242} 247}
243 248
244int 249int
245nfs_inactive(v) 250nfs_inactive(v)
246 void *v; 251 void *v;
247{ 252{
248 struct vop_inactive_args /* { 253 struct vop_inactive_args /* {
249 struct vnode *a_vp; 254 struct vnode *a_vp;
250 bool *a_recycle; 255 bool *a_recycle;
251 } */ *ap = v; 256 } */ *ap = v;
252 struct nfsnode *np; 257 struct nfsnode *np;
253 struct sillyrename *sp; 258 struct sillyrename *sp;
254 struct vnode *vp = ap->a_vp; 259 struct vnode *vp = ap->a_vp;
255 260
256 np = VTONFS(vp); 261 np = VTONFS(vp);
257 if (vp->v_type != VDIR) { 262 if (vp->v_type != VDIR) {
258 sp = np->n_sillyrename; 263 sp = np->n_sillyrename;
259 np->n_sillyrename = (struct sillyrename *)0; 264 np->n_sillyrename = (struct sillyrename *)0;
260 } else 265 } else
261 sp = NULL; 266 sp = NULL;
262 if (sp != NULL) 267 if (sp != NULL)
263 nfs_vinvalbuf(vp, 0, sp->s_cred, curlwp, 1); 268 nfs_vinvalbuf(vp, 0, sp->s_cred, curlwp, 1);
264 *ap->a_recycle = (np->n_flag & NREMOVED) != 0; 269 *ap->a_recycle = (np->n_flag & NREMOVED) != 0;
265 np->n_flag &= 270 np->n_flag &=
266 (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NEOFVALID | NTRUNCDELAYED); 271 (NMODIFIED | NFLUSHINPROG | NFLUSHWANT | NEOFVALID | NTRUNCDELAYED);
267 272
268 if (vp->v_type == VDIR && np->n_dircache) 273 if (vp->v_type == VDIR && np->n_dircache)
269 nfs_invaldircache(vp, 274 nfs_invaldircache(vp,
270 NFS_INVALDIRCACHE_FORCE | NFS_INVALDIRCACHE_KEEPEOF); 275 NFS_INVALDIRCACHE_FORCE | NFS_INVALDIRCACHE_KEEPEOF);
271 276
272 VOP_UNLOCK(vp, 0); 277 VOP_UNLOCK(vp, 0);
273 278
274 if (sp != NULL) { 279 if (sp != NULL) {
275 int error; 280 workqueue_enqueue(nfs_sillyworkq, &sp->s_work, NULL);
276 
277 /* 
278 * Remove the silly file that was rename'd earlier 
279 * 
280 * Just in case our thread also has the parent node locked, 
281 * we use LK_CANRECURSE. 
282 */ 
283 
284 error = vn_lock(sp->s_dvp, LK_EXCLUSIVE | LK_CANRECURSE); 
285 if (error || sp->s_dvp->v_data == NULL) { 
286 /* XXX should recover */ 
287 printf("%s: vp=%p error=%d\n", 
288 __func__, sp->s_dvp, error); 
289 } else { 
290 nfs_removeit(sp); 
291 } 
292 kauth_cred_free(sp->s_cred); 
293 vput(sp->s_dvp); 
294 kmem_free(sp, sizeof(*sp)); 
295 } 281 }
296 282
297 return (0); 283 return (0);
298} 284}
299 285
300/* 286/*
301 * Reclaim an nfsnode so that it can be used for other purposes. 287 * Reclaim an nfsnode so that it can be used for other purposes.
302 */ 288 */
303int 289int
304nfs_reclaim(v) 290nfs_reclaim(v)
305 void *v; 291 void *v;
306{ 292{
307 struct vop_reclaim_args /* { 293 struct vop_reclaim_args /* {
308 struct vnode *a_vp; 294 struct vnode *a_vp;
309 } */ *ap = v; 295 } */ *ap = v;
310 struct vnode *vp = ap->a_vp; 296 struct vnode *vp = ap->a_vp;
311 struct nfsnode *np = VTONFS(vp); 297 struct nfsnode *np = VTONFS(vp);
312 struct nfsmount *nmp = VFSTONFS(vp->v_mount); 298 struct nfsmount *nmp = VFSTONFS(vp->v_mount);
313 299
314 if (prtactive && vp->v_usecount > 1) 300 if (prtactive && vp->v_usecount > 1)
315 vprint("nfs_reclaim: pushing active", vp); 301 vprint("nfs_reclaim: pushing active", vp);
316 302
317 rw_enter(&nmp->nm_rbtlock, RW_WRITER); 303 rw_enter(&nmp->nm_rbtlock, RW_WRITER);
318 rb_tree_remove_node(&nmp->nm_rbtree, &np->n_rbnode); 304 rb_tree_remove_node(&nmp->nm_rbtree, &np->n_rbnode);
319 rw_exit(&nmp->nm_rbtlock); 305 rw_exit(&nmp->nm_rbtlock);
320 306
321 /* 307 /*
322 * Free up any directory cookie structures and 308 * Free up any directory cookie structures and
323 * large file handle structures that might be associated with 309 * large file handle structures that might be associated with
324 * this nfs node. 310 * this nfs node.
325 */ 311 */
326 if (vp->v_type == VDIR && np->n_dircache != NULL) { 312 if (vp->v_type == VDIR && np->n_dircache != NULL) {
327 nfs_invaldircache(vp, NFS_INVALDIRCACHE_FORCE); 313 nfs_invaldircache(vp, NFS_INVALDIRCACHE_FORCE);
328 hashdone(np->n_dircache, HASH_LIST, nfsdirhashmask); 314 hashdone(np->n_dircache, HASH_LIST, nfsdirhashmask);
329 } 315 }
330 KASSERT(np->n_dirgens == NULL); 316 KASSERT(np->n_dirgens == NULL);
331 317
332 if (np->n_fhsize > NFS_SMALLFH) 318 if (np->n_fhsize > NFS_SMALLFH)
333 kmem_free(np->n_fhp, np->n_fhsize); 319 kmem_free(np->n_fhp, np->n_fhsize);
334 320
335 pool_put(&nfs_vattr_pool, np->n_vattr); 321 pool_put(&nfs_vattr_pool, np->n_vattr);
336 if (np->n_rcred) 322 if (np->n_rcred)
337 kauth_cred_free(np->n_rcred); 323 kauth_cred_free(np->n_rcred);
338 324
339 if (np->n_wcred) 325 if (np->n_wcred)
340 kauth_cred_free(np->n_wcred); 326 kauth_cred_free(np->n_wcred);
341 327
342 cache_purge(vp); 328 cache_purge(vp);
343 if (vp->v_type == VREG) { 329 if (vp->v_type == VREG) {
344 mutex_destroy(&np->n_commitlock); 330 mutex_destroy(&np->n_commitlock);
345 } 331 }
346 genfs_node_destroy(vp); 332 genfs_node_destroy(vp);
347 pool_put(&nfs_node_pool, np); 333 pool_put(&nfs_node_pool, np);
348 vp->v_data = NULL; 334 vp->v_data = NULL;
349 return (0); 335 return (0);
350} 336}
351 337
352void 338void
353nfs_gop_size(struct vnode *vp, off_t size, off_t *eobp, int flags) 339nfs_gop_size(struct vnode *vp, off_t size, off_t *eobp, int flags)
354{ 340{
355 341
356 *eobp = MAX(size, vp->v_size); 342 *eobp = MAX(size, vp->v_size);
357} 343}
358 344
359int 345int
360nfs_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags, 346nfs_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags,
361 kauth_cred_t cred) 347 kauth_cred_t cred)
362{ 348{
363 349
364 return 0; 350 return 0;
365} 351}
366 352
367int 353int
368nfs_gop_write(struct vnode *vp, struct vm_page **pgs, int npages, int flags) 354nfs_gop_write(struct vnode *vp, struct vm_page **pgs, int npages, int flags)
369{ 355{
370 int i; 356 int i;
371 357
372 for (i = 0; i < npages; i++) { 358 for (i = 0; i < npages; i++) {
373 pmap_page_protect(pgs[i], VM_PROT_READ); 359 pmap_page_protect(pgs[i], VM_PROT_READ);
374 } 360 }
375 return genfs_gop_write(vp, pgs, npages, flags); 361 return genfs_gop_write(vp, pgs, npages, flags);
376} 362}
 363
 364/*
 365 * Remove a silly file that was rename'd earlier
 366 */
 367static void
 368nfs_sillyworker(struct work *work, void *arg)
 369{
 370 struct sillyrename *sp;
 371 int error;
 372
 373 sp = (struct sillyrename *)work;
 374 error = vn_lock(sp->s_dvp, LK_EXCLUSIVE);
 375 if (error || sp->s_dvp->v_data == NULL) {
 376 /* XXX should recover */
 377 printf("%s: vp=%p error=%d\n", __func__, sp->s_dvp, error);
 378 if (error == 0) {
 379 vput(sp->s_dvp);
 380 } else {
 381 vrele(sp->s_dvp);
 382 }
 383 } else {
 384 nfs_removeit(sp);
 385 vput(sp->s_dvp);
 386 }
 387 kauth_cred_free(sp->s_cred);
 388 kmem_free(sp, sizeof(*sp));
 389}

cvs diff -r1.68 -r1.69 src/sys/nfs/nfsnode.h (switch to unified diff)

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