- Don't vput() a vnode that we do not hold locked.
- Eliminate one of the few remaining uses of LK_CANRECURSE.
This commit is contained in:
parent
624b664af1
commit
27bc6a2391
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: nfs_node.c,v 1.107 2008/11/19 18:36:09 ad Exp $ */
|
/* $NetBSD: nfs_node.c,v 1.108 2009/01/02 12:57:29 ad Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1989, 1993
|
* Copyright (c) 1989, 1993
|
||||||
|
@ -35,7 +35,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.107 2008/11/19 18:36:09 ad Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.108 2009/01/02 12:57:29 ad Exp $");
|
||||||
|
|
||||||
#ifdef _KERNEL_OPT
|
#ifdef _KERNEL_OPT
|
||||||
#include "opt_nfs.h"
|
#include "opt_nfs.h"
|
||||||
|
@ -62,14 +62,14 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_node.c,v 1.107 2008/11/19 18:36:09 ad Exp $");
|
||||||
|
|
||||||
struct pool nfs_node_pool;
|
struct pool nfs_node_pool;
|
||||||
struct pool nfs_vattr_pool;
|
struct pool nfs_vattr_pool;
|
||||||
|
static struct workqueue *nfs_sillyworkq;
|
||||||
MALLOC_JUSTDEFINE(M_NFSNODE, "NFS node", "NFS vnode private part");
|
|
||||||
|
|
||||||
extern int prtactive;
|
extern int prtactive;
|
||||||
|
|
||||||
void nfs_gop_size(struct vnode *, off_t, off_t *, int);
|
static void nfs_gop_size(struct vnode *, off_t, off_t *, int);
|
||||||
int nfs_gop_alloc(struct vnode *, off_t, off_t, int, kauth_cred_t);
|
static int nfs_gop_alloc(struct vnode *, off_t, off_t, int, kauth_cred_t);
|
||||||
int nfs_gop_write(struct vnode *, struct vm_page **, int, int);
|
static int nfs_gop_write(struct vnode *, struct vm_page **, int, int);
|
||||||
|
static void nfs_sillyworker(struct work *, void *);
|
||||||
|
|
||||||
static const struct genfs_ops nfs_genfsops = {
|
static const struct genfs_ops nfs_genfsops = {
|
||||||
.gop_size = nfs_gop_size,
|
.gop_size = nfs_gop_size,
|
||||||
|
@ -83,11 +83,15 @@ static const struct genfs_ops nfs_genfsops = {
|
||||||
void
|
void
|
||||||
nfs_node_init()
|
nfs_node_init()
|
||||||
{
|
{
|
||||||
malloc_type_attach(M_NFSNODE);
|
|
||||||
pool_init(&nfs_node_pool, sizeof(struct nfsnode), 0, 0, 0, "nfsnodepl",
|
pool_init(&nfs_node_pool, sizeof(struct nfsnode), 0, 0, 0, "nfsnodepl",
|
||||||
&pool_allocator_nointr, IPL_NONE);
|
&pool_allocator_nointr, IPL_NONE);
|
||||||
pool_init(&nfs_vattr_pool, sizeof(struct vattr), 0, 0, 0, "nfsvapl",
|
pool_init(&nfs_vattr_pool, sizeof(struct vattr), 0, 0, 0, "nfsvapl",
|
||||||
&pool_allocator_nointr, IPL_NONE);
|
&pool_allocator_nointr, IPL_NONE);
|
||||||
|
if (workqueue_create(&nfs_sillyworkq, "nfssilly", nfs_sillyworker,
|
||||||
|
NULL, PRI_NONE, IPL_NONE, 0) != 0) {
|
||||||
|
panic("nfs_node_init");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -96,9 +100,10 @@ nfs_node_init()
|
||||||
void
|
void
|
||||||
nfs_node_done()
|
nfs_node_done()
|
||||||
{
|
{
|
||||||
|
|
||||||
pool_destroy(&nfs_node_pool);
|
pool_destroy(&nfs_node_pool);
|
||||||
pool_destroy(&nfs_vattr_pool);
|
pool_destroy(&nfs_vattr_pool);
|
||||||
malloc_type_detach(M_NFSNODE);
|
workqueue_destroy(nfs_sillyworkq);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RBTONFSNODE(node) \
|
#define RBTONFSNODE(node) \
|
||||||
|
@ -272,26 +277,7 @@ nfs_inactive(v)
|
||||||
VOP_UNLOCK(vp, 0);
|
VOP_UNLOCK(vp, 0);
|
||||||
|
|
||||||
if (sp != NULL) {
|
if (sp != NULL) {
|
||||||
int error;
|
workqueue_enqueue(nfs_sillyworkq, &sp->s_work, NULL);
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove the silly file that was rename'd earlier
|
|
||||||
*
|
|
||||||
* Just in case our thread also has the parent node locked,
|
|
||||||
* we use LK_CANRECURSE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
error = vn_lock(sp->s_dvp, LK_EXCLUSIVE | LK_CANRECURSE);
|
|
||||||
if (error || sp->s_dvp->v_data == NULL) {
|
|
||||||
/* XXX should recover */
|
|
||||||
printf("%s: vp=%p error=%d\n",
|
|
||||||
__func__, sp->s_dvp, error);
|
|
||||||
} else {
|
|
||||||
nfs_removeit(sp);
|
|
||||||
}
|
|
||||||
kauth_cred_free(sp->s_cred);
|
|
||||||
vput(sp->s_dvp);
|
|
||||||
kmem_free(sp, sizeof(*sp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -374,3 +360,30 @@ nfs_gop_write(struct vnode *vp, struct vm_page **pgs, int npages, int flags)
|
||||||
}
|
}
|
||||||
return genfs_gop_write(vp, pgs, npages, flags);
|
return genfs_gop_write(vp, pgs, npages, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove a silly file that was rename'd earlier
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
nfs_sillyworker(struct work *work, void *arg)
|
||||||
|
{
|
||||||
|
struct sillyrename *sp;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
sp = (struct sillyrename *)work;
|
||||||
|
error = vn_lock(sp->s_dvp, LK_EXCLUSIVE);
|
||||||
|
if (error || sp->s_dvp->v_data == NULL) {
|
||||||
|
/* XXX should recover */
|
||||||
|
printf("%s: vp=%p error=%d\n", __func__, sp->s_dvp, error);
|
||||||
|
if (error == 0) {
|
||||||
|
vput(sp->s_dvp);
|
||||||
|
} else {
|
||||||
|
vrele(sp->s_dvp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nfs_removeit(sp);
|
||||||
|
vput(sp->s_dvp);
|
||||||
|
}
|
||||||
|
kauth_cred_free(sp->s_cred);
|
||||||
|
kmem_free(sp, sizeof(*sp));
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: nfsnode.h,v 1.68 2008/10/22 11:36:06 matt Exp $ */
|
/* $NetBSD: nfsnode.h,v 1.69 2009/01/02 12:57:29 ad Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1989, 1993
|
* Copyright (c) 1989, 1993
|
||||||
|
@ -41,6 +41,7 @@
|
||||||
#include <sys/condvar.h>
|
#include <sys/condvar.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/rb.h>
|
#include <sys/rb.h>
|
||||||
|
#include <sys/workqueue.h>
|
||||||
|
|
||||||
#ifndef _NFS_NFS_H_
|
#ifndef _NFS_NFS_H_
|
||||||
#include <nfs/nfs.h>
|
#include <nfs/nfs.h>
|
||||||
|
@ -53,6 +54,7 @@
|
||||||
* can be removed by nfs_inactive()
|
* can be removed by nfs_inactive()
|
||||||
*/
|
*/
|
||||||
struct sillyrename {
|
struct sillyrename {
|
||||||
|
struct work s_work;
|
||||||
kauth_cred_t s_cred;
|
kauth_cred_t s_cred;
|
||||||
struct vnode *s_dvp;
|
struct vnode *s_dvp;
|
||||||
long s_namlen;
|
long s_namlen;
|
||||||
|
@ -281,7 +283,6 @@ int nfs_pathconf __P((void *));
|
||||||
int nfs_advlock __P((void *));
|
int nfs_advlock __P((void *));
|
||||||
int nfs_getpages __P((void *));
|
int nfs_getpages __P((void *));
|
||||||
int nfs_putpages __P((void *));
|
int nfs_putpages __P((void *));
|
||||||
int nfs_gop_write(struct vnode *, struct vm_page **, int, int);
|
|
||||||
int nfs_kqfilter __P((void *));
|
int nfs_kqfilter __P((void *));
|
||||||
|
|
||||||
extern int (**nfsv2_vnodeop_p) __P((void *));
|
extern int (**nfsv2_vnodeop_p) __P((void *));
|
||||||
|
|
Loading…
Reference in New Issue