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 (expand / 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,14 +1,14 @@ @@ -1,14 +1,14 @@
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.
@@ -25,90 +25,95 @@ @@ -25,90 +25,95 @@
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)
@@ -262,46 +267,27 @@ nfs_inactive(v) @@ -262,46 +267,27 @@ nfs_inactive(v)
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 /* {
@@ -364,13 +350,40 @@ nfs_gop_alloc(struct vnode *vp, off_t of @@ -364,13 +350,40 @@ nfs_gop_alloc(struct vnode *vp, off_t of
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 (expand / 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,14 +1,14 @@ @@ -1,14 +1,14 @@
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.
@@ -31,38 +31,40 @@ @@ -31,38 +31,40 @@
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
@@ -271,23 +273,22 @@ int nfs_readlink __P((void *)); @@ -271,23 +273,22 @@ int 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