version 1.25, 2007/04/04 15:50:56 |
version 1.26, 2007/04/04 16:13:51 |
Line 64 struct puffs_park { |
|
Line 64 struct puffs_park { |
|
void *park_donearg; |
void *park_donearg; |
|
|
int park_flags; |
int park_flags; |
|
int park_refcount; |
|
|
kcondvar_t park_cv; |
kcondvar_t park_cv; |
|
kmutex_t park_mtx; |
|
|
TAILQ_ENTRY(puffs_park) park_entries; |
TAILQ_ENTRY(puffs_park) park_entries; |
}; |
}; |
#define PARKFLAG_WAITERGONE 0x01 |
#define PARKFLAG_WAITERGONE 0x01 |
#define PARKFLAG_PROCESSING 0x02 |
#define PARKFLAG_DONE 0x02 |
#define PARKFLAG_CALL 0x04 |
#define PARKFLAG_ONQUEUE1 0x04 |
|
#define PARKFLAG_ONQUEUE2 0x08 |
|
#define PARKFLAG_CALL 0x10 |
|
|
static struct pool_cache parkpc; |
static struct pool_cache parkpc; |
static struct pool parkpool; |
static struct pool parkpool; |
Line 80 makepark(void *arg, void *obj, int flags |
|
Line 85 makepark(void *arg, void *obj, int flags |
|
{ |
{ |
struct puffs_park *park = obj; |
struct puffs_park *park = obj; |
|
|
|
mutex_init(&park->park_mtx, MUTEX_DEFAULT, IPL_NONE); |
cv_init(&park->park_cv, "puffsrpl"); |
cv_init(&park->park_cv, "puffsrpl"); |
|
|
return 0; |
return 0; |
Line 91 nukepark(void *arg, void *obj) |
|
Line 97 nukepark(void *arg, void *obj) |
|
struct puffs_park *park = obj; |
struct puffs_park *park = obj; |
|
|
cv_destroy(&park->park_cv); |
cv_destroy(&park->park_cv); |
|
mutex_destroy(&park->park_mtx); |
} |
} |
|
|
void |
void |
Line 111 puffs_msgif_destroy() |
|
Line 118 puffs_msgif_destroy() |
|
} |
} |
|
|
void * |
void * |
puffs_parkmem_alloc(int waitok) |
puffs_park_alloc(int waitok) |
|
{ |
|
struct puffs_park *park; |
|
|
|
park = pool_cache_get(&parkpc, waitok ? PR_WAITOK : PR_NOWAIT); |
|
if (park) { |
|
park->park_refcount = 1; |
|
mutex_enter(&park->park_mtx); |
|
} |
|
|
|
return park; |
|
} |
|
|
|
static void |
|
puffs_park_reference(struct puffs_park *park) |
{ |
{ |
|
|
return pool_cache_get(&parkpc, waitok ? PR_WAITOK : PR_NOWAIT); |
mutex_enter(&park->park_mtx); |
|
park->park_refcount++; |
} |
} |
|
|
void |
void |
puffs_parkmem_free(void *park) |
puffs_park_release(void *arg, int fullnuke) |
{ |
{ |
|
struct puffs_park *park = arg; |
|
|
pool_cache_put(&parkpc, park); |
KASSERT(mutex_owned(&park->park_mtx)); |
|
--park->park_refcount; |
|
|
|
mutex_exit(&park->park_mtx); |
|
if (park->park_refcount == 0 || fullnuke) |
|
pool_cache_put(&parkpc, park); |
} |
} |
|
|
|
#ifdef PUFFSDEBUG |
|
static void |
|
parkdump(struct puffs_park *park) |
|
{ |
|
|
|
DPRINTF(("park %p, preq %p, id %" PRIu64 "\n" |
|
"\tcopy %zu, max %zu - done: %p/%p\n" |
|
"\tflags 0x%08x, refcount %d, cv/mtx: %p/%p\n", |
|
park, park->park_preq, park->park_id, |
|
park->park_copylen, park->park_maxlen, |
|
park->park_done, park->park_donearg, |
|
park->park_flags, park->park_refcount, |
|
&park->park_cv, &park->park_mtx)); |
|
} |
|
|
|
static void |
|
parkqdump(struct puffs_wq *q, int dumpall) |
|
{ |
|
struct puffs_park *park; |
|
int total = 0; |
|
|
|
DPRINTF(("puffs waitqueue at %p, BEGIN\n", q)); |
|
TAILQ_FOREACH(park, q, park_entries) { |
|
if (dumpall) |
|
parkdump(park); |
|
total++; |
|
} |
|
DPRINTF(("puffs waitqueue at %p, END. %d total\n", q, total)); |
|
|
|
} |
|
#endif /* PUFFSDEBUG */ |
|
|
/* |
/* |
* Converts a non-FAF op to a FAF. This simply involves making copies |
* Converts a non-FAF op to a FAF. This simply involves making copies |
* of the park and request structures and tagging the request as a FAF. |
* of the park and request structures and tagging the request as a FAF. |
* It is safe to block here, since the original op is not a FAF. |
* It is safe to block here, since the original op is not a FAF. |
*/ |
*/ |
#if 0 |
|
static void |
static void |
puffs_reqtofaf(struct puffs_park *park) |
puffs_reqtofaf(struct puffs_park *park) |
{ |
{ |
Line 146 puffs_reqtofaf(struct puffs_park *park) |
|
Line 204 puffs_reqtofaf(struct puffs_park *park) |
|
park->park_preq = newpreq; |
park->park_preq = newpreq; |
park->park_preq->preq_opclass |= PUFFSOPFLAG_FAF; |
park->park_preq->preq_opclass |= PUFFSOPFLAG_FAF; |
} |
} |
#endif |
|
|
|
|
|
/* |
/* |
Line 174 puffs_vfstouser(struct puffs_mount *pmp, |
|
Line 231 puffs_vfstouser(struct puffs_mount *pmp, |
|
{ |
{ |
struct puffs_park *park; |
struct puffs_park *park; |
|
|
park = puffs_parkmem_alloc(1); |
park = puffs_park_alloc(1); |
park->park_preq = kbuf; |
park->park_preq = kbuf; |
|
|
park->park_preq->preq_opclass = PUFFSOP_VFS; |
park->park_preq->preq_opclass = PUFFSOP_VFS; |
Line 194 puffs_suspendtouser(struct puffs_mount * |
|
Line 251 puffs_suspendtouser(struct puffs_mount * |
|
|
|
pvfsr_susp = malloc(sizeof(struct puffs_vfsreq_suspend), |
pvfsr_susp = malloc(sizeof(struct puffs_vfsreq_suspend), |
M_PUFFS, M_WAITOK | M_ZERO); |
M_PUFFS, M_WAITOK | M_ZERO); |
park = puffs_parkmem_alloc(1); |
park = puffs_park_alloc(1); |
|
|
pvfsr_susp->pvfsr_status = status; |
pvfsr_susp->pvfsr_status = status; |
park->park_preq = (struct puffs_req *)pvfsr_susp; |
park->park_preq = (struct puffs_req *)pvfsr_susp; |
Line 219 puffs_vntouser(struct puffs_mount *pmp, |
|
Line 276 puffs_vntouser(struct puffs_mount *pmp, |
|
{ |
{ |
struct puffs_park *park; |
struct puffs_park *park; |
|
|
park = puffs_parkmem_alloc(1); |
park = puffs_park_alloc(1); |
park->park_preq = kbuf; |
park->park_preq = kbuf; |
|
|
park->park_preq->preq_opclass = PUFFSOP_VN; |
park->park_preq->preq_opclass = PUFFSOP_VN; |
Line 243 puffs_vntouser_req(struct puffs_mount *p |
|
Line 300 puffs_vntouser_req(struct puffs_mount *p |
|
{ |
{ |
struct puffs_park *park; |
struct puffs_park *park; |
|
|
park = puffs_parkmem_alloc(1); |
park = puffs_park_alloc(1); |
park->park_preq = kbuf; |
park->park_preq = kbuf; |
|
|
park->park_preq->preq_opclass = PUFFSOP_VN; |
park->park_preq->preq_opclass = PUFFSOP_VN; |
Line 265 puffs_vntouser_call(struct puffs_mount * |
|
Line 322 puffs_vntouser_call(struct puffs_mount * |
|
{ |
{ |
struct puffs_park *park; |
struct puffs_park *park; |
|
|
park = puffs_parkmem_alloc(1); |
park = puffs_park_alloc(1); |
park->park_preq = kbuf; |
park->park_preq = kbuf; |
|
|
park->park_preq->preq_opclass = PUFFSOP_VN; |
park->park_preq->preq_opclass = PUFFSOP_VN; |
Line 293 puffs_vntouser_faf(struct puffs_mount *p |
|
Line 350 puffs_vntouser_faf(struct puffs_mount *p |
|
struct puffs_park *park; |
struct puffs_park *park; |
|
|
/* XXX: is it allowable to sleep here? */ |
/* XXX: is it allowable to sleep here? */ |
park = puffs_parkmem_alloc(0); |
park = puffs_park_alloc(0); |
if (park == NULL) |
if (park == NULL) |
return; /* 2bad */ |
return; /* 2bad */ |
|
|
Line 320 puffs_cacheop(struct puffs_mount *pmp, s |
|
Line 377 puffs_cacheop(struct puffs_mount *pmp, s |
|
park->park_preq->preq_cookie = cookie; |
park->park_preq->preq_cookie = cookie; |
|
|
park->park_maxlen = park->park_copylen = pcilen; |
park->park_maxlen = park->park_copylen = pcilen; |
|
park->park_flags = 0; |
|
|
(void)touser(pmp, park, 0, NULL, NULL); |
(void)touser(pmp, park, 0, NULL, NULL); |
} |
} |
|
|
touser(struct puffs_mount *pmp, struct puffs_park *park, uint64_t reqid, |
touser(struct puffs_mount *pmp, struct puffs_park *park, uint64_t reqid, |
struct vnode *vp1, struct vnode *vp2) |
struct vnode *vp1, struct vnode *vp2) |
{ |
{ |
|
struct lwp *l = curlwp; |
struct mount *mp; |
struct mount *mp; |
struct puffs_req *preq; |
struct puffs_req *preq; |
int rv = 0; |
int rv = 0; |
Line 347 touser(struct puffs_mount *pmp, struct p |
|
Line 406 touser(struct puffs_mount *pmp, struct p |
|
preq->preq_id = park->park_id = reqid; |
preq->preq_id = park->park_id = reqid; |
preq->preq_buflen = ALIGN(park->park_maxlen); |
preq->preq_buflen = ALIGN(park->park_maxlen); |
|
|
#if 0 |
|
/* |
|
* We don't trap signals currently |
|
*/ |
|
struct lwp *l = curlwp; |
|
|
|
/* |
/* |
* To support PCATCH, yet another movie: check if there are signals |
* To support PCATCH, yet another movie: check if there are signals |
* pending and we are issueing a non-FAF. If so, return an error |
* pending and we are issueing a non-FAF. If so, return an error |
Line 369 touser(struct puffs_mount *pmp, struct p |
|
Line 422 touser(struct puffs_mount *pmp, struct p |
|
DPRINTF(("puffs touser: converted to FAF %p\n", park)); |
DPRINTF(("puffs touser: converted to FAF %p\n", park)); |
rv = EINTR; |
rv = EINTR; |
} else { |
} else { |
|
puffs_park_release(park, 0); |
return EINTR; |
return EINTR; |
} |
} |
} |
} |
#endif |
|
|
|
/* |
/* |
* test for suspension lock. |
* test for suspension lock. |
Line 408 touser(struct puffs_mount *pmp, struct p |
|
Line 461 touser(struct puffs_mount *pmp, struct p |
|
|
|
if (pmp->pmp_status != PUFFSTAT_RUNNING) { |
if (pmp->pmp_status != PUFFSTAT_RUNNING) { |
mutex_exit(&pmp->pmp_lock); |
mutex_exit(&pmp->pmp_lock); |
puffs_parkmem_free(park); |
puffs_park_release(park, 0); |
return ENXIO; |
return ENXIO; |
} |
} |
|
|
|
#ifdef PUFFSDEBUG |
|
parkqdump(&pmp->pmp_req_touser, puffsdebug > 1); |
|
parkqdump(&pmp->pmp_req_replywait, puffsdebug > 1); |
|
#endif |
|
|
TAILQ_INSERT_TAIL(&pmp->pmp_req_touser, park, park_entries); |
TAILQ_INSERT_TAIL(&pmp->pmp_req_touser, park, park_entries); |
|
park->park_flags |= PARKFLAG_ONQUEUE1; |
pmp->pmp_req_waiters++; |
pmp->pmp_req_waiters++; |
|
mutex_exit(&pmp->pmp_lock); |
|
|
#if 0 |
#if 0 |
/* |
/* |
Line 442 touser(struct puffs_mount *pmp, struct p |
|
Line 502 touser(struct puffs_mount *pmp, struct p |
|
&& (park->park_flags & PARKFLAG_CALL) == 0) { |
&& (park->park_flags & PARKFLAG_CALL) == 0) { |
int error; |
int error; |
|
|
error = 0; /* XXX: no interrupt for now */ |
error = cv_wait_sig(&park->park_cv, &park->park_mtx); |
|
|
cv_wait(&park->park_cv, &pmp->pmp_lock); |
|
if (error) { |
if (error) { |
park->park_flags |= PARKFLAG_WAITERGONE; |
park->park_flags |= PARKFLAG_WAITERGONE; |
if (park->park_flags & PARKFLAG_PROCESSING) { |
if (park->park_flags & PARKFLAG_DONE) { |
cv_wait(&park->park_cv, &pmp->pmp_lock); |
|
rv = preq->preq_rv; |
rv = preq->preq_rv; |
|
puffs_park_release(park, 0); |
} else { |
} else { |
|
/* |
|
* ok, we marked it as going away, but |
|
* still need to do queue ops. take locks |
|
* in correct order. |
|
* |
|
* We don't want to release our reference |
|
* if it's on replywait queue to avoid error |
|
* to file server. putop() code will DTRT. |
|
*/ |
|
KASSERT(park->park_flags & |
|
(PARKFLAG_ONQUEUE1 | PARKFLAG_ONQUEUE2)); |
|
mutex_exit(&park->park_mtx); |
|
|
|
mutex_enter(&pmp->pmp_lock); |
|
mutex_enter(&park->park_mtx); |
|
if (park->park_flags & PARKFLAG_ONQUEUE1) |
|
TAILQ_REMOVE(&pmp->pmp_req_touser, |
|
park, park_entries); |
|
park->park_flags &= ~PARKFLAG_ONQUEUE1; |
|
if ((park->park_flags & PARKFLAG_ONQUEUE2) == 0) |
|
puffs_park_release(park, 0); |
|
else |
|
mutex_exit(&park->park_mtx); |
|
mutex_exit(&pmp->pmp_lock); |
|
|
rv = error; |
rv = error; |
} |
} |
} else { |
} else { |
rv = preq->preq_rv; |
rv = preq->preq_rv; |
|
puffs_park_release(park, 0); |
} |
} |
mutex_exit(&pmp->pmp_lock); |
|
puffs_parkmem_free(park); |
|
|
|
/* |
/* |
* retake the lock and release. This makes sure (haha, |
* retake the lock and release. This makes sure (haha, |
Line 473 touser(struct puffs_mount *pmp, struct p |
|
Line 555 touser(struct puffs_mount *pmp, struct p |
|
fstrans_done(mp); |
fstrans_done(mp); |
} |
} |
} else { |
} else { |
mutex_exit(&pmp->pmp_lock); |
mutex_exit(&park->park_mtx); |
} |
} |
|
|
#if 0 |
#if 0 |
Line 542 puffs_getop(struct puffs_mount *pmp, str |
|
Line 624 puffs_getop(struct puffs_mount *pmp, str |
|
} |
} |
|
|
park = TAILQ_FIRST(&pmp->pmp_req_touser); |
park = TAILQ_FIRST(&pmp->pmp_req_touser); |
preq = park->park_preq; |
puffs_park_reference(park); |
if (phg->phg_buflen < preq->preq_buflen) { |
|
if (!donesome) |
|
error = E2BIG; |
|
goto out; |
|
} |
|
TAILQ_REMOVE(&pmp->pmp_req_touser, park, park_entries); |
|
|
|
/* If it's a goner, don't process any furher */ |
/* If it's a goner, don't process any furher */ |
if (park->park_flags & PARKFLAG_WAITERGONE) { |
if (park->park_flags & PARKFLAG_WAITERGONE) { |
panic("impossible for now"); |
puffs_park_release(park, 0); |
puffs_parkmem_free(park); |
|
continue; |
continue; |
} |
} |
|
|
|
preq = park->park_preq; |
|
TAILQ_REMOVE(&pmp->pmp_req_touser, park, park_entries); |
|
KASSERT(park->park_flags & PARKFLAG_ONQUEUE1); |
|
park->park_flags &= ~PARKFLAG_ONQUEUE1; |
mutex_exit(&pmp->pmp_lock); |
mutex_exit(&pmp->pmp_lock); |
|
|
|
if (phg->phg_buflen < preq->preq_buflen) { |
|
if (!donesome) |
|
error = E2BIG; |
|
puffs_park_release(park, 0); |
|
goto out; |
|
} |
|
|
DPRINTF(("puffsgetop: get op %" PRIu64 " (%d.), from %p " |
DPRINTF(("puffsgetop: get op %" PRIu64 " (%d.), from %p " |
"len %zu (buflen %zu), target %p\n", preq->preq_id, |
"len %zu (buflen %zu), target %p\n", preq->preq_id, |
donesome, preq, park->park_copylen, preq->preq_buflen, |
donesome, preq, park->park_copylen, preq->preq_buflen, |
bufpos)); |
bufpos)); |
|
|
if ((error = copyout(preq, bufpos, park->park_copylen)) != 0) { |
if ((error = copyout(preq, bufpos, park->park_copylen)) != 0) { |
DPRINTF(("puffs_getop: copyout failed\n")); |
DPRINTF(("puffs_getop: copyout failed: %d\n", error)); |
/* |
/* |
* ok, user server is probably trying to cheat. |
* ok, user server is probably trying to cheat. |
* stuff op back & return error to user |
* stuff op back & return error to user. We need |
|
* to take locks in the correct order. |
*/ |
*/ |
mutex_enter(&pmp->pmp_lock); |
mutex_exit(&park->park_mtx); |
TAILQ_INSERT_HEAD(&pmp->pmp_req_touser, park, |
mutex_enter(&pmp->pmp_lock); |
park_entries); |
mutex_enter(&park->park_mtx); |
|
if ((park->park_flags & PARKFLAG_WAITERGONE) == 0) { |
|
TAILQ_INSERT_HEAD(&pmp->pmp_req_touser, park, |
|
park_entries); |
|
park->park_flags |= PARKFLAG_ONQUEUE1; |
|
} |
|
mutex_exit(&pmp->pmp_lock); |
|
|
if (donesome) |
if (donesome) |
error = 0; |
error = 0; |
goto out; |
puffs_park_release(park, 0); |
|
goto out; |
} |
} |
bufpos += preq->preq_buflen; |
bufpos += preq->preq_buflen; |
phg->phg_buflen -= preq->preq_buflen; |
phg->phg_buflen -= preq->preq_buflen; |
Line 586 puffs_getop(struct puffs_mount *pmp, str |
|
Line 680 puffs_getop(struct puffs_mount *pmp, str |
|
if (PUFFSOP_WANTREPLY(preq->preq_opclass)) { |
if (PUFFSOP_WANTREPLY(preq->preq_opclass)) { |
TAILQ_INSERT_TAIL(&pmp->pmp_req_replywait, park, |
TAILQ_INSERT_TAIL(&pmp->pmp_req_replywait, park, |
park_entries); |
park_entries); |
|
park->park_flags |= PARKFLAG_ONQUEUE2; |
|
puffs_park_release(park, 0); |
} else { |
} else { |
free(preq, M_PUFFS); |
free(preq, M_PUFFS); |
puffs_parkmem_free(park); |
puffs_park_release(park, 1); |
} |
} |
} |
} |
|
|
Line 610 puffs_putop(struct puffs_mount *pmp, str |
|
Line 706 puffs_putop(struct puffs_mount *pmp, str |
|
void *userbuf; |
void *userbuf; |
uint64_t id; |
uint64_t id; |
size_t reqlen; |
size_t reqlen; |
int donesome, error, wgone; |
int donesome, error, wgone, release; |
|
|
donesome = error = wgone = 0; |
donesome = error = wgone = 0; |
|
|
Line 620 puffs_putop(struct puffs_mount *pmp, str |
|
Line 716 puffs_putop(struct puffs_mount *pmp, str |
|
|
|
mutex_enter(&pmp->pmp_lock); |
mutex_enter(&pmp->pmp_lock); |
while (donesome != php->php_nops) { |
while (donesome != php->php_nops) { |
|
release = 0; |
#ifdef PUFFSDEBUG |
#ifdef PUFFSDEBUG |
DPRINTF(("puffsputop: searching for %" PRIu64 ", ubuf: %p, " |
DPRINTF(("puffsputop: searching for %" PRIu64 ", ubuf: %p, " |
"len %zu\n", id, userbuf, reqlen)); |
"len %zu\n", id, userbuf, reqlen)); |
Line 635 puffs_putop(struct puffs_mount *pmp, str |
|
Line 732 puffs_putop(struct puffs_mount *pmp, str |
|
break; |
break; |
} |
} |
|
|
|
puffs_park_reference(park); |
if (reqlen == 0 || reqlen > park->park_maxlen) { |
if (reqlen == 0 || reqlen > park->park_maxlen) { |
DPRINTF(("puffsputop: invalid buffer length: " |
DPRINTF(("puffsputop: invalid buffer length: " |
"%zu\n", reqlen)); |
"%zu\n", reqlen)); |
error = E2BIG; |
error = E2BIG; |
|
puffs_park_release(park, 0); |
break; |
break; |
} |
} |
TAILQ_REMOVE(&pmp->pmp_req_replywait, park, park_entries); |
|
wgone = park->park_flags & PARKFLAG_WAITERGONE; |
wgone = park->park_flags & PARKFLAG_WAITERGONE; |
park->park_flags |= PARKFLAG_PROCESSING; |
|
|
/* check if it's still on the queue after acquiring lock */ |
|
if (park->park_flags & PARKFLAG_ONQUEUE2) { |
|
TAILQ_REMOVE(&pmp->pmp_req_replywait, park, |
|
park_entries); |
|
park->park_flags &= ~PARKFLAG_ONQUEUE2; |
|
} |
|
|
mutex_exit(&pmp->pmp_lock); |
mutex_exit(&pmp->pmp_lock); |
|
|
/* |
/* |
* If the caller has gone south, go to next, collect |
* If the caller has gone south, go to next, collect |
* $200 and free the structure there instead of wakeup. |
* $200 and free the structure there instead of wakeup. |
* We also need to copyin the |
* We also need to copyin the header info. Flag structure |
|
* release to mode total and utter destruction. |
*/ |
*/ |
if (wgone) { |
if (wgone) { |
panic("puffs: wgone impossible for now\n"); |
|
DPRINTF(("puffs_putop: bad service - waiter gone for " |
DPRINTF(("puffs_putop: bad service - waiter gone for " |
"park %p\n", park)); |
"park %p\n", park)); |
error = copyin(userbuf, &tmpreq, |
error = copyin(userbuf, &tmpreq, |
sizeof(struct puffs_req)); |
sizeof(struct puffs_req)); |
|
release = 1; |
if (error) |
if (error) |
goto loopout; |
goto loopout; |
nextpreq = &tmpreq; |
nextpreq = &tmpreq; |
Line 683 puffs_putop(struct puffs_mount *pmp, str |
|
Line 789 puffs_putop(struct puffs_mount *pmp, str |
|
|
|
if (park->park_flags & PARKFLAG_CALL) { |
if (park->park_flags & PARKFLAG_CALL) { |
park->park_done(park->park_preq, park->park_donearg); |
park->park_done(park->park_preq, park->park_donearg); |
puffs_parkmem_free(park); |
release = 1; |
} |
} |
|
|
mutex_enter(&pmp->pmp_lock); |
|
if (!wgone) { |
if (!wgone) { |
DPRINTF(("puffs_putop: flagging done for " |
DPRINTF(("puffs_putop: flagging done for " |
"park %p\n", park)); |
"park %p\n", park)); |
|
|
cv_signal(&park->park_cv); |
cv_signal(&park->park_cv); |
} |
} |
|
puffs_park_release(park, release); |
|
|
|
mutex_enter(&pmp->pmp_lock); |
if (error) |
if (error) |
break; |
break; |
wgone = 0; |
wgone = 0; |
Line 727 puffs_userdead(struct puffs_mount *pmp) |
|
Line 834 puffs_userdead(struct puffs_mount *pmp) |
|
TAILQ_FOREACH(park, &pmp->pmp_req_touser, park_entries) { |
TAILQ_FOREACH(park, &pmp->pmp_req_touser, park_entries) { |
uint8_t opclass; |
uint8_t opclass; |
|
|
|
puffs_park_reference(park); |
|
|
|
KASSERT(park->park_flags & PARKFLAG_ONQUEUE1); |
|
|
opclass = park->park_preq->preq_opclass; |
opclass = park->park_preq->preq_opclass; |
park->park_preq->preq_rv = ENXIO; |
park->park_preq->preq_rv = ENXIO; |
TAILQ_REMOVE(&pmp->pmp_req_touser, park, park_entries); |
TAILQ_REMOVE(&pmp->pmp_req_touser, park, park_entries); |
|
park->park_flags &= ~PARKFLAG_ONQUEUE1; |
|
|
if (park->park_flags & PARKFLAG_CALL) { |
if (park->park_flags & PARKFLAG_CALL) { |
park->park_done(park->park_preq, park->park_donearg); |
park->park_done(park->park_preq, park->park_donearg); |
puffs_parkmem_free(park); |
puffs_park_release(park, 1); |
} else if (!PUFFSOP_WANTREPLY(opclass)) { |
} else if (!PUFFSOP_WANTREPLY(opclass)) { |
free(park->park_preq, M_PUFFS); |
free(park->park_preq, M_PUFFS); |
puffs_parkmem_free(park); |
puffs_park_release(park, 1); |
} else { |
} else { |
park->park_preq->preq_rv = ENXIO; |
park->park_preq->preq_rv = ENXIO; |
cv_signal(&park->park_cv); |
cv_signal(&park->park_cv); |
|
puffs_park_release(park, 0); |
} |
} |
} |
} |
|
|
/* signal waiters on RESPONSE FROM file server queue */ |
/* signal waiters on RESPONSE FROM file server queue */ |
TAILQ_FOREACH(park, &pmp->pmp_req_replywait, park_entries) { |
TAILQ_FOREACH(park, &pmp->pmp_req_replywait, park_entries) { |
|
puffs_park_reference(park); |
|
|
|
KASSERT(park->park_flags & PARKFLAG_ONQUEUE2); |
|
|
TAILQ_REMOVE(&pmp->pmp_req_replywait, park, park_entries); |
TAILQ_REMOVE(&pmp->pmp_req_replywait, park, park_entries); |
|
park->park_flags &= ~PARKFLAG_ONQUEUE2; |
|
|
KASSERT(PUFFSOP_WANTREPLY(park->park_preq->preq_opclass)); |
KASSERT(PUFFSOP_WANTREPLY(park->park_preq->preq_opclass)); |
|
|
park->park_preq->preq_rv = ENXIO; |
park->park_preq->preq_rv = ENXIO; |
if (park->park_flags & PARKFLAG_CALL) { |
if (park->park_flags & PARKFLAG_CALL) { |
park->park_done(park->park_preq, park->park_donearg); |
park->park_done(park->park_preq, park->park_donearg); |
puffs_parkmem_free(park); |
mutex_enter(&park->park_mtx); |
|
puffs_park_release(park, 1); |
} else { |
} else { |
cv_signal(&park->park_cv); |
cv_signal(&park->park_cv); |
|
puffs_park_release(park, 0); |
} |
} |
} |
} |
} |
} |