Protect hash data with lock manager instead of home grown one.

Replace shared lock on vnode with exclusive one. It shouldn't impact
perfomance as NCP protocol doesn't support outstanding requests.

Do not hold simple lock on vnode for long period of time.

Add functionality to the nwfs_print() routine.
This commit is contained in:
Boris Popov 2000-10-02 09:49:04 +00:00
parent 7f66accf02
commit 5c4db877e4
8 changed files with 212 additions and 144 deletions

View File

@ -61,7 +61,7 @@ extern vop_t **nwfs_vnodeop_p;
static LIST_HEAD(nwnode_hash_head,nwnode) *nwhashtbl;
static u_long nwnodehash;
static int nwhashlock = 0;
static struct lock nwhashlock;
MALLOC_DEFINE(M_NWNODE, "NWFS node", "NWFS vnode private part");
MALLOC_DEFINE(M_NWFSHASH, "NWFS hash", "NWFS has table");
@ -76,20 +76,18 @@ SYSCTL_PROC(_vfs_nwfs, OID_AUTO, vnprint, CTLFLAG_WR|CTLTYPE_OPAQUE,
NULL, 0, nwfs_sysctl_vnprint, "S,vnlist", "vnode hash");
void
nwfs_hash_init(void)
{
nwfs_hash_init(void) {
nwhashtbl = hashinit(desiredvnodes, M_NWFSHASH, &nwnodehash);
lockinit(&nwhashlock, PVFS, "nwfshl", 0, 0);
}
void
nwfs_hash_free(void)
{
nwfs_hash_free(void) {
free(nwhashtbl, M_NWFSHASH);
}
int
nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS)
{
nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS) {
struct nwnode *np;
struct nwnode_hash_head *nhpp;
struct vnode *vp;
@ -102,6 +100,7 @@ nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS)
nhpp = &nwhashtbl[i];
for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
vp = NWTOV(np);
vprint(NULL, vp);
printf("%s:%d:%d:%d:%d\n",np->n_name,vp->v_usecount,vp->v_holdcnt,
np->n_fid.f_id, np->n_fid.f_parent);
}
@ -109,6 +108,27 @@ nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS)
return 0;
}
/*
* Search nwnode with given fid.
* Hash list should be locked by caller.
*/
static int
nwfs_hashlookup(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
{
struct nwnode *np;
struct nwnode_hash_head *nhpp;
nhpp = NWNOHASH(fid);
LIST_FOREACH(np, nhpp, n_hash) {
if (nmp != np->n_mount || !NWCMPF(&fid, &np->n_fid))
continue;
if (npp)
*npp = np;
return 0;
}
return ENOENT;
}
/*
* Allocate new nwfsnode/vnode from given nwnode.
* Vnode referenced and not locked.
@ -117,33 +137,26 @@ int
nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
{
struct proc *p = curproc; /* XXX */
struct nwnode *np, *np2;
struct nwnode *np;
struct nwnode_hash_head *nhpp;
struct nwmount *nmp = VFSTONWFS(mp);
struct vnode *vp;
int error;
retry:
nhpp = NWNOHASH(fid);
loop:
for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
rescan:
if (nwfs_hashlookup(nmp, fid, &np) == 0) {
vp = NWTOV(np);
if (mp != vp->v_mount || !NWCMPF(&fid, &np->n_fid))
continue;
if (vget(vp, LK_EXCLUSIVE, p))
simple_lock(&vp->v_interlock);
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
goto loop;
*vpp = vp;
return(0);
}
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
/* lock list, or waiting in malloc can cause problems */
if (nwhashlock) {
while(nwhashlock) {
nwhashlock = -1;
tsleep((caddr_t) &nwhashlock, PVM, "nwfsvp", 0);
}
goto loop;
}
nwhashlock = 1;
/*
* Do the MALLOC before the getnewvnode since doing so afterward
* might cause a bogus v_data pointer to get dereferenced
@ -152,52 +165,47 @@ loop:
MALLOC(np, struct nwnode *, sizeof *np, M_NWNODE, M_WAITOK);
error = getnewvnode(VT_NWFS, mp, nwfs_vnodeop_p, &vp);
if (error) {
if (nwhashlock < 0)
wakeup(&nwhashlock);
nwhashlock = 0;
*vpp = 0;
*vpp = NULL;
FREE(np, M_NWNODE);
return (error);
}
*vpp = vp;
bzero(np,sizeof(*np));
bzero(np, sizeof(*np));
vp->v_data = np;
np->n_vnode = vp;
np->n_mount = VFSTONWFS(mp);
np->n_fid = fid;
for (np2 = nhpp->lh_first; np2 != 0; np2 = np->n_hash.le_next) {
if (mp != NWTOV(np2)->v_mount || !NWCMPF(&fid, &np2->n_fid))
continue;
np->n_mount = nmp;
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
/*
* Another process can create vnode while we blocked in malloc() or
* getnewvnode(). Rescan list again.
*/
if (nwfs_hashlookup(nmp, fid, NULL) == 0) {
vp->v_data = NULL;
np->n_vnode = NULL;
vrele(vp);
FREE(np, M_NWNODE);
if (nwhashlock < 0)
wakeup(&nwhashlock);
nwhashlock = 0;
goto retry;
goto rescan;
}
LIST_INSERT_HEAD(nhpp, np, n_hash);
if (nwhashlock < 0)
wakeup(&nwhashlock);
nwhashlock = 0;
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
np->n_fid = fid;
np->n_flag |= NNEW;
return (error);
lockinit(&vp->v_lock, PINOD, "nwnode", 0, LK_CANRECURSE);
nhpp = NWNOHASH(fid);
LIST_INSERT_HEAD(nhpp, np, n_hash);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
return 0;
}
int
nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct proc *p,
struct nwnode **npp)
{
struct nwnode *np;
struct nwnode_hash_head *nhpp;
int error;
nhpp = NWNOHASH(fid);
for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
if (nmp != np->n_mount || !NWCMPF(&fid, &np->n_fid))
continue;
*npp = np;
return(0);
}
return ENOENT;
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
error = nwfs_hashlookup(nmp, fid, npp);
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
return error;
}
/*
@ -206,23 +214,27 @@ nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
int
nwfs_reclaim(ap)
struct vop_reclaim_args /* {
struct vnode *a_vp;
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
struct vnode *dvp = NULL, *vp = ap->a_vp;
struct nwnode *dnp, *np = VTONW(vp);
struct nwmount *nmp=VTONWFS(vp);
struct nwmount *nmp = VTONWFS(vp);
struct proc *p = ap->a_p;
NCPVNDEBUG("%s,%d\n", np->n_name, vp->v_usecount);
if (np->n_refparent) {
np->n_refparent = 0;
if (nwfs_lookupnp(nmp, np->n_parent, &dnp) == 0) {
if (nwfs_lookupnp(nmp, np->n_parent, p, &dnp) == 0) {
dvp = dnp->n_vnode;
} else {
NCPVNDEBUG("%s: has no parent ?\n",np->n_name);
}
}
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
LIST_REMOVE(np, n_hash);
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
cache_purge(vp);
if (nmp->n_root == np) {
nmp->n_root = NULL;
@ -255,6 +267,10 @@ nwfs_inactive(ap)
np->opened = 0;
}
VOP_UNLOCK(vp, 0, p);
if (np->n_flag & NSHOULDFREE) {
cache_purge(vp);
vgone(vp);
}
return (0);
}
/*

View File

@ -43,6 +43,7 @@
#define NMODIFIED 0x0004 /* bogus, until async IO implemented */
#define NNEW 0x0008 /* vnode has been allocated */
#define NVOLUME 0x0010 /* vnode references a volume */
#define NSHOULDFREE 0x0020 /* vnode should be removed from hash */
struct nwnode {
LIST_ENTRY(nwnode) n_hash;
@ -85,7 +86,8 @@ struct uio;
void nwfs_hash_init(void);
void nwfs_hash_free(void);
int nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp);
int nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct nwnode **npp);
int nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct proc *p,
struct nwnode **npp);
int nwfs_inactive(struct vop_inactive_args *);
int nwfs_reclaim(struct vop_reclaim_args *);
int nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,

View File

@ -301,7 +301,8 @@ nwfs_root(struct mount *mp, struct vnode **vpp) {
conn = NWFSTOCONN(nmp);
if (nmp->n_root) {
*vpp = NWTOV(nmp->n_root);
vget(*vpp, LK_EXCLUSIVE, curproc);
while (vget(*vpp, LK_EXCLUSIVE, curproc) != 0)
;
return 0;
}
error = ncp_lookup_volume(conn, nmp->m.mounted_vol, &vol,

View File

@ -97,9 +97,9 @@ static struct vnodeopv_entry_desc nwfs_vnodeop_entries[] = {
{ &vop_putpages_desc, (vop_t *) nwfs_putpages },
{ &vop_ioctl_desc, (vop_t *) nwfs_ioctl },
{ &vop_inactive_desc, (vop_t *) nwfs_inactive },
{ &vop_islocked_desc, (vop_t *) vop_noislocked },
{ &vop_islocked_desc, (vop_t *) vop_stdislocked },
{ &vop_link_desc, (vop_t *) nwfs_link },
{ &vop_lock_desc, (vop_t *) vop_sharedlock },
{ &vop_lock_desc, (vop_t *) vop_stdlock },
{ &vop_lookup_desc, (vop_t *) nwfs_lookup },
{ &vop_mkdir_desc, (vop_t *) nwfs_mkdir },
{ &vop_mknod_desc, (vop_t *) nwfs_mknod },
@ -114,7 +114,7 @@ static struct vnodeopv_entry_desc nwfs_vnodeop_entries[] = {
{ &vop_setattr_desc, (vop_t *) nwfs_setattr },
{ &vop_strategy_desc, (vop_t *) nwfs_strategy },
{ &vop_symlink_desc, (vop_t *) nwfs_symlink },
{ &vop_unlock_desc, (vop_t *) vop_nounlock },
{ &vop_unlock_desc, (vop_t *) vop_stdunlock },
{ &vop_write_desc, (vop_t *) nwfs_write },
{ NULL, NULL }
};
@ -192,7 +192,7 @@ nwfs_open(ap)
NCPVNDEBUG("%s,%d\n",np->n_name, np->opened);
if (vp->v_type != VREG && vp->v_type != VDIR) {
NCPFATAL("open eacces vtype=%d\n", vp->v_type);
NCPFATAL("open vtype = %d\n", vp->v_type);
return (EACCES);
}
if (vp->v_type == VDIR) return 0; /* nothing to do now */
@ -267,10 +267,12 @@ nwfs_close(ap)
simple_unlock(&vp->v_interlock);
return 0;
}
if (--np->opened == 0)
if (--np->opened == 0) {
simple_unlock(&vp->v_interlock);
error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh,
ap->a_p, ap->a_cred);
simple_unlock(&vp->v_interlock);
} else
simple_unlock(&vp->v_interlock);
np->n_atime = 0;
return (error);
}
@ -504,7 +506,10 @@ nwfs_remove(ap)
cache_purge(vp);
error = ncp_DeleteNSEntry(nmp, VTONW(dvp)->n_fid.f_id,
cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_proc,cnp->cn_cred);
if (error == 0x899c) error = EACCES;
if (error == 0)
np->n_flag |= NSHOULDFREE;
else if (error == 0x899c)
error = EACCES;
}
return (error);
}
@ -700,16 +705,20 @@ nwfs_rmdir(ap)
struct vnode *vp = ap->a_vp;
struct vnode *dvp = ap->a_dvp;
struct componentname *cnp = ap->a_cnp;
struct nwnode *np = VTONW(vp);
struct nwmount *nmp = VTONWFS(vp);
struct nwnode *dnp = VTONW(dvp);
int error = EIO;
if (dvp == vp) return EINVAL;
if (!ncp_conn_valid(NWFSTOCONN(nmp))) return(error);
if (dvp == vp)
return EINVAL;
error = ncp_DeleteNSEntry(nmp, dnp->n_fid.f_id,
cnp->cn_namelen, cnp->cn_nameptr,cnp->cn_proc,cnp->cn_cred);
if (error == NWE_DIR_NOT_EMPTY) error = ENOTEMPTY;
if (error == 0)
np->n_flag |= NSHOULDFREE;
else if (error == NWE_DIR_NOT_EMPTY)
error = ENOTEMPTY;
dnp->n_flag |= NMODIFIED;
nwfs_attr_cacheremove(dvp);
cache_purge(dvp);
@ -759,13 +768,19 @@ nwfs_fsync(ap)
/* return (nfs_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_p, 1));*/
return (0);
}
/* ARGSUSED */
static
int nwfs_print (ap)
struct vop_print_args /* {
struct vnode *a_vp;
struct vnode *a_vp;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
struct nwnode *np = VTONW(vp);
printf("nwfs node: name = '%s', fid = %d, pfid = %d\n",
np->n_name, np->n_fid.f_id, np->n_fid.f_parent);
return (0);
}
@ -1003,7 +1018,7 @@ printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_flag & VROOT, (int)flags & ISDOTDO
fap = NULL;
notfound = 0;
} else {
error = nwfs_lookupnp(nmp, dnp->n_parent, &npp);
error = nwfs_lookupnp(nmp, dnp->n_parent, p, &npp);
if (error) {
return error;
}

View File

@ -61,7 +61,7 @@ extern vop_t **nwfs_vnodeop_p;
static LIST_HEAD(nwnode_hash_head,nwnode) *nwhashtbl;
static u_long nwnodehash;
static int nwhashlock = 0;
static struct lock nwhashlock;
MALLOC_DEFINE(M_NWNODE, "NWFS node", "NWFS vnode private part");
MALLOC_DEFINE(M_NWFSHASH, "NWFS hash", "NWFS has table");
@ -76,20 +76,18 @@ SYSCTL_PROC(_vfs_nwfs, OID_AUTO, vnprint, CTLFLAG_WR|CTLTYPE_OPAQUE,
NULL, 0, nwfs_sysctl_vnprint, "S,vnlist", "vnode hash");
void
nwfs_hash_init(void)
{
nwfs_hash_init(void) {
nwhashtbl = hashinit(desiredvnodes, M_NWFSHASH, &nwnodehash);
lockinit(&nwhashlock, PVFS, "nwfshl", 0, 0);
}
void
nwfs_hash_free(void)
{
nwfs_hash_free(void) {
free(nwhashtbl, M_NWFSHASH);
}
int
nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS)
{
nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS) {
struct nwnode *np;
struct nwnode_hash_head *nhpp;
struct vnode *vp;
@ -102,6 +100,7 @@ nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS)
nhpp = &nwhashtbl[i];
for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
vp = NWTOV(np);
vprint(NULL, vp);
printf("%s:%d:%d:%d:%d\n",np->n_name,vp->v_usecount,vp->v_holdcnt,
np->n_fid.f_id, np->n_fid.f_parent);
}
@ -109,6 +108,27 @@ nwfs_sysctl_vnprint(SYSCTL_HANDLER_ARGS)
return 0;
}
/*
* Search nwnode with given fid.
* Hash list should be locked by caller.
*/
static int
nwfs_hashlookup(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
{
struct nwnode *np;
struct nwnode_hash_head *nhpp;
nhpp = NWNOHASH(fid);
LIST_FOREACH(np, nhpp, n_hash) {
if (nmp != np->n_mount || !NWCMPF(&fid, &np->n_fid))
continue;
if (npp)
*npp = np;
return 0;
}
return ENOENT;
}
/*
* Allocate new nwfsnode/vnode from given nwnode.
* Vnode referenced and not locked.
@ -117,33 +137,26 @@ int
nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
{
struct proc *p = curproc; /* XXX */
struct nwnode *np, *np2;
struct nwnode *np;
struct nwnode_hash_head *nhpp;
struct nwmount *nmp = VFSTONWFS(mp);
struct vnode *vp;
int error;
retry:
nhpp = NWNOHASH(fid);
loop:
for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
rescan:
if (nwfs_hashlookup(nmp, fid, &np) == 0) {
vp = NWTOV(np);
if (mp != vp->v_mount || !NWCMPF(&fid, &np->n_fid))
continue;
if (vget(vp, LK_EXCLUSIVE, p))
simple_lock(&vp->v_interlock);
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
goto loop;
*vpp = vp;
return(0);
}
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
/* lock list, or waiting in malloc can cause problems */
if (nwhashlock) {
while(nwhashlock) {
nwhashlock = -1;
tsleep((caddr_t) &nwhashlock, PVM, "nwfsvp", 0);
}
goto loop;
}
nwhashlock = 1;
/*
* Do the MALLOC before the getnewvnode since doing so afterward
* might cause a bogus v_data pointer to get dereferenced
@ -152,52 +165,47 @@ loop:
MALLOC(np, struct nwnode *, sizeof *np, M_NWNODE, M_WAITOK);
error = getnewvnode(VT_NWFS, mp, nwfs_vnodeop_p, &vp);
if (error) {
if (nwhashlock < 0)
wakeup(&nwhashlock);
nwhashlock = 0;
*vpp = 0;
*vpp = NULL;
FREE(np, M_NWNODE);
return (error);
}
*vpp = vp;
bzero(np,sizeof(*np));
bzero(np, sizeof(*np));
vp->v_data = np;
np->n_vnode = vp;
np->n_mount = VFSTONWFS(mp);
np->n_fid = fid;
for (np2 = nhpp->lh_first; np2 != 0; np2 = np->n_hash.le_next) {
if (mp != NWTOV(np2)->v_mount || !NWCMPF(&fid, &np2->n_fid))
continue;
np->n_mount = nmp;
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
/*
* Another process can create vnode while we blocked in malloc() or
* getnewvnode(). Rescan list again.
*/
if (nwfs_hashlookup(nmp, fid, NULL) == 0) {
vp->v_data = NULL;
np->n_vnode = NULL;
vrele(vp);
FREE(np, M_NWNODE);
if (nwhashlock < 0)
wakeup(&nwhashlock);
nwhashlock = 0;
goto retry;
goto rescan;
}
LIST_INSERT_HEAD(nhpp, np, n_hash);
if (nwhashlock < 0)
wakeup(&nwhashlock);
nwhashlock = 0;
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
np->n_fid = fid;
np->n_flag |= NNEW;
return (error);
lockinit(&vp->v_lock, PINOD, "nwnode", 0, LK_CANRECURSE);
nhpp = NWNOHASH(fid);
LIST_INSERT_HEAD(nhpp, np, n_hash);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
return 0;
}
int
nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct proc *p,
struct nwnode **npp)
{
struct nwnode *np;
struct nwnode_hash_head *nhpp;
int error;
nhpp = NWNOHASH(fid);
for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
if (nmp != np->n_mount || !NWCMPF(&fid, &np->n_fid))
continue;
*npp = np;
return(0);
}
return ENOENT;
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
error = nwfs_hashlookup(nmp, fid, npp);
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
return error;
}
/*
@ -206,23 +214,27 @@ nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
int
nwfs_reclaim(ap)
struct vop_reclaim_args /* {
struct vnode *a_vp;
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
struct vnode *dvp = NULL, *vp = ap->a_vp;
struct nwnode *dnp, *np = VTONW(vp);
struct nwmount *nmp=VTONWFS(vp);
struct nwmount *nmp = VTONWFS(vp);
struct proc *p = ap->a_p;
NCPVNDEBUG("%s,%d\n", np->n_name, vp->v_usecount);
if (np->n_refparent) {
np->n_refparent = 0;
if (nwfs_lookupnp(nmp, np->n_parent, &dnp) == 0) {
if (nwfs_lookupnp(nmp, np->n_parent, p, &dnp) == 0) {
dvp = dnp->n_vnode;
} else {
NCPVNDEBUG("%s: has no parent ?\n",np->n_name);
}
}
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
LIST_REMOVE(np, n_hash);
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
cache_purge(vp);
if (nmp->n_root == np) {
nmp->n_root = NULL;
@ -255,6 +267,10 @@ nwfs_inactive(ap)
np->opened = 0;
}
VOP_UNLOCK(vp, 0, p);
if (np->n_flag & NSHOULDFREE) {
cache_purge(vp);
vgone(vp);
}
return (0);
}
/*

View File

@ -43,6 +43,7 @@
#define NMODIFIED 0x0004 /* bogus, until async IO implemented */
#define NNEW 0x0008 /* vnode has been allocated */
#define NVOLUME 0x0010 /* vnode references a volume */
#define NSHOULDFREE 0x0020 /* vnode should be removed from hash */
struct nwnode {
LIST_ENTRY(nwnode) n_hash;
@ -85,7 +86,8 @@ struct uio;
void nwfs_hash_init(void);
void nwfs_hash_free(void);
int nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp);
int nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct nwnode **npp);
int nwfs_lookupnp(struct nwmount *nmp, ncpfid fid, struct proc *p,
struct nwnode **npp);
int nwfs_inactive(struct vop_inactive_args *);
int nwfs_reclaim(struct vop_reclaim_args *);
int nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,

View File

@ -301,7 +301,8 @@ nwfs_root(struct mount *mp, struct vnode **vpp) {
conn = NWFSTOCONN(nmp);
if (nmp->n_root) {
*vpp = NWTOV(nmp->n_root);
vget(*vpp, LK_EXCLUSIVE, curproc);
while (vget(*vpp, LK_EXCLUSIVE, curproc) != 0)
;
return 0;
}
error = ncp_lookup_volume(conn, nmp->m.mounted_vol, &vol,

View File

@ -97,9 +97,9 @@ static struct vnodeopv_entry_desc nwfs_vnodeop_entries[] = {
{ &vop_putpages_desc, (vop_t *) nwfs_putpages },
{ &vop_ioctl_desc, (vop_t *) nwfs_ioctl },
{ &vop_inactive_desc, (vop_t *) nwfs_inactive },
{ &vop_islocked_desc, (vop_t *) vop_noislocked },
{ &vop_islocked_desc, (vop_t *) vop_stdislocked },
{ &vop_link_desc, (vop_t *) nwfs_link },
{ &vop_lock_desc, (vop_t *) vop_sharedlock },
{ &vop_lock_desc, (vop_t *) vop_stdlock },
{ &vop_lookup_desc, (vop_t *) nwfs_lookup },
{ &vop_mkdir_desc, (vop_t *) nwfs_mkdir },
{ &vop_mknod_desc, (vop_t *) nwfs_mknod },
@ -114,7 +114,7 @@ static struct vnodeopv_entry_desc nwfs_vnodeop_entries[] = {
{ &vop_setattr_desc, (vop_t *) nwfs_setattr },
{ &vop_strategy_desc, (vop_t *) nwfs_strategy },
{ &vop_symlink_desc, (vop_t *) nwfs_symlink },
{ &vop_unlock_desc, (vop_t *) vop_nounlock },
{ &vop_unlock_desc, (vop_t *) vop_stdunlock },
{ &vop_write_desc, (vop_t *) nwfs_write },
{ NULL, NULL }
};
@ -192,7 +192,7 @@ nwfs_open(ap)
NCPVNDEBUG("%s,%d\n",np->n_name, np->opened);
if (vp->v_type != VREG && vp->v_type != VDIR) {
NCPFATAL("open eacces vtype=%d\n", vp->v_type);
NCPFATAL("open vtype = %d\n", vp->v_type);
return (EACCES);
}
if (vp->v_type == VDIR) return 0; /* nothing to do now */
@ -267,10 +267,12 @@ nwfs_close(ap)
simple_unlock(&vp->v_interlock);
return 0;
}
if (--np->opened == 0)
if (--np->opened == 0) {
simple_unlock(&vp->v_interlock);
error = ncp_close_file(NWFSTOCONN(VTONWFS(vp)), &np->n_fh,
ap->a_p, ap->a_cred);
simple_unlock(&vp->v_interlock);
} else
simple_unlock(&vp->v_interlock);
np->n_atime = 0;
return (error);
}
@ -504,7 +506,10 @@ nwfs_remove(ap)
cache_purge(vp);
error = ncp_DeleteNSEntry(nmp, VTONW(dvp)->n_fid.f_id,
cnp->cn_namelen,cnp->cn_nameptr,cnp->cn_proc,cnp->cn_cred);
if (error == 0x899c) error = EACCES;
if (error == 0)
np->n_flag |= NSHOULDFREE;
else if (error == 0x899c)
error = EACCES;
}
return (error);
}
@ -700,16 +705,20 @@ nwfs_rmdir(ap)
struct vnode *vp = ap->a_vp;
struct vnode *dvp = ap->a_dvp;
struct componentname *cnp = ap->a_cnp;
struct nwnode *np = VTONW(vp);
struct nwmount *nmp = VTONWFS(vp);
struct nwnode *dnp = VTONW(dvp);
int error = EIO;
if (dvp == vp) return EINVAL;
if (!ncp_conn_valid(NWFSTOCONN(nmp))) return(error);
if (dvp == vp)
return EINVAL;
error = ncp_DeleteNSEntry(nmp, dnp->n_fid.f_id,
cnp->cn_namelen, cnp->cn_nameptr,cnp->cn_proc,cnp->cn_cred);
if (error == NWE_DIR_NOT_EMPTY) error = ENOTEMPTY;
if (error == 0)
np->n_flag |= NSHOULDFREE;
else if (error == NWE_DIR_NOT_EMPTY)
error = ENOTEMPTY;
dnp->n_flag |= NMODIFIED;
nwfs_attr_cacheremove(dvp);
cache_purge(dvp);
@ -759,13 +768,19 @@ nwfs_fsync(ap)
/* return (nfs_flush(ap->a_vp, ap->a_cred, ap->a_waitfor, ap->a_p, 1));*/
return (0);
}
/* ARGSUSED */
static
int nwfs_print (ap)
struct vop_print_args /* {
struct vnode *a_vp;
struct vnode *a_vp;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
struct nwnode *np = VTONW(vp);
printf("nwfs node: name = '%s', fid = %d, pfid = %d\n",
np->n_name, np->n_fid.f_id, np->n_fid.f_parent);
return (0);
}
@ -1003,7 +1018,7 @@ printf("dvp %d:%d:%d\n", (int)mp, (int)dvp->v_flag & VROOT, (int)flags & ISDOTDO
fap = NULL;
notfound = 0;
} else {
error = nwfs_lookupnp(nmp, dnp->n_parent, &npp);
error = nwfs_lookupnp(nmp, dnp->n_parent, p, &npp);
if (error) {
return error;
}