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:
bp 2001-03-10 05:39:03 +00:00
parent 121df52182
commit 2435f9d89d
12 changed files with 90 additions and 102 deletions

View File

@ -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>

View File

@ -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 {

View File

@ -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 *);

View File

@ -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 {

View File

@ -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);

View File

@ -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

View File

@ -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>

View File

@ -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 {

View File

@ -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 *);

View File

@ -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 {

View File

@ -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);

View File

@ -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