version 1.9, 2006/11/18 08:18:24 |
version 1.9.2.3, 2007/01/12 01:04:05 |
Line 53 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 53 __KERNEL_RCSID(0, "$NetBSD$"); |
|
POOL_INIT(puffs_pnpool, sizeof(struct puffs_node), 0, 0, 0, "puffspnpl", |
POOL_INIT(puffs_pnpool, sizeof(struct puffs_node), 0, 0, 0, "puffspnpl", |
&pool_allocator_nointr); |
&pool_allocator_nointr); |
|
|
|
#ifdef DEBUG |
|
int puffsdebug; |
|
#endif |
|
|
|
|
static void puffs_gop_size(struct vnode *, off_t, off_t *, int); |
static void puffs_gop_size(struct vnode *, off_t, off_t *, int); |
static void puffs_gop_markupdate(struct vnode *, int); |
static void puffs_gop_markupdate(struct vnode *, int); |
|
|
puffs_newnode(struct mount *mp, struct vnode *dvp, struct vnode **vpp, |
puffs_newnode(struct mount *mp, struct vnode *dvp, struct vnode **vpp, |
void *cookie, struct componentname *cnp, enum vtype type, dev_t rdev) |
void *cookie, struct componentname *cnp, enum vtype type, dev_t rdev) |
{ |
{ |
|
struct puffs_mount *pmp = MPTOPUFFSMP(mp); |
struct vnode *vp; |
struct vnode *vp; |
int error; |
int error; |
|
|
Line 215 puffs_newnode(struct mount *mp, struct v |
|
Line 220 puffs_newnode(struct mount *mp, struct v |
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
*vpp = vp; |
*vpp = vp; |
|
|
|
if ((cnp->cn_flags & MAKEENTRY) && PUFFS_DOCACHE(pmp)) |
|
cache_enter(dvp, vp, cnp); |
|
|
return 0; |
return 0; |
} |
} |
|
|
Line 247 puffs_putvnode(struct vnode *vp) |
|
Line 255 puffs_putvnode(struct vnode *vp) |
|
* XXX: lists, although lookup cache mostly shields us from this |
* XXX: lists, although lookup cache mostly shields us from this |
*/ |
*/ |
struct vnode * |
struct vnode * |
puffs_pnode2vnode(struct puffs_mount *pmp, void *cookie) |
puffs_pnode2vnode(struct puffs_mount *pmp, void *cookie, int lock) |
{ |
{ |
struct puffs_node *pnode; |
struct puffs_node *pnode; |
struct vnode *vp; |
struct vnode *vp; |
|
int vgetflags; |
|
|
simple_lock(&pmp->pmp_lock); |
simple_lock(&pmp->pmp_lock); |
LIST_FOREACH(pnode, &pmp->pmp_pnodelist, pn_entries) { |
LIST_FOREACH(pnode, &pmp->pmp_pnodelist, pn_entries) { |
Line 258 puffs_pnode2vnode(struct puffs_mount *pm |
|
Line 267 puffs_pnode2vnode(struct puffs_mount *pm |
|
break; |
break; |
} |
} |
simple_unlock(&pmp->pmp_lock); |
simple_unlock(&pmp->pmp_lock); |
|
|
|
/* XXX: what lock controls this? */ |
if (!pnode) |
if (!pnode) |
return NULL; |
return NULL; |
vp = pnode->pn_vp; |
vp = pnode->pn_vp; |
|
|
if (pnode->pn_stat & PNODE_INACTIVE) { |
if (lock) |
if (vget(vp, LK_EXCLUSIVE | LK_RETRY)) |
vgetflags = LK_EXCLUSIVE | LK_RETRY; |
return NULL; |
else |
} else { |
vgetflags = 0; |
vref(vp); |
|
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); |
if (vget(vp, vgetflags)) |
} |
return NULL; |
|
|
return vp; |
return vp; |
} |
} |
|
|
void |
void |
puffs_makecn(struct puffs_cn *pcn, const struct componentname *cn) |
puffs_makecn(struct puffs_kcn *pkcn, const struct componentname *cn) |
{ |
{ |
|
|
pcn->pcn_nameiop = cn->cn_nameiop; |
pkcn->pkcn_nameiop = cn->cn_nameiop; |
pcn->pcn_flags = cn->cn_flags; |
pkcn->pkcn_flags = cn->cn_flags; |
pcn->pcn_pid = cn->cn_lwp->l_proc->p_pid; |
pkcn->pkcn_pid = cn->cn_lwp->l_proc->p_pid; |
puffs_credcvt(&pcn->pcn_cred, cn->cn_cred); |
puffs_credcvt(&pkcn->pkcn_cred, cn->cn_cred); |
|
|
(void)memcpy(&pcn->pcn_name, cn->cn_nameptr, cn->cn_namelen); |
(void)memcpy(&pkcn->pkcn_name, cn->cn_nameptr, cn->cn_namelen); |
pcn->pcn_name[cn->cn_namelen] = '\0'; |
pkcn->pkcn_name[cn->cn_namelen] = '\0'; |
pcn->pcn_namelen = cn->cn_namelen; |
pkcn->pkcn_namelen = cn->cn_namelen; |
} |
} |
|
|
/* |
/* |
Line 385 puffs_updatevpsize(struct vnode *vp) |
|
Line 397 puffs_updatevpsize(struct vnode *vp) |
|
if (va.va_size != VNOVAL) |
if (va.va_size != VNOVAL) |
vp->v_size = va.va_size; |
vp->v_size = va.va_size; |
} |
} |
|
|
|
/* |
|
* We're dead, kaput, RIP, slightly more than merely pining for the |
|
* fjords, belly-up, fallen, lifeless, finished, expired, gone to meet |
|
* our maker, ceased to be, etcetc. YASD. It's a dead FS! |
|
*/ |
|
void |
|
puffs_userdead(struct puffs_mount *pmp) |
|
{ |
|
struct puffs_park *park; |
|
|
|
simple_lock(&pmp->pmp_lock); |
|
|
|
/* |
|
* Mark filesystem status as dying so that operations don't |
|
* attempt to march to userspace any longer. |
|
*/ |
|
pmp->pmp_status = PUFFSTAT_DYING; |
|
|
|
/* and wakeup processes waiting for a reply from userspace */ |
|
TAILQ_FOREACH(park, &pmp->pmp_req_replywait, park_entries) { |
|
park->park_preq->preq_rv = ENXIO; |
|
TAILQ_REMOVE(&pmp->pmp_req_replywait, park, park_entries); |
|
wakeup(park); |
|
} |
|
|
|
/* wakeup waiters for completion of vfs/vnode requests */ |
|
TAILQ_FOREACH(park, &pmp->pmp_req_touser, park_entries) { |
|
park->park_preq->preq_rv = ENXIO; |
|
TAILQ_REMOVE(&pmp->pmp_req_touser, park, park_entries); |
|
wakeup(park); |
|
} |
|
|
|
simple_unlock(&pmp->pmp_lock); |
|
} |