version 1.113, 2007/10/26 16:54:50 |
version 1.113.2.2, 2007/12/08 18:20:18 |
Line 405 static int puffs_callremove(struct puffs |
|
Line 405 static int puffs_callremove(struct puffs |
|
struct componentname *); |
struct componentname *); |
static int puffs_callrmdir(struct puffs_mount *, void *, void *, |
static int puffs_callrmdir(struct puffs_mount *, void *, void *, |
struct componentname *); |
struct componentname *); |
static void puffs_callinactive(struct puffs_mount *, void *, int, struct lwp *); |
static void puffs_callinactive(struct puffs_mount *, void *, int); |
static void puffs_callreclaim(struct puffs_mount *, void *, struct lwp *); |
static void puffs_callreclaim(struct puffs_mount *, void *); |
|
|
#define PUFFS_ABORT_LOOKUP 1 |
#define PUFFS_ABORT_LOOKUP 1 |
#define PUFFS_ABORT_CREATE 2 |
#define PUFFS_ABORT_CREATE 2 |
Line 433 puffs_abortbutton(struct puffs_mount *pm |
|
Line 433 puffs_abortbutton(struct puffs_mount *pm |
|
break; |
break; |
} |
} |
|
|
puffs_callinactive(pmp, cookie, 0, cnp->cn_lwp); |
puffs_callinactive(pmp, cookie, 0); |
puffs_callreclaim(pmp, cookie, cnp->cn_lwp); |
puffs_callreclaim(pmp, cookie); |
} |
} |
|
|
|
/* |
|
* Begin vnode operations. |
|
* |
|
* A word from the keymaster about locks: generally we don't want |
|
* to use the vnode locks at all: it creates an ugly dependency between |
|
* the userlandia file server and the kernel. But we'll play along with |
|
* the kernel vnode locks for now. However, even currently we attempt |
|
* to release locks as early as possible. This is possible for some |
|
* operations which a) don't need a locked vnode after the userspace op |
|
* and b) return with the vnode unlocked. Theoretically we could |
|
* unlock-do op-lock for others and order the graph in userspace, but I |
|
* don't want to think of the consequences for the time being. |
|
*/ |
|
|
int |
int |
puffs_lookup(void *v) |
puffs_lookup(void *v) |
{ |
{ |
Line 494 puffs_lookup(void *v) |
|
Line 508 puffs_lookup(void *v) |
|
if (cnp->cn_flags & ISDOTDOT) |
if (cnp->cn_flags & ISDOTDOT) |
VOP_UNLOCK(dvp, 0); |
VOP_UNLOCK(dvp, 0); |
|
|
error = puffs_msg_vn(pmp, park_lookup, PUFFS_VN_LOOKUP, 0, dvp, NULL); |
puffs_msg_setinfo(park_lookup, PUFFSOP_VN, |
|
PUFFS_VN_LOOKUP, VPTOPNC(dvp)); |
|
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_lookup, dvp->v_data, NULL, error); |
DPRINTF(("puffs_lookup: return of the userspace, part %d\n", error)); |
DPRINTF(("puffs_lookup: return of the userspace, part %d\n", error)); |
|
|
/* |
/* |
Line 535 puffs_lookup(void *v) |
|
Line 551 puffs_lookup(void *v) |
|
*/ |
*/ |
dpn = dvp->v_data; |
dpn = dvp->v_data; |
if (lookup_msg->pvnr_newnode == dpn->pn_cookie) { |
if (lookup_msg->pvnr_newnode == dpn->pn_cookie) { |
puffs_msg_errnotify(pmp, PUFFS_ERR_LOOKUP, EINVAL, |
puffs_senderr(pmp, PUFFS_ERR_LOOKUP, EINVAL, |
"lookup produced parent cookie", lookup_msg->pvnr_newnode); |
"lookup produced parent cookie", lookup_msg->pvnr_newnode); |
error = EPROTO; |
error = EPROTO; |
goto out; |
goto out; |
Line 579 puffs_lookup(void *v) |
|
Line 595 puffs_lookup(void *v) |
|
return error; |
return error; |
} |
} |
|
|
|
#define REFPN_AND_UNLOCKVP(a, b) \ |
|
do { \ |
|
mutex_enter(&b->pn_mtx); \ |
|
puffs_referencenode(b); \ |
|
mutex_exit(&b->pn_mtx); \ |
|
VOP_UNLOCK(a, 0); \ |
|
} while (/*CONSTCOND*/0) |
|
|
|
#define REFPN(b) \ |
|
do { \ |
|
mutex_enter(&b->pn_mtx); \ |
|
puffs_referencenode(b); \ |
|
mutex_exit(&b->pn_mtx); \ |
|
} while (/*CONSTCOND*/0) |
|
|
|
#define RELEPN_AND_VP(a, b) \ |
|
do { \ |
|
puffs_releasenode(b); \ |
|
vrele(a); \ |
|
} while (/*CONSTCOND*/0) |
|
|
int |
int |
puffs_create(void *v) |
puffs_create(void *v) |
{ |
{ |
Line 591 puffs_create(void *v) |
|
Line 628 puffs_create(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, create); |
PUFFS_MSG_VARS(vn, create); |
struct vnode *dvp = ap->a_dvp; |
struct vnode *dvp = ap->a_dvp; |
|
struct puffs_node *dpn = VPTOPP(dvp); |
struct componentname *cnp = ap->a_cnp; |
struct componentname *cnp = ap->a_cnp; |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct mount *mp = dvp->v_mount; |
|
struct puffs_mount *pmp = MPTOPUFFSMP(mp); |
int error; |
int error; |
|
|
DPRINTF(("puffs_create: dvp %p, cnp: %s\n", |
DPRINTF(("puffs_create: dvp %p, cnp: %s\n", |
Line 602 puffs_create(void *v) |
|
Line 641 puffs_create(void *v) |
|
puffs_makecn(&create_msg->pvnr_cn, &create_msg->pvnr_cn_cred, |
puffs_makecn(&create_msg->pvnr_cn, &create_msg->pvnr_cn_cred, |
&create_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&create_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
create_msg->pvnr_va = *ap->a_vap; |
create_msg->pvnr_va = *ap->a_vap; |
|
puffs_msg_setinfo(park_create, PUFFSOP_VN, |
|
PUFFS_VN_CREATE, VPTOPNC(dvp)); |
|
|
|
/* |
|
* Do the dance: |
|
* + insert into queue ("interlock") |
|
* + unlock vnode |
|
* + wait for response |
|
*/ |
|
puffs_msg_enqueue(pmp, park_create); |
|
REFPN_AND_UNLOCKVP(dvp, dpn); |
|
error = puffs_msg_wait2(pmp, park_create, dpn, NULL); |
|
|
error = puffs_msg_vn(pmp, park_create, PUFFS_VN_CREATE, 0, dvp, NULL); |
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
goto out; |
goto out; |
|
|
error = puffs_newnode(dvp->v_mount, dvp, ap->a_vpp, |
error = puffs_newnode(mp, dvp, ap->a_vpp, |
create_msg->pvnr_newnode, cnp, ap->a_vap->va_type, 0); |
create_msg->pvnr_newnode, cnp, ap->a_vap->va_type, 0); |
if (error) |
if (error) |
puffs_abortbutton(pmp, PUFFS_ABORT_CREATE, VPTOPNC(dvp), |
puffs_abortbutton(pmp, PUFFS_ABORT_CREATE, dpn->pn_cookie, |
create_msg->pvnr_newnode, cnp); |
create_msg->pvnr_newnode, cnp); |
|
|
out: |
out: |
if (error || (cnp->cn_flags & SAVESTART) == 0) |
if (error || (cnp->cn_flags & SAVESTART) == 0) |
PNBUF_PUT(cnp->cn_pnbuf); |
PNBUF_PUT(cnp->cn_pnbuf); |
vput(dvp); |
|
|
|
|
RELEPN_AND_VP(dvp, dpn); |
DPRINTF(("puffs_create: return %d\n", error)); |
DPRINTF(("puffs_create: return %d\n", error)); |
PUFFS_MSG_RELEASE(create); |
PUFFS_MSG_RELEASE(create); |
return error; |
return error; |
Line 636 puffs_mknod(void *v) |
|
Line 686 puffs_mknod(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, mknod); |
PUFFS_MSG_VARS(vn, mknod); |
struct vnode *dvp = ap->a_dvp; |
struct vnode *dvp = ap->a_dvp; |
|
struct puffs_node *dpn = VPTOPP(dvp); |
struct componentname *cnp = ap->a_cnp; |
struct componentname *cnp = ap->a_cnp; |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct mount *mp = dvp->v_mount; |
|
struct puffs_mount *pmp = MPTOPUFFSMP(mp); |
int error; |
int error; |
|
|
PUFFS_MSG_ALLOC(vn, mknod); |
PUFFS_MSG_ALLOC(vn, mknod); |
puffs_makecn(&mknod_msg->pvnr_cn, &mknod_msg->pvnr_cn_cred, |
puffs_makecn(&mknod_msg->pvnr_cn, &mknod_msg->pvnr_cn_cred, |
&mknod_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&mknod_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
mknod_msg->pvnr_va = *ap->a_vap; |
mknod_msg->pvnr_va = *ap->a_vap; |
|
puffs_msg_setinfo(park_mknod, PUFFSOP_VN, |
|
PUFFS_VN_MKNOD, VPTOPNC(dvp)); |
|
|
|
puffs_msg_enqueue(pmp, park_mknod); |
|
REFPN_AND_UNLOCKVP(dvp, dpn); |
|
error = puffs_msg_wait2(pmp, park_mknod, dpn, NULL); |
|
|
error = puffs_msg_vn(pmp, park_mknod, PUFFS_VN_MKNOD, 0, dvp, NULL); |
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
goto out; |
goto out; |
|
|
error = puffs_newnode(dvp->v_mount, dvp, ap->a_vpp, |
error = puffs_newnode(mp, dvp, ap->a_vpp, |
mknod_msg->pvnr_newnode, cnp, ap->a_vap->va_type, |
mknod_msg->pvnr_newnode, cnp, ap->a_vap->va_type, |
ap->a_vap->va_rdev); |
ap->a_vap->va_rdev); |
if (error) |
if (error) |
puffs_abortbutton(pmp, PUFFS_ABORT_MKNOD, VPTOPNC(dvp), |
puffs_abortbutton(pmp, PUFFS_ABORT_MKNOD, dpn->pn_cookie, |
mknod_msg->pvnr_newnode, cnp); |
mknod_msg->pvnr_newnode, cnp); |
|
|
out: |
out: |
PUFFS_MSG_RELEASE(mknod); |
PUFFS_MSG_RELEASE(mknod); |
if (error || (cnp->cn_flags & SAVESTART) == 0) |
if (error || (cnp->cn_flags & SAVESTART) == 0) |
PNBUF_PUT(cnp->cn_pnbuf); |
PNBUF_PUT(cnp->cn_pnbuf); |
vput(dvp); |
RELEPN_AND_VP(dvp, dpn); |
return error; |
return error; |
} |
} |
|
|
Line 673 puffs_open(void *v) |
|
Line 730 puffs_open(void *v) |
|
struct vnode *a_vp; |
struct vnode *a_vp; |
int a_mode; |
int a_mode; |
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, open); |
PUFFS_MSG_VARS(vn, open); |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
Line 692 puffs_open(void *v) |
|
Line 748 puffs_open(void *v) |
|
PUFFS_MSG_ALLOC(vn, open); |
PUFFS_MSG_ALLOC(vn, open); |
open_msg->pvnr_mode = mode; |
open_msg->pvnr_mode = mode; |
puffs_credcvt(&open_msg->pvnr_cred, ap->a_cred); |
puffs_credcvt(&open_msg->pvnr_cred, ap->a_cred); |
puffs_cidcvt(&open_msg->pvnr_cid, ap->a_l); |
puffs_msg_setinfo(park_open, PUFFSOP_VN, |
|
PUFFS_VN_OPEN, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_open, PUFFS_VN_OPEN, 0, vp, NULL); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_open, vp->v_data, NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
|
|
out: |
out: |
Line 711 puffs_close(void *v) |
|
Line 768 puffs_close(void *v) |
|
struct vnode *a_vp; |
struct vnode *a_vp; |
int a_fflag; |
int a_fflag; |
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, close); |
PUFFS_MSG_VARS(vn, close); |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
Line 721 puffs_close(void *v) |
|
Line 777 puffs_close(void *v) |
|
puffs_msg_setfaf(park_close); |
puffs_msg_setfaf(park_close); |
close_msg->pvnr_fflag = ap->a_fflag; |
close_msg->pvnr_fflag = ap->a_fflag; |
puffs_credcvt(&close_msg->pvnr_cred, ap->a_cred); |
puffs_credcvt(&close_msg->pvnr_cred, ap->a_cred); |
puffs_cidcvt(&close_msg->pvnr_cid, ap->a_l); |
puffs_msg_setinfo(park_close, PUFFSOP_VN, |
|
PUFFS_VN_CLOSE, VPTOPNC(vp)); |
puffs_msg_vn(pmp, park_close, PUFFS_VN_CLOSE, 0, vp, NULL); |
|
|
|
|
puffs_msg_enqueue(pmp, park_close); |
PUFFS_MSG_RELEASE(close); |
PUFFS_MSG_RELEASE(close); |
return 0; |
return 0; |
} |
} |
Line 737 puffs_access(void *v) |
|
Line 793 puffs_access(void *v) |
|
struct vnode *a_vp; |
struct vnode *a_vp; |
int a_mode; |
int a_mode; |
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, access); |
PUFFS_MSG_VARS(vn, access); |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
Line 765 puffs_access(void *v) |
|
Line 820 puffs_access(void *v) |
|
PUFFS_MSG_ALLOC(vn, access); |
PUFFS_MSG_ALLOC(vn, access); |
access_msg->pvnr_mode = ap->a_mode; |
access_msg->pvnr_mode = ap->a_mode; |
puffs_credcvt(&access_msg->pvnr_cred, ap->a_cred); |
puffs_credcvt(&access_msg->pvnr_cred, ap->a_cred); |
puffs_cidcvt(&access_msg->pvnr_cid, ap->a_l); |
puffs_msg_setinfo(park_access, PUFFSOP_VN, |
|
PUFFS_VN_ACCESS, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_access, PUFFS_VN_ACCESS, 0, vp, NULL); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_access, vp->v_data, NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
PUFFS_MSG_RELEASE(access); |
PUFFS_MSG_RELEASE(access); |
|
|
Line 782 puffs_getattr(void *v) |
|
Line 838 puffs_getattr(void *v) |
|
struct vnode *a_vp; |
struct vnode *a_vp; |
struct vattr *a_vap; |
struct vattr *a_vap; |
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, getattr); |
PUFFS_MSG_VARS(vn, getattr); |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
Line 797 puffs_getattr(void *v) |
|
Line 852 puffs_getattr(void *v) |
|
PUFFS_MSG_ALLOC(vn, getattr); |
PUFFS_MSG_ALLOC(vn, getattr); |
vattr_null(&getattr_msg->pvnr_va); |
vattr_null(&getattr_msg->pvnr_va); |
puffs_credcvt(&getattr_msg->pvnr_cred, ap->a_cred); |
puffs_credcvt(&getattr_msg->pvnr_cred, ap->a_cred); |
puffs_cidcvt(&getattr_msg->pvnr_cid, ap->a_l); |
puffs_msg_setinfo(park_getattr, PUFFSOP_VN, |
|
PUFFS_VN_GETATTR, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_getattr, PUFFS_VN_GETATTR, 0, vp, NULL); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_getattr, vp->v_data, NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
goto out; |
goto out; |
Line 845 puffs_getattr(void *v) |
|
Line 901 puffs_getattr(void *v) |
|
|
|
static int |
static int |
puffs_dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, |
puffs_dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, |
struct lwp *l, int chsize) |
int chsize) |
{ |
{ |
PUFFS_MSG_VARS(vn, setattr); |
PUFFS_MSG_VARS(vn, setattr); |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
Line 887 puffs_dosetattr(struct vnode *vp, struct |
|
Line 943 puffs_dosetattr(struct vnode *vp, struct |
|
PUFFS_MSG_ALLOC(vn, setattr); |
PUFFS_MSG_ALLOC(vn, setattr); |
(void)memcpy(&setattr_msg->pvnr_va, vap, sizeof(struct vattr)); |
(void)memcpy(&setattr_msg->pvnr_va, vap, sizeof(struct vattr)); |
puffs_credcvt(&setattr_msg->pvnr_cred, cred); |
puffs_credcvt(&setattr_msg->pvnr_cred, cred); |
puffs_cidcvt(&setattr_msg->pvnr_cid, l); |
puffs_msg_setinfo(park_setattr, PUFFSOP_VN, |
|
PUFFS_VN_SETATTR, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_setattr, PUFFS_VN_SETATTR, 0, vp, NULL); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_setattr, vp->v_data, NULL, error); |
PUFFS_MSG_RELEASE(setattr); |
PUFFS_MSG_RELEASE(setattr); |
|
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
return error; |
return error; |
Line 913 puffs_setattr(void *v) |
|
Line 969 puffs_setattr(void *v) |
|
struct vnode *a_vp; |
struct vnode *a_vp; |
struct vattr *a_vap; |
struct vattr *a_vap; |
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
|
|
return puffs_dosetattr(ap->a_vp, ap->a_vap, ap->a_cred, ap->a_l, 1); |
return puffs_dosetattr(ap->a_vp, ap->a_vap, ap->a_cred, 1); |
} |
} |
|
|
static __inline int |
static __inline int |
Line 936 doinact(struct puffs_mount *pmp, int iaf |
|
Line 991 doinact(struct puffs_mount *pmp, int iaf |
|
} |
} |
|
|
static void |
static void |
puffs_callinactive(struct puffs_mount *pmp, void *cookie, int iaflag, |
puffs_callinactive(struct puffs_mount *pmp, void *cookie, int iaflag) |
struct lwp *l) |
|
{ |
{ |
|
int error; |
PUFFS_MSG_VARS(vn, inactive); |
PUFFS_MSG_VARS(vn, inactive); |
|
|
if (doinact(pmp, iaflag)) { |
if (doinact(pmp, iaflag)) { |
struct puffs_req *preq; |
|
|
|
PUFFS_MSG_ALLOC(vn, inactive); |
PUFFS_MSG_ALLOC(vn, inactive); |
puffs_cidcvt(&inactive_msg->pvnr_cid, l); |
puffs_msg_setinfo(park_inactive, PUFFSOP_VN, |
preq = (struct puffs_req *)inactive_msg; |
PUFFS_VN_INACTIVE, cookie); |
preq->preq_cookie = cookie; |
|
preq->preq_opclass = PUFFSOP_VN; |
|
preq->preq_optype = PUFFS_VN_INACTIVE; |
|
|
|
puffs_msg_raw(pmp, park_inactive); |
PUFFS_MSG_ENQUEUEWAIT(pmp, park_inactive, error); |
PUFFS_MSG_RELEASE(inactive); |
PUFFS_MSG_RELEASE(inactive); |
} |
} |
} |
} |
Line 963 puffs_inactive(void *v) |
|
Line 1013 puffs_inactive(void *v) |
|
struct vop_inactive_args /* { |
struct vop_inactive_args /* { |
const struct vnodeop_desc *a_desc; |
const struct vnodeop_desc *a_desc; |
struct vnode *a_vp; |
struct vnode *a_vp; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, inactive); |
PUFFS_MSG_VARS(vn, inactive); |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
struct puffs_node *pnode; |
struct puffs_node *pnode; |
|
int error; |
|
|
pnode = vp->v_data; |
pnode = vp->v_data; |
|
|
if (doinact(pmp, pnode->pn_stat & PNODE_DOINACT)) { |
if (doinact(pmp, pnode->pn_stat & PNODE_DOINACT)) { |
PUFFS_MSG_ALLOC(vn, inactive); |
PUFFS_MSG_ALLOC(vn, inactive); |
puffs_cidcvt(&inactive_msg->pvnr_cid, ap->a_l); |
puffs_msg_setinfo(park_inactive, PUFFSOP_VN, |
puffs_msg_vn(pmp, park_inactive, PUFFS_VN_INACTIVE, 0, vp,NULL); |
PUFFS_VN_INACTIVE, VPTOPNC(vp)); |
|
|
|
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_inactive, vp->v_data, |
|
NULL, error); |
PUFFS_MSG_RELEASE(inactive); |
PUFFS_MSG_RELEASE(inactive); |
} |
} |
pnode->pn_stat &= ~PNODE_DOINACT; |
pnode->pn_stat &= ~PNODE_DOINACT; |
Line 988 puffs_inactive(void *v) |
|
Line 1041 puffs_inactive(void *v) |
|
*/ |
*/ |
if (pnode->pn_stat & PNODE_NOREFS) { |
if (pnode->pn_stat & PNODE_NOREFS) { |
pnode->pn_stat |= PNODE_DYING; |
pnode->pn_stat |= PNODE_DYING; |
vrecycle(vp, NULL, ap->a_l); |
vrecycle(vp, NULL, curlwp); |
} |
} |
|
|
return 0; |
return 0; |
} |
} |
|
|
static void |
static void |
puffs_callreclaim(struct puffs_mount *pmp, void *cookie, struct lwp *l) |
puffs_callreclaim(struct puffs_mount *pmp, void *cookie) |
{ |
{ |
PUFFS_MSG_VARS(vn, reclaim); |
PUFFS_MSG_VARS(vn, reclaim); |
struct puffs_req *preq; |
|
|
|
if (!EXISTSOP(pmp, RECLAIM)) |
if (!EXISTSOP(pmp, RECLAIM)) |
return; |
return; |
|
|
PUFFS_MSG_ALLOC(vn, reclaim); |
PUFFS_MSG_ALLOC(vn, reclaim); |
puffs_msg_setfaf(park_reclaim); |
puffs_msg_setfaf(park_reclaim); |
puffs_cidcvt(&reclaim_msg->pvnr_cid, l); |
puffs_msg_setinfo(park_reclaim, PUFFSOP_VN, PUFFS_VN_RECLAIM, cookie); |
|
|
preq = (struct puffs_req *)reclaim_msg; |
puffs_msg_enqueue(pmp, park_reclaim); |
preq->preq_cookie = cookie; |
|
preq->preq_opclass = PUFFSOP_VN; |
|
preq->preq_optype = PUFFS_VN_RECLAIM; |
|
|
|
puffs_msg_raw(pmp, park_reclaim); |
|
PUFFS_MSG_RELEASE(reclaim); |
PUFFS_MSG_RELEASE(reclaim); |
} |
} |
|
|
Line 1026 puffs_reclaim(void *v) |
|
Line 1073 puffs_reclaim(void *v) |
|
struct vop_reclaim_args /* { |
struct vop_reclaim_args /* { |
const struct vnodeop_desc *a_desc; |
const struct vnodeop_desc *a_desc; |
struct vnode *a_vp; |
struct vnode *a_vp; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
Line 1045 puffs_reclaim(void *v) |
|
Line 1091 puffs_reclaim(void *v) |
|
goto out; |
goto out; |
} |
} |
|
|
puffs_callreclaim(MPTOPUFFSMP(vp->v_mount), VPTOPNC(vp), ap->a_l); |
puffs_callreclaim(MPTOPUFFSMP(vp->v_mount), VPTOPNC(vp)); |
|
|
out: |
out: |
if (PUFFS_USE_NAMECACHE(pmp)) |
if (PUFFS_USE_NAMECACHE(pmp)) |
Line 1119 puffs_readdir(void *v) |
|
Line 1165 puffs_readdir(void *v) |
|
readdir_msg->pvnr_ncookies = cookiesmax; |
readdir_msg->pvnr_ncookies = cookiesmax; |
readdir_msg->pvnr_eofflag = 0; |
readdir_msg->pvnr_eofflag = 0; |
readdir_msg->pvnr_dentoff = cookiemem; |
readdir_msg->pvnr_dentoff = cookiemem; |
|
puffs_msg_setinfo(park_readdir, PUFFSOP_VN, |
|
PUFFS_VN_READDIR, VPTOPNC(vp)); |
|
puffs_msg_setdelta(park_readdir, tomove); |
|
|
error = puffs_msg_vn(pmp, park_readdir, PUFFS_VN_READDIR, |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_readdir, vp->v_data, NULL, error); |
tomove, vp, NULL); |
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
goto out; |
goto out; |
|
|
/* userspace is cheating? */ |
/* userspace is cheating? */ |
if (readdir_msg->pvnr_resid > resid) { |
if (readdir_msg->pvnr_resid > resid) { |
puffs_msg_errnotify(pmp, PUFFS_ERR_READDIR, E2BIG, |
puffs_senderr(pmp, PUFFS_ERR_READDIR, E2BIG, |
"resid grew", VPTOPNC(vp)); |
"resid grew", VPTOPNC(vp)); |
ERROUT(EPROTO); |
ERROUT(EPROTO); |
} |
} |
if (readdir_msg->pvnr_ncookies > cookiesmax) { |
if (readdir_msg->pvnr_ncookies > cookiesmax) { |
puffs_msg_errnotify(pmp, PUFFS_ERR_READDIR, E2BIG, |
puffs_senderr(pmp, PUFFS_ERR_READDIR, E2BIG, |
"too many cookies", VPTOPNC(vp)); |
"too many cookies", VPTOPNC(vp)); |
ERROUT(EPROTO); |
ERROUT(EPROTO); |
} |
} |
Line 1190 puffs_poll(void *v) |
|
Line 1238 puffs_poll(void *v) |
|
const struct vnodeop_desc *a_desc; |
const struct vnodeop_desc *a_desc; |
struct vnode *a_vp; |
struct vnode *a_vp; |
int a_events; |
int a_events; |
struct lwp *a_l; |
|
}/ *ap = v; |
}/ *ap = v; |
PUFFS_MSG_VARS(vn, poll); |
PUFFS_MSG_VARS(vn, poll); |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
struct puffs_node *pn = vp->v_data; |
struct puffs_node *pn = vp->v_data; |
int events; |
int events, error; |
|
|
if (EXISTSOP(pmp, POLL)) { |
if (EXISTSOP(pmp, POLL)) { |
mutex_enter(&pn->pn_mtx); |
mutex_enter(&pn->pn_mtx); |
Line 1212 puffs_poll(void *v) |
|
Line 1259 puffs_poll(void *v) |
|
|
|
PUFFS_MSG_ALLOC(vn, poll); |
PUFFS_MSG_ALLOC(vn, poll); |
poll_msg->pvnr_events = ap->a_events; |
poll_msg->pvnr_events = ap->a_events; |
puffs_cidcvt(&poll_msg->pvnr_cid, ap->a_l); |
puffs_msg_setinfo(park_poll, PUFFSOP_VN, |
|
PUFFS_VN_POLL, VPTOPNC(vp)); |
|
puffs_msg_setcall(park_poll, puffs_parkdone_poll, pn); |
|
selrecord(curlwp, &pn->pn_sel); |
|
|
selrecord(ap->a_l, &pn->pn_sel); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_poll, vp->v_data, |
puffs_msg_vncall(pmp, park_poll, PUFFS_VN_POLL, 0, |
NULL, error); |
puffs_parkdone_poll, pn, vp); |
|
PUFFS_MSG_RELEASE(poll); |
PUFFS_MSG_RELEASE(poll); |
|
|
return 0; |
return 0; |
Line 1236 puffs_fsync(void *v) |
|
Line 1285 puffs_fsync(void *v) |
|
int a_flags; |
int a_flags; |
off_t a_offlo; |
off_t a_offlo; |
off_t a_offhi; |
off_t a_offhi; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, fsync); |
PUFFS_MSG_VARS(vn, fsync); |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
Line 1251 puffs_fsync(void *v) |
|
Line 1299 puffs_fsync(void *v) |
|
if (pn->pn_stat & PNODE_METACACHE_MASK |
if (pn->pn_stat & PNODE_METACACHE_MASK |
&& (pn->pn_stat & PNODE_DYING) == 0) { |
&& (pn->pn_stat & PNODE_DYING) == 0) { |
vattr_null(&va); |
vattr_null(&va); |
error = VOP_SETATTR(vp, &va, FSCRED, NULL); |
error = VOP_SETATTR(vp, &va, FSCRED); |
if (error) |
if (error) |
return error; |
return error; |
} |
} |
Line 1300 puffs_fsync(void *v) |
|
Line 1348 puffs_fsync(void *v) |
|
fsync_msg->pvnr_flags = ap->a_flags; |
fsync_msg->pvnr_flags = ap->a_flags; |
fsync_msg->pvnr_offlo = ap->a_offlo; |
fsync_msg->pvnr_offlo = ap->a_offlo; |
fsync_msg->pvnr_offhi = ap->a_offhi; |
fsync_msg->pvnr_offhi = ap->a_offhi; |
puffs_cidcvt(&fsync_msg->pvnr_cid, ap->a_l); |
puffs_msg_setinfo(park_fsync, PUFFSOP_VN, |
|
PUFFS_VN_FSYNC, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_fsync, PUFFS_VN_FSYNC, 0, vp, NULL); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_fsync, vp->v_data, NULL, error); |
PUFFS_MSG_RELEASE(fsync); |
PUFFS_MSG_RELEASE(fsync); |
|
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
Line 1329 puffs_seek(void *v) |
|
Line 1378 puffs_seek(void *v) |
|
seek_msg->pvnr_oldoff = ap->a_oldoff; |
seek_msg->pvnr_oldoff = ap->a_oldoff; |
seek_msg->pvnr_newoff = ap->a_newoff; |
seek_msg->pvnr_newoff = ap->a_newoff; |
puffs_credcvt(&seek_msg->pvnr_cred, ap->a_cred); |
puffs_credcvt(&seek_msg->pvnr_cred, ap->a_cred); |
|
puffs_msg_setinfo(park_seek, PUFFSOP_VN, |
|
PUFFS_VN_SEEK, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_seek, PUFFS_VN_SEEK, 0, vp, NULL); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_seek, vp->v_data, NULL, error); |
PUFFS_MSG_RELEASE(seek); |
PUFFS_MSG_RELEASE(seek); |
return checkerr(pmp, error, __func__); |
return checkerr(pmp, error, __func__); |
} |
} |
Line 1340 puffs_callremove(struct puffs_mount *pmp |
|
Line 1391 puffs_callremove(struct puffs_mount *pmp |
|
struct componentname *cnp) |
struct componentname *cnp) |
{ |
{ |
PUFFS_MSG_VARS(vn, remove); |
PUFFS_MSG_VARS(vn, remove); |
struct puffs_req *preq; |
|
int error; |
int error; |
|
|
PUFFS_MSG_ALLOC(vn, remove); |
PUFFS_MSG_ALLOC(vn, remove); |
remove_msg->pvnr_cookie_targ = cookie; |
remove_msg->pvnr_cookie_targ = cookie; |
puffs_makecn(&remove_msg->pvnr_cn, &remove_msg->pvnr_cn_cred, |
puffs_makecn(&remove_msg->pvnr_cn, &remove_msg->pvnr_cn_cred, |
&remove_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&remove_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
|
puffs_msg_setinfo(park_remove, PUFFSOP_VN, PUFFS_VN_REMOVE, dcookie); |
|
|
/* XXX: uh, this is wrong because we don't get setbacks with raw */ |
PUFFS_MSG_ENQUEUEWAIT(pmp, park_remove, error); |
preq = (struct puffs_req *)remove_msg; |
|
preq->preq_cookie = dcookie; |
|
preq->preq_opclass = PUFFSOP_VN; |
|
preq->preq_optype = PUFFS_VN_REMOVE; |
|
|
|
error = puffs_msg_raw(pmp, park_remove); |
|
PUFFS_MSG_RELEASE(remove); |
PUFFS_MSG_RELEASE(remove); |
|
|
return checkerr(pmp, error, __func__); |
return checkerr(pmp, error, __func__); |
Line 1362 puffs_callremove(struct puffs_mount *pmp |
|
Line 1407 puffs_callremove(struct puffs_mount *pmp |
|
|
|
/* |
/* |
* XXX: can't use callremove now because can't catch setbacks with |
* XXX: can't use callremove now because can't catch setbacks with |
* it due to lack of a vnode argument. |
* it due to lack of a pnode argument. |
*/ |
*/ |
int |
int |
puffs_remove(void *v) |
puffs_remove(void *v) |
Line 1376 puffs_remove(void *v) |
|
Line 1421 puffs_remove(void *v) |
|
PUFFS_MSG_VARS(vn, remove); |
PUFFS_MSG_VARS(vn, remove); |
struct vnode *dvp = ap->a_dvp; |
struct vnode *dvp = ap->a_dvp; |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct puffs_node *dpn = VPTOPP(dvp); |
|
struct puffs_node *pn = VPTOPP(vp); |
struct componentname *cnp = ap->a_cnp; |
struct componentname *cnp = ap->a_cnp; |
|
struct mount *mp = dvp->v_mount; |
|
struct puffs_mount *pmp = MPTOPUFFSMP(mp); |
int error; |
int error; |
|
|
PUFFS_MSG_ALLOC(vn, remove); |
PUFFS_MSG_ALLOC(vn, remove); |
remove_msg->pvnr_cookie_targ = VPTOPNC(vp); |
remove_msg->pvnr_cookie_targ = VPTOPNC(vp); |
puffs_makecn(&remove_msg->pvnr_cn, &remove_msg->pvnr_cn_cred, |
puffs_makecn(&remove_msg->pvnr_cn, &remove_msg->pvnr_cn_cred, |
&remove_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&remove_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
|
puffs_msg_setinfo(park_remove, PUFFSOP_VN, |
|
PUFFS_VN_REMOVE, VPTOPNC(dvp)); |
|
|
error = puffs_msg_vn(pmp, park_remove, PUFFS_VN_REMOVE, 0, dvp, vp); |
puffs_msg_enqueue(pmp, park_remove); |
PUFFS_MSG_RELEASE(remove); |
REFPN_AND_UNLOCKVP(dvp, dpn); |
|
|
error = checkerr(pmp, error, __func__); |
|
vput(vp); |
|
if (dvp == vp) |
if (dvp == vp) |
vrele(dvp); |
REFPN(pn); |
else |
else |
vput(dvp); |
REFPN_AND_UNLOCKVP(vp, pn); |
|
error = puffs_msg_wait2(pmp, park_remove, dpn, pn); |
|
|
|
PUFFS_MSG_RELEASE(remove); |
|
|
|
RELEPN_AND_VP(dvp, dpn); |
|
RELEPN_AND_VP(vp, pn); |
|
|
|
error = checkerr(pmp, error, __func__); |
return error; |
return error; |
} |
} |
|
|
Line 1410 puffs_mkdir(void *v) |
|
Line 1464 puffs_mkdir(void *v) |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, mkdir); |
PUFFS_MSG_VARS(vn, mkdir); |
struct vnode *dvp = ap->a_dvp; |
struct vnode *dvp = ap->a_dvp; |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct puffs_node *dpn = VPTOPP(dvp); |
struct componentname *cnp = ap->a_cnp; |
struct componentname *cnp = ap->a_cnp; |
|
struct mount *mp = dvp->v_mount; |
|
struct puffs_mount *pmp = MPTOPUFFSMP(mp); |
int error; |
int error; |
|
|
PUFFS_MSG_ALLOC(vn, mkdir); |
PUFFS_MSG_ALLOC(vn, mkdir); |
puffs_makecn(&mkdir_msg->pvnr_cn, &mkdir_msg->pvnr_cn_cred, |
puffs_makecn(&mkdir_msg->pvnr_cn, &mkdir_msg->pvnr_cn_cred, |
&mkdir_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&mkdir_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
mkdir_msg->pvnr_va = *ap->a_vap; |
mkdir_msg->pvnr_va = *ap->a_vap; |
|
puffs_msg_setinfo(park_mkdir, PUFFSOP_VN, |
|
PUFFS_VN_MKDIR, VPTOPNC(dvp)); |
|
|
|
puffs_msg_enqueue(pmp, park_mkdir); |
|
REFPN_AND_UNLOCKVP(dvp, dpn); |
|
error = puffs_msg_wait2(pmp, park_mkdir, dpn, NULL); |
|
|
error = puffs_msg_vn(pmp, park_mkdir, PUFFS_VN_MKDIR, 0, dvp, NULL); |
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
goto out; |
goto out; |
|
|
error = puffs_newnode(dvp->v_mount, dvp, ap->a_vpp, |
error = puffs_newnode(mp, dvp, ap->a_vpp, |
mkdir_msg->pvnr_newnode, cnp, VDIR, 0); |
mkdir_msg->pvnr_newnode, cnp, VDIR, 0); |
if (error) |
if (error) |
puffs_abortbutton(pmp, PUFFS_ABORT_MKDIR, VPTOPNC(ap->a_dvp), |
puffs_abortbutton(pmp, PUFFS_ABORT_MKDIR, dpn->pn_cookie, |
mkdir_msg->pvnr_newnode, cnp); |
mkdir_msg->pvnr_newnode, cnp); |
|
|
out: |
out: |
PUFFS_MSG_RELEASE(mkdir); |
PUFFS_MSG_RELEASE(mkdir); |
if (error || (cnp->cn_flags & SAVESTART) == 0) |
if (error || (cnp->cn_flags & SAVESTART) == 0) |
PNBUF_PUT(cnp->cn_pnbuf); |
PNBUF_PUT(cnp->cn_pnbuf); |
vput(ap->a_dvp); |
RELEPN_AND_VP(dvp, dpn); |
return error; |
return error; |
} |
} |
|
|
Line 1443 puffs_callrmdir(struct puffs_mount *pmp, |
|
Line 1504 puffs_callrmdir(struct puffs_mount *pmp, |
|
struct componentname *cnp) |
struct componentname *cnp) |
{ |
{ |
PUFFS_MSG_VARS(vn, rmdir); |
PUFFS_MSG_VARS(vn, rmdir); |
struct puffs_req *preq; |
|
int error; |
int error; |
|
|
PUFFS_MSG_ALLOC(vn, rmdir); |
PUFFS_MSG_ALLOC(vn, rmdir); |
rmdir_msg->pvnr_cookie_targ = cookie; |
rmdir_msg->pvnr_cookie_targ = cookie; |
puffs_makecn(&rmdir_msg->pvnr_cn, &rmdir_msg->pvnr_cn_cred, |
puffs_makecn(&rmdir_msg->pvnr_cn, &rmdir_msg->pvnr_cn_cred, |
&rmdir_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&rmdir_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
|
puffs_msg_setinfo(park_rmdir, PUFFSOP_VN, PUFFS_VN_RMDIR, dcookie); |
|
|
/* XXX: uh, this is wrong because we don't get setbacks with raw */ |
PUFFS_MSG_ENQUEUEWAIT(pmp, park_rmdir, error); |
preq = (struct puffs_req *)rmdir_msg; |
|
preq->preq_cookie = dcookie; |
|
preq->preq_opclass = PUFFSOP_VN; |
|
preq->preq_optype = PUFFS_VN_RMDIR; |
|
|
|
error = puffs_msg_raw(pmp, park_rmdir); |
|
PUFFS_MSG_RELEASE(rmdir); |
PUFFS_MSG_RELEASE(rmdir); |
|
|
return checkerr(pmp, error, __func__); |
return checkerr(pmp, error, __func__); |
Line 1475 puffs_rmdir(void *v) |
|
Line 1530 puffs_rmdir(void *v) |
|
PUFFS_MSG_VARS(vn, rmdir); |
PUFFS_MSG_VARS(vn, rmdir); |
struct vnode *dvp = ap->a_dvp; |
struct vnode *dvp = ap->a_dvp; |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
|
struct puffs_node *dpn = VPTOPP(dvp); |
|
struct puffs_node *pn = VPTOPP(vp); |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct componentname *cnp = ap->a_cnp; |
struct componentname *cnp = ap->a_cnp; |
int error; |
int error; |
Line 1483 puffs_rmdir(void *v) |
|
Line 1540 puffs_rmdir(void *v) |
|
rmdir_msg->pvnr_cookie_targ = VPTOPNC(vp); |
rmdir_msg->pvnr_cookie_targ = VPTOPNC(vp); |
puffs_makecn(&rmdir_msg->pvnr_cn, &rmdir_msg->pvnr_cn_cred, |
puffs_makecn(&rmdir_msg->pvnr_cn, &rmdir_msg->pvnr_cn_cred, |
&rmdir_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&rmdir_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
|
puffs_msg_setinfo(park_rmdir, PUFFSOP_VN, |
|
PUFFS_VN_RMDIR, VPTOPNC(dvp)); |
|
|
|
puffs_msg_enqueue(pmp, park_rmdir); |
|
REFPN_AND_UNLOCKVP(dvp, dpn); |
|
REFPN_AND_UNLOCKVP(vp, pn); |
|
error = puffs_msg_wait2(pmp, park_rmdir, dpn, pn); |
|
|
error = puffs_msg_vn(pmp, park_rmdir, PUFFS_VN_RMDIR, 0, dvp, vp); |
|
PUFFS_MSG_RELEASE(rmdir); |
PUFFS_MSG_RELEASE(rmdir); |
|
|
/* XXX: some call cache_purge() *for both vnodes* here, investigate */ |
/* XXX: some call cache_purge() *for both vnodes* here, investigate */ |
vput(dvp); |
RELEPN_AND_VP(dvp, dpn); |
vput(vp); |
RELEPN_AND_VP(vp, pn); |
|
|
return error; |
return error; |
} |
} |
Line 1506 puffs_link(void *v) |
|
Line 1569 puffs_link(void *v) |
|
PUFFS_MSG_VARS(vn, link); |
PUFFS_MSG_VARS(vn, link); |
struct vnode *dvp = ap->a_dvp; |
struct vnode *dvp = ap->a_dvp; |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
|
struct puffs_node *dpn = VPTOPP(dvp); |
|
struct puffs_node *pn = VPTOPP(vp); |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct componentname *cnp = ap->a_cnp; |
struct componentname *cnp = ap->a_cnp; |
int error; |
int error; |
Line 1514 puffs_link(void *v) |
|
Line 1579 puffs_link(void *v) |
|
link_msg->pvnr_cookie_targ = VPTOPNC(vp); |
link_msg->pvnr_cookie_targ = VPTOPNC(vp); |
puffs_makecn(&link_msg->pvnr_cn, &link_msg->pvnr_cn_cred, |
puffs_makecn(&link_msg->pvnr_cn, &link_msg->pvnr_cn_cred, |
&link_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&link_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
|
puffs_msg_setinfo(park_link, PUFFSOP_VN, |
|
PUFFS_VN_LINK, VPTOPNC(dvp)); |
|
|
|
puffs_msg_enqueue(pmp, park_link); |
|
REFPN_AND_UNLOCKVP(dvp, dpn); |
|
REFPN(pn); |
|
error = puffs_msg_wait2(pmp, park_link, dpn, pn); |
|
|
error = puffs_msg_vn(pmp, park_link, PUFFS_VN_LINK, 0, dvp, NULL); |
|
PUFFS_MSG_RELEASE(link); |
PUFFS_MSG_RELEASE(link); |
|
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
Line 1525 puffs_link(void *v) |
|
Line 1596 puffs_link(void *v) |
|
* don't have a better solution either. See also puffs_rename(). |
* don't have a better solution either. See also puffs_rename(). |
*/ |
*/ |
if (error == 0) |
if (error == 0) |
puffs_updatenode(vp, PUFFS_UPDATECTIME); |
puffs_updatenode(pn, PUFFS_UPDATECTIME, 0); |
|
|
PNBUF_PUT(cnp->cn_pnbuf); |
PNBUF_PUT(cnp->cn_pnbuf); |
vput(dvp); |
RELEPN_AND_VP(dvp, dpn); |
|
puffs_releasenode(pn); |
|
|
return error; |
return error; |
} |
} |
Line 1546 puffs_symlink(void *v) |
|
Line 1618 puffs_symlink(void *v) |
|
}/ *ap = v; |
}/ *ap = v; |
PUFFS_MSG_VARS(vn, symlink); |
PUFFS_MSG_VARS(vn, symlink); |
struct vnode *dvp = ap->a_dvp; |
struct vnode *dvp = ap->a_dvp; |
|
struct puffs_node *dpn = VPTOPP(dvp); |
|
struct mount *mp = dvp->v_mount; |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
struct puffs_mount *pmp = MPTOPUFFSMP(dvp->v_mount); |
|
struct componentname *cnp = ap->a_cnp; |
int error; |
int error; |
|
|
*ap->a_vpp = NULL; |
*ap->a_vpp = NULL; |
|
|
PUFFS_MSG_ALLOC(vn, symlink); |
PUFFS_MSG_ALLOC(vn, symlink); |
puffs_makecn(&symlink_msg->pvnr_cn, &symlink_msg->pvnr_cn_cred, |
puffs_makecn(&symlink_msg->pvnr_cn, &symlink_msg->pvnr_cn_cred, |
&symlink_msg->pvnr_cn_cid, ap->a_cnp, PUFFS_USE_FULLPNBUF(pmp)); |
&symlink_msg->pvnr_cn_cid, cnp, PUFFS_USE_FULLPNBUF(pmp)); |
symlink_msg->pvnr_va = *ap->a_vap; |
symlink_msg->pvnr_va = *ap->a_vap; |
(void)strlcpy(symlink_msg->pvnr_link, ap->a_target, |
(void)strlcpy(symlink_msg->pvnr_link, ap->a_target, |
sizeof(symlink_msg->pvnr_link)); |
sizeof(symlink_msg->pvnr_link)); |
|
puffs_msg_setinfo(park_symlink, PUFFSOP_VN, |
|
PUFFS_VN_SYMLINK, VPTOPNC(dvp)); |
|
|
|
puffs_msg_enqueue(pmp, park_symlink); |
|
REFPN_AND_UNLOCKVP(dvp, dpn); |
|
error = puffs_msg_wait2(pmp, park_symlink, dpn, NULL); |
|
|
error = puffs_msg_vn(pmp, park_symlink, PUFFS_VN_SYMLINK, 0, dvp,NULL); |
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
goto out; |
goto out; |
|
|
error = puffs_newnode(ap->a_dvp->v_mount, ap->a_dvp, ap->a_vpp, |
error = puffs_newnode(mp, dvp, ap->a_vpp, |
symlink_msg->pvnr_newnode, ap->a_cnp, VLNK, 0); |
symlink_msg->pvnr_newnode, cnp, VLNK, 0); |
if (error) |
if (error) |
puffs_abortbutton(pmp, PUFFS_ABORT_SYMLINK, VPTOPNC(ap->a_dvp), |
puffs_abortbutton(pmp, PUFFS_ABORT_SYMLINK, dpn->pn_cookie, |
symlink_msg->pvnr_newnode, ap->a_cnp); |
symlink_msg->pvnr_newnode, cnp); |
|
|
out: |
out: |
PUFFS_MSG_RELEASE(symlink); |
PUFFS_MSG_RELEASE(symlink); |
if (error || (ap->a_cnp->cn_flags & SAVESTART) == 0) |
if (error || (cnp->cn_flags & SAVESTART) == 0) |
PNBUF_PUT(ap->a_cnp->cn_pnbuf); |
PNBUF_PUT(cnp->cn_pnbuf); |
vput(ap->a_dvp); |
RELEPN_AND_VP(dvp, dpn); |
|
|
return error; |
return error; |
} |
} |
Line 1597 puffs_readlink(void *v) |
|
Line 1677 puffs_readlink(void *v) |
|
puffs_credcvt(&readlink_msg->pvnr_cred, ap->a_cred); |
puffs_credcvt(&readlink_msg->pvnr_cred, ap->a_cred); |
linklen = sizeof(readlink_msg->pvnr_link); |
linklen = sizeof(readlink_msg->pvnr_link); |
readlink_msg->pvnr_linklen = linklen; |
readlink_msg->pvnr_linklen = linklen; |
|
puffs_msg_setinfo(park_readlink, PUFFSOP_VN, |
|
PUFFS_VN_READLINK, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_readlink, PUFFS_VN_READLINK, 0, vp,NULL); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_readlink, vp->v_data, NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
goto out; |
goto out; |
|
|
/* bad bad user file server */ |
/* bad bad user file server */ |
if (readlink_msg->pvnr_linklen > linklen) { |
if (readlink_msg->pvnr_linklen > linklen) { |
puffs_msg_errnotify(pmp, PUFFS_ERR_READLINK, E2BIG, |
puffs_senderr(pmp, PUFFS_ERR_READLINK, E2BIG, |
"linklen too big", VPTOPNC(ap->a_vp)); |
"linklen too big", VPTOPNC(ap->a_vp)); |
error = EPROTO; |
error = EPROTO; |
goto out; |
goto out; |
Line 1631 puffs_rename(void *v) |
|
Line 1713 puffs_rename(void *v) |
|
struct componentname *a_tcnp; |
struct componentname *a_tcnp; |
}/ *ap = v; |
}/ *ap = v; |
PUFFS_MSG_VARS(vn, rename); |
PUFFS_MSG_VARS(vn, rename); |
struct puffs_mount *pmp = MPTOPUFFSMP(ap->a_fdvp->v_mount); |
struct vnode *fdvp = ap->a_fdvp; |
|
struct puffs_node *fpn = ap->a_fvp->v_data; |
|
struct puffs_mount *pmp = MPTOPUFFSMP(fdvp->v_mount); |
int error; |
int error; |
|
|
if (ap->a_fvp->v_mount != ap->a_tdvp->v_mount) |
if (ap->a_fvp->v_mount != ap->a_tdvp->v_mount) |
Line 1650 puffs_rename(void *v) |
|
Line 1734 puffs_rename(void *v) |
|
puffs_makecn(&rename_msg->pvnr_cn_targ, |
puffs_makecn(&rename_msg->pvnr_cn_targ, |
&rename_msg->pvnr_cn_targ_cred, &rename_msg->pvnr_cn_targ_cid, |
&rename_msg->pvnr_cn_targ_cred, &rename_msg->pvnr_cn_targ_cid, |
ap->a_tcnp, PUFFS_USE_FULLPNBUF(pmp)); |
ap->a_tcnp, PUFFS_USE_FULLPNBUF(pmp)); |
|
puffs_msg_setinfo(park_rename, PUFFSOP_VN, |
|
PUFFS_VN_RENAME, VPTOPNC(fdvp)); |
|
|
error = puffs_msg_vn(pmp, park_rename, PUFFS_VN_RENAME, |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_rename, fdvp->v_data, NULL, error); |
0, ap->a_fdvp, NULL); /* XXX: missing vnodes */ |
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
|
|
/* |
/* |
Line 1660 puffs_rename(void *v) |
|
Line 1745 puffs_rename(void *v) |
|
* don't have a better solution either. See also puffs_link(). |
* don't have a better solution either. See also puffs_link(). |
*/ |
*/ |
if (error == 0) |
if (error == 0) |
puffs_updatenode(ap->a_fvp, PUFFS_UPDATECTIME); |
puffs_updatenode(fpn, PUFFS_UPDATECTIME, 0); |
|
|
out: |
out: |
PUFFS_MSG_RELEASE(rename); |
PUFFS_MSG_RELEASE(rename); |
Line 1733 puffs_read(void *v) |
|
Line 1818 puffs_read(void *v) |
|
} |
} |
|
|
if ((vp->v_mount->mnt_flag & MNT_NOATIME) == 0) |
if ((vp->v_mount->mnt_flag & MNT_NOATIME) == 0) |
puffs_updatenode(vp, PUFFS_UPDATEATIME); |
puffs_updatenode(VPTOPP(vp), PUFFS_UPDATEATIME, 0); |
} else { |
} else { |
/* |
/* |
* in case it's not a regular file or we're operating |
* in case it's not a regular file or we're operating |
Line 1752 puffs_read(void *v) |
|
Line 1837 puffs_read(void *v) |
|
memset(read_msg, 0, argsize); /* XXX: touser KASSERT */ |
memset(read_msg, 0, argsize); /* XXX: touser KASSERT */ |
RWARGS(read_msg, ap->a_ioflag, tomove, |
RWARGS(read_msg, ap->a_ioflag, tomove, |
uio->uio_offset, ap->a_cred); |
uio->uio_offset, ap->a_cred); |
|
puffs_msg_setinfo(park_read, PUFFSOP_VN, |
|
PUFFS_VN_READ, VPTOPNC(vp)); |
|
puffs_msg_setdelta(park_read, tomove); |
|
|
error = puffs_msg_vn(pmp, park_read, PUFFS_VN_READ, |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_read, vp->v_data, |
tomove, vp, NULL); |
NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
break; |
break; |
|
|
if (read_msg->pvnr_resid > tomove) { |
if (read_msg->pvnr_resid > tomove) { |
puffs_msg_errnotify(pmp, PUFFS_ERR_READ, |
puffs_senderr(pmp, PUFFS_ERR_READ, |
E2BIG, "resid grew", VPTOPNC(ap->a_vp)); |
E2BIG, "resid grew", VPTOPNC(ap->a_vp)); |
error = EPROTO; |
error = EPROTO; |
break; |
break; |
Line 1890 puffs_write(void *v) |
|
Line 1978 puffs_write(void *v) |
|
round_page(uio->uio_offset), PGO_CLEANIT); |
round_page(uio->uio_offset), PGO_CLEANIT); |
} |
} |
|
|
puffs_updatenode(vp, uflags); |
puffs_updatenode(VPTOPP(vp), uflags, vp->v_size); |
} else { |
} else { |
/* tomove is non-increasing */ |
/* tomove is non-increasing */ |
tomove = PUFFS_TOMOVE(uio->uio_resid, pmp); |
tomove = PUFFS_TOMOVE(uio->uio_resid, pmp); |
Line 1908 puffs_write(void *v) |
|
Line 1996 puffs_write(void *v) |
|
break; |
break; |
|
|
/* move buffer to userspace */ |
/* move buffer to userspace */ |
error = puffs_msg_vn(pmp, park_write, PUFFS_VN_WRITE, |
puffs_msg_setinfo(park_write, PUFFSOP_VN, |
0, vp, NULL); |
PUFFS_VN_WRITE, VPTOPNC(vp)); |
|
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_write, vp->v_data, |
|
NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
break; |
break; |
|
|
if (write_msg->pvnr_resid > tomove) { |
if (write_msg->pvnr_resid > tomove) { |
puffs_msg_errnotify(pmp, PUFFS_ERR_WRITE, |
puffs_senderr(pmp, PUFFS_ERR_WRITE, |
E2BIG, "resid grew", VPTOPNC(ap->a_vp)); |
E2BIG, "resid grew", VPTOPNC(ap->a_vp)); |
error = EPROTO; |
error = EPROTO; |
break; |
break; |
Line 1947 puffs_print(void *v) |
|
Line 2037 puffs_print(void *v) |
|
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); |
struct puffs_node *pn = vp->v_data; |
struct puffs_node *pn = vp->v_data; |
|
int error; |
|
|
/* kernel portion */ |
/* kernel portion */ |
printf("tag VT_PUFFS, vnode %p, puffs node: %p,\n" |
printf("tag VT_PUFFS, vnode %p, puffs node: %p,\n" |
Line 1958 puffs_print(void *v) |
|
Line 2049 puffs_print(void *v) |
|
/* userspace portion */ |
/* userspace portion */ |
if (EXISTSOP(pmp, PRINT)) { |
if (EXISTSOP(pmp, PRINT)) { |
PUFFS_MSG_ALLOC(vn, print); |
PUFFS_MSG_ALLOC(vn, print); |
puffs_msg_vn(pmp, park_print, PUFFS_VN_PRINT, 0, vp, NULL); |
puffs_msg_setinfo(park_print, PUFFSOP_VN, |
|
PUFFS_VN_PRINT, VPTOPNC(vp)); |
|
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_print, vp->v_data, |
|
NULL, error); |
PUFFS_MSG_RELEASE(print); |
PUFFS_MSG_RELEASE(print); |
} |
} |
|
|
Line 1981 puffs_pathconf(void *v) |
|
Line 2075 puffs_pathconf(void *v) |
|
|
|
PUFFS_MSG_ALLOC(vn, pathconf); |
PUFFS_MSG_ALLOC(vn, pathconf); |
pathconf_msg->pvnr_name = ap->a_name; |
pathconf_msg->pvnr_name = ap->a_name; |
error = puffs_msg_vn(pmp, park_pathconf, PUFFS_VN_PATHCONF, 0, vp,NULL); |
puffs_msg_setinfo(park_pathconf, PUFFSOP_VN, |
|
PUFFS_VN_PATHCONF, VPTOPNC(vp)); |
|
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_pathconf, vp->v_data, NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (!error) |
if (!error) |
*ap->a_retval = pathconf_msg->pvnr_retval; |
*ap->a_retval = pathconf_msg->pvnr_retval; |
Line 2013 puffs_advlock(void *v) |
|
Line 2109 puffs_advlock(void *v) |
|
advlock_msg->pvnr_id = ap->a_id; |
advlock_msg->pvnr_id = ap->a_id; |
advlock_msg->pvnr_op = ap->a_op; |
advlock_msg->pvnr_op = ap->a_op; |
advlock_msg->pvnr_flags = ap->a_flags; |
advlock_msg->pvnr_flags = ap->a_flags; |
|
puffs_msg_setinfo(park_advlock, PUFFSOP_VN, |
|
PUFFS_VN_ADVLOCK, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_advlock, PUFFS_VN_ADVLOCK, 0, vp, NULL); |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_advlock, vp->v_data, NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
|
|
out: |
out: |
Line 2023 puffs_advlock(void *v) |
|
Line 2121 puffs_advlock(void *v) |
|
} |
} |
|
|
#define BIOASYNC(bp) (bp->b_flags & B_ASYNC) |
#define BIOASYNC(bp) (bp->b_flags & B_ASYNC) |
#define BIOREAD(bp) (bp->b_flags & B_READ) |
|
#define BIOWRITE(bp) ((bp->b_flags & B_READ) == 0) |
|
|
|
/* |
/* |
* This maps itself to PUFFS_VN_READ/WRITE for data transfer. |
* This maps itself to PUFFS_VN_READ/WRITE for data transfer. |
Line 2044 puffs_strategy(void *v) |
|
Line 2140 puffs_strategy(void *v) |
|
struct buf *bp; |
struct buf *bp; |
size_t argsize; |
size_t argsize; |
size_t tomove, moved; |
size_t tomove, moved; |
int error, dofaf; |
int error, dofaf, dobiodone; |
|
|
pmp = MPTOPUFFSMP(vp->v_mount); |
pmp = MPTOPUFFSMP(vp->v_mount); |
bp = ap->a_bp; |
bp = ap->a_bp; |
Line 2052 puffs_strategy(void *v) |
|
Line 2148 puffs_strategy(void *v) |
|
dofaf = 0; |
dofaf = 0; |
pn = VPTOPP(vp); |
pn = VPTOPP(vp); |
park_rw = NULL; /* explicit */ |
park_rw = NULL; /* explicit */ |
|
dobiodone = 1; |
|
|
if ((BIOREAD(bp) && !EXISTSOP(pmp, READ)) |
if ((BUF_ISREAD(bp) && !EXISTSOP(pmp, READ)) |
|| (BIOWRITE(bp) && !EXISTSOP(pmp, WRITE))) |
|| (BUF_ISWRITE(bp) && !EXISTSOP(pmp, WRITE))) |
ERROUT(EOPNOTSUPP); |
ERROUT(EOPNOTSUPP); |
|
|
/* |
/* |
Line 2062 puffs_strategy(void *v) |
|
Line 2159 puffs_strategy(void *v) |
|
* VOP_INACTIVE and VOP_RECLAIM in case the node has no references. |
* VOP_INACTIVE and VOP_RECLAIM in case the node has no references. |
*/ |
*/ |
if (pn->pn_stat & PNODE_DYING) { |
if (pn->pn_stat & PNODE_DYING) { |
KASSERT(BIOWRITE(bp)); |
KASSERT(BUF_ISWRITE(bp)); |
bp->b_resid = 0; |
bp->b_resid = 0; |
goto out; |
goto out; |
} |
} |
Line 2079 puffs_strategy(void *v) |
|
Line 2176 puffs_strategy(void *v) |
|
* Also, do FAF in case we're suspending. |
* Also, do FAF in case we're suspending. |
* See puffs_vfsops.c:pageflush() |
* See puffs_vfsops.c:pageflush() |
*/ |
*/ |
if (BIOWRITE(bp)) { |
if (BUF_ISWRITE(bp)) { |
simple_lock(&vp->v_interlock); |
simple_lock(&vp->v_interlock); |
if (vp->v_iflag & VI_XLOCK) |
if (vp->v_iflag & VI_XLOCK) |
dofaf = 1; |
dofaf = 1; |
Line 2088 puffs_strategy(void *v) |
|
Line 2185 puffs_strategy(void *v) |
|
simple_unlock(&vp->v_interlock); |
simple_unlock(&vp->v_interlock); |
} |
} |
|
|
if (BIOASYNC(bp)) |
|
dofaf = 1; |
|
|
|
#ifdef DIAGNOSTIC |
#ifdef DIAGNOSTIC |
if (curlwp == uvm.pagedaemon_lwp) |
if (curlwp == uvm.pagedaemon_lwp) |
KASSERT(dofaf); |
KASSERT(dofaf || BIOASYNC(bp)); |
#endif |
#endif |
|
|
/* allocate transport structure */ |
/* allocate transport structure */ |
Line 2106 puffs_strategy(void *v) |
|
Line 2200 puffs_strategy(void *v) |
|
RWARGS(rw_msg, 0, tomove, bp->b_blkno << DEV_BSHIFT, FSCRED); |
RWARGS(rw_msg, 0, tomove, bp->b_blkno << DEV_BSHIFT, FSCRED); |
|
|
/* 2x2 cases: read/write, faf/nofaf */ |
/* 2x2 cases: read/write, faf/nofaf */ |
if (BIOREAD(bp)) { |
if (BUF_ISREAD(bp)) { |
if (dofaf) { |
puffs_msg_setinfo(park_rw, PUFFSOP_VN, |
puffs_msg_vncall(pmp, park_rw, PUFFS_VN_READ, 0, |
PUFFS_VN_READ, VPTOPNC(vp)); |
puffs_parkdone_asyncbioread, bp, vp); |
puffs_msg_setdelta(park_rw, tomove); |
|
if (BIOASYNC(bp)) { |
|
puffs_msg_setcall(park_rw, |
|
puffs_parkdone_asyncbioread, bp); |
|
puffs_msg_enqueue(pmp, park_rw); |
|
dobiodone = 0; |
} else { |
} else { |
error = puffs_msg_vn(pmp, park_rw, PUFFS_VN_READ, |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_rw, vp->v_data, |
tomove, vp, NULL); |
NULL, error); |
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
if (error) |
if (error) |
goto out; |
goto out; |
|
|
if (rw_msg->pvnr_resid > tomove) { |
if (rw_msg->pvnr_resid > tomove) { |
puffs_msg_errnotify(pmp, PUFFS_ERR_READ, |
puffs_senderr(pmp, PUFFS_ERR_READ, |
E2BIG, "resid grew", VPTOPNC(vp)); |
E2BIG, "resid grew", VPTOPNC(vp)); |
ERROUT(EPROTO); |
ERROUT(EPROTO); |
} |
} |
Line 2129 puffs_strategy(void *v) |
|
Line 2228 puffs_strategy(void *v) |
|
bp->b_resid = bp->b_bcount - moved; |
bp->b_resid = bp->b_bcount - moved; |
} |
} |
} else { |
} else { |
|
puffs_msg_setinfo(park_rw, PUFFSOP_VN, |
|
PUFFS_VN_WRITE, VPTOPNC(vp)); |
/* |
/* |
* make pages read-only before we write them if we want |
* make pages read-only before we write them if we want |
* write caching info |
* write caching info |
Line 2153 puffs_strategy(void *v) |
|
Line 2254 puffs_strategy(void *v) |
|
} |
} |
|
|
(void)memcpy(&rw_msg->pvnr_data, bp->b_data, tomove); |
(void)memcpy(&rw_msg->pvnr_data, bp->b_data, tomove); |
if (dofaf) |
if (dofaf) { |
puffs_msg_setfaf(park_rw); |
puffs_msg_setfaf(park_rw); |
error = puffs_msg_vn(pmp, park_rw, PUFFS_VN_WRITE, 0, vp, NULL); |
} else if (BIOASYNC(bp)) { |
|
puffs_msg_setcall(park_rw, |
|
puffs_parkdone_asyncbiowrite, bp); |
|
dobiodone = 0; |
|
} |
|
|
|
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_rw, vp->v_data, NULL, error); |
|
|
|
if (dobiodone == 0) |
|
goto out; |
|
|
/* |
/* |
* XXXXXXXX: wrong, but kernel can't survive strategy |
* XXXXXXXX: wrong, but kernel can't survive strategy |
Line 2169 puffs_strategy(void *v) |
|
Line 2279 puffs_strategy(void *v) |
|
goto out; |
goto out; |
|
|
if (rw_msg->pvnr_resid > tomove) { |
if (rw_msg->pvnr_resid > tomove) { |
puffs_msg_errnotify(pmp, PUFFS_ERR_WRITE, |
puffs_senderr(pmp, PUFFS_ERR_WRITE, |
E2BIG, "resid grew", VPTOPNC(vp)); |
E2BIG, "resid grew", VPTOPNC(vp)); |
ERROUT(EPROTO); |
ERROUT(EPROTO); |
} |
} |
Line 2196 puffs_strategy(void *v) |
|
Line 2306 puffs_strategy(void *v) |
|
if (error) |
if (error) |
bp->b_error = error; |
bp->b_error = error; |
|
|
if (error || !(BIOREAD(bp) && BIOASYNC(bp))) |
if (error || dobiodone) |
biodone(bp); |
biodone(bp); |
|
|
return error; |
return error; |
Line 2210 puffs_mmap(void *v) |
|
Line 2320 puffs_mmap(void *v) |
|
struct vnode *a_vp; |
struct vnode *a_vp; |
vm_prot_t a_prot; |
vm_prot_t a_prot; |
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
struct lwp *a_l; |
|
} */ *ap = v; |
} */ *ap = v; |
PUFFS_MSG_VARS(vn, mmap); |
PUFFS_MSG_VARS(vn, mmap); |
struct vnode *vp = ap->a_vp; |
struct vnode *vp = ap->a_vp; |
Line 2224 puffs_mmap(void *v) |
|
Line 2333 puffs_mmap(void *v) |
|
PUFFS_MSG_ALLOC(vn, mmap); |
PUFFS_MSG_ALLOC(vn, mmap); |
mmap_msg->pvnr_prot = ap->a_prot; |
mmap_msg->pvnr_prot = ap->a_prot; |
puffs_credcvt(&mmap_msg->pvnr_cred, ap->a_cred); |
puffs_credcvt(&mmap_msg->pvnr_cred, ap->a_cred); |
puffs_cidcvt(&mmap_msg->pvnr_cid, ap->a_l); |
puffs_msg_setinfo(park_mmap, PUFFSOP_VN, |
|
PUFFS_VN_MMAP, VPTOPNC(vp)); |
|
|
error = puffs_msg_vn(pmp, park_mmap, PUFFS_VN_MMAP, |
PUFFS_MSG_ENQUEUEWAIT2(pmp, park_mmap, vp->v_data, NULL, error); |
0, vp, NULL); |
|
error = checkerr(pmp, error, __func__); |
error = checkerr(pmp, error, __func__); |
PUFFS_MSG_RELEASE(mmap); |
PUFFS_MSG_RELEASE(mmap); |
} else { |
} else { |
Line 2335 puffs_getpages(void *v) |
|
Line 2444 puffs_getpages(void *v) |
|
simple_unlock(&vp->v_interlock); |
simple_unlock(&vp->v_interlock); |
vattr_null(&va); |
vattr_null(&va); |
va.va_size = vp->v_size; |
va.va_size = vp->v_size; |
error = puffs_dosetattr(vp, &va, FSCRED, NULL, 0); |
error = puffs_dosetattr(vp, &va, FSCRED, 0); |
if (error) |
if (error) |
ERROUT(error); |
ERROUT(error); |
simple_lock(&vp->v_interlock); |
simple_lock(&vp->v_interlock); |
Line 2345 puffs_getpages(void *v) |
|
Line 2454 puffs_getpages(void *v) |
|
#ifdef notnowjohn |
#ifdef notnowjohn |
/* allocate worst-case memory */ |
/* allocate worst-case memory */ |
runsizes = ((npages / 2) + 1) * sizeof(struct puffs_cacherun); |
runsizes = ((npages / 2) + 1) * sizeof(struct puffs_cacherun); |
pcinfo = malloc(sizeof(struct puffs_cacheinfo) + runsizes, |
pcinfo = kmem_zalloc(sizeof_puffs_cacheinfo) + runsize, |
M_PUFFS, M_ZERO | locked ? M_NOWAIT : M_WAITOK); |
locked ? KM_NOSLEEP : KM_SLEEP); |
|
|
/* |
/* |
* can't block if we're locked and can't mess up caching |
* can't block if we're locked and can't mess up caching |
Line 2419 puffs_getpages(void *v) |
|
Line 2528 puffs_getpages(void *v) |
|
out: |
out: |
if (error) { |
if (error) { |
if (pcinfo != NULL) |
if (pcinfo != NULL) |
free(pcinfo, M_PUFFS); |
kmem_free(pcinfo, |
|
sizeof(struct puffs_cacheinfo) + runsizes); |
#ifdef notnowjohn |
#ifdef notnowjohn |
if (parkmem != NULL) |
if (parkmem != NULL) |
puffs_park_release(parkmem, 1); |
puffs_park_release(parkmem, 1); |
Line 2524 puffs_spec_read(void *v) |
|
Line 2634 puffs_spec_read(void *v) |
|
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
} */ *ap = v; |
} */ *ap = v; |
|
|
puffs_updatenode(ap->a_vp, PUFFS_UPDATEATIME); |
puffs_updatenode(VPTOPP(ap->a_vp), PUFFS_UPDATEATIME, 0); |
return VOCALL(spec_vnodeop_p, VOFFSET(vop_read), v); |
return VOCALL(spec_vnodeop_p, VOFFSET(vop_read), v); |
} |
} |
|
|
Line 2539 puffs_spec_write(void *v) |
|
Line 2649 puffs_spec_write(void *v) |
|
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
}/ *ap = v; |
}/ *ap = v; |
|
|
puffs_updatenode(ap->a_vp, PUFFS_UPDATEMTIME); |
puffs_updatenode(VPTOPP(ap->a_vp), PUFFS_UPDATEMTIME, 0); |
return VOCALL(spec_vnodeop_p, VOFFSET(vop_write), v); |
return VOCALL(spec_vnodeop_p, VOFFSET(vop_write), v); |
} |
} |
|
|
Line 2554 puffs_fifo_read(void *v) |
|
Line 2664 puffs_fifo_read(void *v) |
|
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
} */ *ap = v; |
} */ *ap = v; |
|
|
puffs_updatenode(ap->a_vp, PUFFS_UPDATEATIME); |
puffs_updatenode(VPTOPP(ap->a_vp), PUFFS_UPDATEATIME, 0); |
return VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), v); |
return VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), v); |
} |
} |
|
|
Line 2569 puffs_fifo_write(void *v) |
|
Line 2679 puffs_fifo_write(void *v) |
|
kauth_cred_t a_cred; |
kauth_cred_t a_cred; |
}/ *ap = v; |
}/ *ap = v; |
|
|
puffs_updatenode(ap->a_vp, PUFFS_UPDATEMTIME); |
puffs_updatenode(VPTOPP(ap->a_vp), PUFFS_UPDATEMTIME, 0); |
return VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), v); |
return VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), v); |
} |
} |