Slightly reorganize allocation of new vnode. Use bit NVOLUME to detected
vnodes which represent volumes (before it was done via strcmp()). Turn n_refparent into bit in the n_flag field.
This commit is contained in:
parent
de328d4a59
commit
1db5c04bc0
@ -56,6 +56,7 @@
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
|
||||
#include <nwfs/nwfs.h>
|
||||
#include <nwfs/nwfs_node.h>
|
||||
|
@ -134,8 +134,9 @@ nwfs_hashlookup(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
|
||||
* Allocate new nwfsnode/vnode from given nwnode.
|
||||
* Vnode referenced and not locked.
|
||||
*/
|
||||
int
|
||||
nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
|
||||
static int
|
||||
nwfs_allocvp(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp)
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct nwnode *np;
|
||||
@ -153,11 +154,15 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
|
||||
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
|
||||
goto loop;
|
||||
if (fap)
|
||||
np->n_attr = fap->attributes;
|
||||
*vpp = vp;
|
||||
return(0);
|
||||
}
|
||||
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
|
||||
|
||||
if (fap == NULL || ((fap->attributes & aDIR) == 0 && dvp == NULL))
|
||||
panic("nwfs_allocvp: fap = %p, dvp = %p\n", fap, dvp);
|
||||
/*
|
||||
* Do the MALLOC before the getnewvnode since doing so afterward
|
||||
* might cause a bogus v_data pointer to get dereferenced
|
||||
@ -173,6 +178,13 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
|
||||
vp->v_data = np;
|
||||
np->n_vnode = vp;
|
||||
np->n_mount = nmp;
|
||||
np->n_attr = fap->attributes;
|
||||
vp->v_type = np->n_attr & aDIR ? VDIR : VREG;
|
||||
np->n_fid = fid;
|
||||
if (dvp) {
|
||||
np->n_parent = VTONW(dvp)->n_fid;
|
||||
}
|
||||
lockinit(&vp->v_lock, PINOD, "nwnode", 0, LK_CANRECURSE);
|
||||
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
|
||||
/*
|
||||
* Another process can create vnode while we blocked in malloc() or
|
||||
@ -186,13 +198,32 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
|
||||
goto rescan;
|
||||
}
|
||||
*vpp = vp;
|
||||
np->n_fid = fid;
|
||||
np->n_flag |= NNEW;
|
||||
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);
|
||||
|
||||
if (vp->v_type == VDIR && dvp && (dvp->v_flag & VROOT) == 0) {
|
||||
np->n_flag |= NREFPARENT;
|
||||
vref(dvp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
int error;
|
||||
|
||||
*vpp = NULL;
|
||||
error = nwfs_allocvp(mp, fid, fap, dvp, &vp);
|
||||
if (error)
|
||||
return error;
|
||||
if (fap)
|
||||
nwfs_attr_cacheenter(vp, fap);
|
||||
*vpp = vp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -224,8 +255,8 @@ nwfs_reclaim(ap)
|
||||
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 (np->n_flag & NREFPARENT) {
|
||||
np->n_flag &= ~NREFPARENT;
|
||||
if (nwfs_lookupnp(nmp, np->n_parent, p, &dnp) == 0) {
|
||||
dvp = dnp->n_vnode;
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2000 Boris Popov
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,13 +35,12 @@
|
||||
#define _NWFS_NODE_H_
|
||||
|
||||
#define NWFS_ROOT_INO 0x7ffffffd
|
||||
#define NWFS_ROOTVOL "#.ROOT"
|
||||
|
||||
/* Bits for nwnode.n_flag */
|
||||
#define NFLUSHINPROG 0x0001
|
||||
#define NFLUSHWANT 0x0002 /* they should gone ... */
|
||||
#define NMODIFIED 0x0004 /* bogus, until async IO implemented */
|
||||
#define NNEW 0x0008 /* vnode has been allocated */
|
||||
#define NREFPARENT 0x0008 /* vnode holds reference to a parent vnode */
|
||||
#define NVOLUME 0x0010 /* vnode references a volume */
|
||||
#define NSHOULDFREE 0x0020 /* vnode should be removed from hash */
|
||||
|
||||
@ -56,7 +55,6 @@ struct nwnode {
|
||||
int n_flag;
|
||||
ncpfid n_parent;
|
||||
ncpfid n_fid;
|
||||
int n_refparent;
|
||||
u_long n_attr; /* LH */
|
||||
u_long n_size;
|
||||
u_long n_dosfid;
|
||||
@ -85,13 +83,12 @@ 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 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,
|
||||
struct vnode *dvp, struct vnode **vpp);
|
||||
int nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp);
|
||||
|
||||
int nwfs_getpages(struct vop_getpages_args *);
|
||||
int nwfs_putpages(struct vop_putpages_args *);
|
||||
|
@ -188,7 +188,7 @@ ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap,
|
||||
conn = NWFSTOCONN(nmp);
|
||||
|
||||
if (len == 1 && name[0] == '.') {
|
||||
if (strcmp(dnp->n_name, NWFS_ROOTVOL) == 0) {
|
||||
if (dnp->n_flag & NVOLUME) {
|
||||
error = ncp_obtain_info(nmp, dnp->n_fid.f_id, 0, NULL,
|
||||
fap, p, cred);
|
||||
} else {
|
||||
|
@ -352,7 +352,7 @@ nwfs_root(struct mount *mp, struct vnode **vpp) {
|
||||
NCPFATAL("Can't obtain volume info\n");
|
||||
return ENOENT;
|
||||
}
|
||||
fattr.nameLen = strlen(strcpy(fattr.entryName, NWFS_ROOTVOL));
|
||||
fattr.nameLen = strlen(strcpy(fattr.entryName, "#.ROOT"));
|
||||
nmp->n_rootent.f_parent = nmp->n_rootent.f_id;
|
||||
}
|
||||
error = nwfs_nget(mp, nmp->n_rootent, &fattr, NULL, &vp);
|
||||
|
@ -854,41 +854,6 @@ nwfs_bmap(ap)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp)
|
||||
{
|
||||
int error;
|
||||
struct nwnode *newnp;
|
||||
struct vnode *vp;
|
||||
|
||||
*vpp = NULL;
|
||||
error = nwfs_allocvp(mp, fid, &vp);
|
||||
if (error)
|
||||
return error;
|
||||
newnp = VTONW(vp);
|
||||
if (fap) {
|
||||
newnp->n_attr = fap->attributes;
|
||||
vp->v_type = newnp->n_attr & aDIR ? VDIR : VREG;
|
||||
nwfs_attr_cacheenter(vp, fap);
|
||||
}
|
||||
if (dvp) {
|
||||
newnp->n_parent = VTONW(dvp)->n_fid;
|
||||
if ((newnp->n_flag & NNEW) && vp->v_type == VDIR) {
|
||||
if ((dvp->v_flag & VROOT) == 0) {
|
||||
newnp->n_refparent = 1;
|
||||
vref(dvp); /* vhold */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((newnp->n_flag & NNEW) && vp->v_type == VREG)
|
||||
printf("new vnode '%s' borned without parent ?\n",newnp->n_name);
|
||||
}
|
||||
newnp->n_flag &= ~NNEW;
|
||||
*vpp = vp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* How to keep the brain busy ...
|
||||
* Currently lookup routine can make two lookup for vnode. This can be
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include <netncp/ncp.h>
|
||||
#include <netncp/ncp_conn.h>
|
||||
#include <netncp/ncp_subr.h>
|
||||
#include <netncp/ncp_ncp.h>
|
||||
|
||||
#include <nwfs/nwfs.h>
|
||||
#include <nwfs/nwfs_node.h>
|
||||
|
@ -134,8 +134,9 @@ nwfs_hashlookup(struct nwmount *nmp, ncpfid fid, struct nwnode **npp)
|
||||
* Allocate new nwfsnode/vnode from given nwnode.
|
||||
* Vnode referenced and not locked.
|
||||
*/
|
||||
int
|
||||
nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
|
||||
static int
|
||||
nwfs_allocvp(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp)
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct nwnode *np;
|
||||
@ -153,11 +154,15 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
|
||||
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
|
||||
goto loop;
|
||||
if (fap)
|
||||
np->n_attr = fap->attributes;
|
||||
*vpp = vp;
|
||||
return(0);
|
||||
}
|
||||
lockmgr(&nwhashlock, LK_RELEASE, NULL, p);
|
||||
|
||||
if (fap == NULL || ((fap->attributes & aDIR) == 0 && dvp == NULL))
|
||||
panic("nwfs_allocvp: fap = %p, dvp = %p\n", fap, dvp);
|
||||
/*
|
||||
* Do the MALLOC before the getnewvnode since doing so afterward
|
||||
* might cause a bogus v_data pointer to get dereferenced
|
||||
@ -173,6 +178,13 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
|
||||
vp->v_data = np;
|
||||
np->n_vnode = vp;
|
||||
np->n_mount = nmp;
|
||||
np->n_attr = fap->attributes;
|
||||
vp->v_type = np->n_attr & aDIR ? VDIR : VREG;
|
||||
np->n_fid = fid;
|
||||
if (dvp) {
|
||||
np->n_parent = VTONW(dvp)->n_fid;
|
||||
}
|
||||
lockinit(&vp->v_lock, PINOD, "nwnode", 0, LK_CANRECURSE);
|
||||
lockmgr(&nwhashlock, LK_EXCLUSIVE, NULL, p);
|
||||
/*
|
||||
* Another process can create vnode while we blocked in malloc() or
|
||||
@ -186,13 +198,32 @@ nwfs_allocvp(struct mount *mp, ncpfid fid, struct vnode **vpp)
|
||||
goto rescan;
|
||||
}
|
||||
*vpp = vp;
|
||||
np->n_fid = fid;
|
||||
np->n_flag |= NNEW;
|
||||
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);
|
||||
|
||||
if (vp->v_type == VDIR && dvp && (dvp->v_flag & VROOT) == 0) {
|
||||
np->n_flag |= NREFPARENT;
|
||||
vref(dvp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp)
|
||||
{
|
||||
struct vnode *vp;
|
||||
int error;
|
||||
|
||||
*vpp = NULL;
|
||||
error = nwfs_allocvp(mp, fid, fap, dvp, &vp);
|
||||
if (error)
|
||||
return error;
|
||||
if (fap)
|
||||
nwfs_attr_cacheenter(vp, fap);
|
||||
*vpp = vp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -224,8 +255,8 @@ nwfs_reclaim(ap)
|
||||
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 (np->n_flag & NREFPARENT) {
|
||||
np->n_flag &= ~NREFPARENT;
|
||||
if (nwfs_lookupnp(nmp, np->n_parent, p, &dnp) == 0) {
|
||||
dvp = dnp->n_vnode;
|
||||
} else {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2000 Boris Popov
|
||||
* Copyright (c) 1999, 2000, 2001 Boris Popov
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,13 +35,12 @@
|
||||
#define _NWFS_NODE_H_
|
||||
|
||||
#define NWFS_ROOT_INO 0x7ffffffd
|
||||
#define NWFS_ROOTVOL "#.ROOT"
|
||||
|
||||
/* Bits for nwnode.n_flag */
|
||||
#define NFLUSHINPROG 0x0001
|
||||
#define NFLUSHWANT 0x0002 /* they should gone ... */
|
||||
#define NMODIFIED 0x0004 /* bogus, until async IO implemented */
|
||||
#define NNEW 0x0008 /* vnode has been allocated */
|
||||
#define NREFPARENT 0x0008 /* vnode holds reference to a parent vnode */
|
||||
#define NVOLUME 0x0010 /* vnode references a volume */
|
||||
#define NSHOULDFREE 0x0020 /* vnode should be removed from hash */
|
||||
|
||||
@ -56,7 +55,6 @@ struct nwnode {
|
||||
int n_flag;
|
||||
ncpfid n_parent;
|
||||
ncpfid n_fid;
|
||||
int n_refparent;
|
||||
u_long n_attr; /* LH */
|
||||
u_long n_size;
|
||||
u_long n_dosfid;
|
||||
@ -85,13 +83,12 @@ 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 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,
|
||||
struct vnode *dvp, struct vnode **vpp);
|
||||
int nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp);
|
||||
|
||||
int nwfs_getpages(struct vop_getpages_args *);
|
||||
int nwfs_putpages(struct vop_putpages_args *);
|
||||
|
@ -188,7 +188,7 @@ ncp_lookup(struct vnode *dvp, int len, char *name, struct nw_entry_info *fap,
|
||||
conn = NWFSTOCONN(nmp);
|
||||
|
||||
if (len == 1 && name[0] == '.') {
|
||||
if (strcmp(dnp->n_name, NWFS_ROOTVOL) == 0) {
|
||||
if (dnp->n_flag & NVOLUME) {
|
||||
error = ncp_obtain_info(nmp, dnp->n_fid.f_id, 0, NULL,
|
||||
fap, p, cred);
|
||||
} else {
|
||||
|
@ -352,7 +352,7 @@ nwfs_root(struct mount *mp, struct vnode **vpp) {
|
||||
NCPFATAL("Can't obtain volume info\n");
|
||||
return ENOENT;
|
||||
}
|
||||
fattr.nameLen = strlen(strcpy(fattr.entryName, NWFS_ROOTVOL));
|
||||
fattr.nameLen = strlen(strcpy(fattr.entryName, "#.ROOT"));
|
||||
nmp->n_rootent.f_parent = nmp->n_rootent.f_id;
|
||||
}
|
||||
error = nwfs_nget(mp, nmp->n_rootent, &fattr, NULL, &vp);
|
||||
|
@ -854,41 +854,6 @@ nwfs_bmap(ap)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
nwfs_nget(struct mount *mp, ncpfid fid, struct nw_entry_info *fap,
|
||||
struct vnode *dvp, struct vnode **vpp)
|
||||
{
|
||||
int error;
|
||||
struct nwnode *newnp;
|
||||
struct vnode *vp;
|
||||
|
||||
*vpp = NULL;
|
||||
error = nwfs_allocvp(mp, fid, &vp);
|
||||
if (error)
|
||||
return error;
|
||||
newnp = VTONW(vp);
|
||||
if (fap) {
|
||||
newnp->n_attr = fap->attributes;
|
||||
vp->v_type = newnp->n_attr & aDIR ? VDIR : VREG;
|
||||
nwfs_attr_cacheenter(vp, fap);
|
||||
}
|
||||
if (dvp) {
|
||||
newnp->n_parent = VTONW(dvp)->n_fid;
|
||||
if ((newnp->n_flag & NNEW) && vp->v_type == VDIR) {
|
||||
if ((dvp->v_flag & VROOT) == 0) {
|
||||
newnp->n_refparent = 1;
|
||||
vref(dvp); /* vhold */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((newnp->n_flag & NNEW) && vp->v_type == VREG)
|
||||
printf("new vnode '%s' borned without parent ?\n",newnp->n_name);
|
||||
}
|
||||
newnp->n_flag &= ~NNEW;
|
||||
*vpp = vp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* How to keep the brain busy ...
|
||||
* Currently lookup routine can make two lookup for vnode. This can be
|
||||
|
Loading…
Reference in New Issue
Block a user