Commit ab821632 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Propagate BOS_FAILED to the objcore, and ignore OC_F_FAILED objects

in HSH_Lookup()
parent 5b339acd
...@@ -424,6 +424,7 @@ struct objcore { ...@@ -424,6 +424,7 @@ struct objcore {
#define OC_F_PRIV (1<<5) /* Stevedore private flag */ #define OC_F_PRIV (1<<5) /* Stevedore private flag */
#define OC_F_LURK (3<<6) /* Ban-lurker-color */ #define OC_F_LURK (3<<6) /* Ban-lurker-color */
#define OC_F_PRIVATE (1<<8) #define OC_F_PRIVATE (1<<8)
#define OC_F_FAILED (1<<9)
unsigned timer_idx; unsigned timer_idx;
VTAILQ_ENTRY(objcore) list; VTAILQ_ENTRY(objcore) list;
VTAILQ_ENTRY(objcore) lru_list; VTAILQ_ENTRY(objcore) lru_list;
......
...@@ -118,7 +118,7 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo) ...@@ -118,7 +118,7 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
if (wrk->handling == VCL_RET_ABANDON) { if (wrk->handling == VCL_RET_ABANDON) {
if (bo->req != NULL) if (bo->req != NULL)
vbf_release_req(bo); vbf_release_req(bo);
VBO_setstate(bo, BOS_FAILED); (void)VFP_Error(bo, "Abandonned in vcl_backend_fetch");
return (F_STP_ABANDON); return (F_STP_ABANDON);
} }
assert (wrk->handling == VCL_RET_FETCH); assert (wrk->handling == VCL_RET_FETCH);
...@@ -360,10 +360,8 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo) ...@@ -360,10 +360,8 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
} }
bo->stats = NULL; bo->stats = NULL;
if (obj == NULL) { if (obj == NULL) {
(void)HSH_Deref(&wrk->stats, bo->fetch_objcore, NULL); (void)VFP_Error(bo, "Could not get storage");
bo->fetch_objcore = NULL;
VDI_CloseFd(&bo->vbc); VDI_CloseFd(&bo->vbc);
VBO_setstate(bo, BOS_FAILED);
return (F_STP_ABANDON); return (F_STP_ABANDON);
} }
CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC); CHECK_OBJ_NOTNULL(obj, OBJECT_MAGIC);
...@@ -428,11 +426,7 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo) ...@@ -428,11 +426,7 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
assert(bo->refcount >= 1); assert(bo->refcount >= 1);
if (bo->state == BOS_FAILED) { if (bo->state != BOS_FAILED)
/* handle early failures */
(void)HSH_Deref(&wrk->stats, NULL, &obj);
return (F_STP_ABANDON);
}
VBO_setstate(bo, BOS_FINISHED); VBO_setstate(bo, BOS_FINISHED);
VSLb(bo->vsl, SLT_Debug, "YYY REF %d %d", bo->refcount, bo->fetch_obj->objcore->refcnt); VSLb(bo->vsl, SLT_Debug, "YYY REF %d %d", bo->refcount, bo->fetch_obj->objcore->refcnt);
...@@ -450,6 +444,7 @@ vbf_stp_abandon(struct worker *wrk, struct busyobj *bo) ...@@ -450,6 +444,7 @@ vbf_stp_abandon(struct worker *wrk, struct busyobj *bo)
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC); CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
assert(bo->state == BOS_FAILED); assert(bo->state == BOS_FAILED);
assert(bo->fetch_objcore->flags & OC_F_FAILED);
VBO_DerefBusyObj(wrk, &bo); // XXX ? VBO_DerefBusyObj(wrk, &bo); // XXX ?
return (F_STP_DONE); return (F_STP_DONE);
} }
...@@ -571,5 +566,8 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc, ...@@ -571,5 +566,8 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
return (NULL); return (NULL);
} }
VBO_waitstate(bo, BOS_FETCHING); VBO_waitstate(bo, BOS_FETCHING);
if (!bo->do_stream)
VBO_waitstate(bo, BOS_FINISHED);
assert(bo->state != BOS_FAILED || (oc->flags & OC_F_FAILED));
return (bo); return (bo);
} }
...@@ -62,6 +62,8 @@ VFP_Error2(struct busyobj *bo, const char *error, const char *more) ...@@ -62,6 +62,8 @@ VFP_Error2(struct busyobj *bo, const char *error, const char *more)
VSLb(bo->vsl, SLT_FetchError, "%s", error); VSLb(bo->vsl, SLT_FetchError, "%s", error);
else else
VSLb(bo->vsl, SLT_FetchError, "%s: %s", error, more); VSLb(bo->vsl, SLT_FetchError, "%s: %s", error, more);
if (bo->fetch_objcore != NULL)
HSH_Fail(bo->fetch_objcore);
VBO_setstate(bo, BOS_FAILED); VBO_setstate(bo, BOS_FAILED);
} }
return (-1); return (-1);
......
...@@ -401,6 +401,9 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp, ...@@ -401,6 +401,9 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp,
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC); CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
assert(oc->objhead == oh); assert(oc->objhead == oh);
if (oc->flags & OC_F_FAILED)
continue;
if (oc->flags & OC_F_BUSY || oc->busyobj != NULL) { if (oc->flags & OC_F_BUSY || oc->busyobj != NULL) {
CHECK_OBJ_ORNULL(oc->busyobj, BUSYOBJ_MAGIC); CHECK_OBJ_ORNULL(oc->busyobj, BUSYOBJ_MAGIC);
if (req->hash_ignore_busy) if (req->hash_ignore_busy)
...@@ -623,6 +626,24 @@ HSH_Drop(struct worker *wrk, struct object **oo) ...@@ -623,6 +626,24 @@ HSH_Drop(struct worker *wrk, struct object **oo)
AZ(HSH_Deref(&wrk->stats, NULL, oo)); AZ(HSH_Deref(&wrk->stats, NULL, oo));
} }
/*---------------------------------------------------------------------
* Fail an objcore
*/
void
HSH_Fail(struct objcore *oc)
{
struct objhead *oh;
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
oh = oc->objhead;
CHECK_OBJ(oh, OBJHEAD_MAGIC);
Lck_Lock(&oh->mtx);
oc->flags |= OC_F_FAILED;
Lck_Unlock(&oh->mtx);
}
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
* Remove the busyobj from an objcore * Remove the busyobj from an objcore
*/ */
......
...@@ -385,20 +385,18 @@ cnt_fetch(struct worker *wrk, struct req *req) ...@@ -385,20 +385,18 @@ cnt_fetch(struct worker *wrk, struct req *req)
assert(bo->refcount > 0); assert(bo->refcount > 0);
(void)HTTP1_DiscardReqBody(req); (void)HTTP1_DiscardReqBody(req);
/* bo->do_stream is not valid until after vcl_backend_response{} */ if (req->objcore->flags & OC_F_FAILED) {
if (!bo->do_stream)
VBO_waitstate(bo, BOS_FINISHED);
if (bo->state == BOS_FAILED) {
VBO_DerefBusyObj(wrk, &req->busyobj); VBO_DerefBusyObj(wrk, &req->busyobj);
req->err_code = 503; req->err_code = 503;
req->req_step = R_STP_ERROR; req->req_step = R_STP_ERROR;
req->objcore = NULL;
return (REQ_FSM_MORE); return (REQ_FSM_MORE);
} }
assert (bo->state >= BOS_FETCHING); assert (bo->state >= BOS_FETCHING);
req->err_code = bo->err_code; req->err_code = bo->err_code;
req->obj = bo->fetch_obj; // XXX: recnt ? req->obj = bo->fetch_obj; // XXX: recnt ?
req->objcore = NULL;
if (bo->state == BOS_FINISHED) if (bo->state == BOS_FINISHED)
VBO_DerefBusyObj(wrk, &req->busyobj); VBO_DerefBusyObj(wrk, &req->busyobj);
assert(WRW_IsReleased(wrk)); assert(WRW_IsReleased(wrk));
...@@ -609,7 +607,6 @@ cnt_miss(struct worker *wrk, struct req *req) ...@@ -609,7 +607,6 @@ cnt_miss(struct worker *wrk, struct req *req)
AN (req->objcore); AN (req->objcore);
req->busyobj = VBF_Fetch(wrk, req, req->objcore, VBF_NORMAL); req->busyobj = VBF_Fetch(wrk, req, req->objcore, VBF_NORMAL);
req->objcore = NULL;
req->req_step = R_STP_FETCH; req->req_step = R_STP_FETCH;
return (REQ_FSM_MORE); return (REQ_FSM_MORE);
} }
...@@ -634,7 +631,6 @@ XDOT err_pass [label="ERROR",shape=plaintext] ...@@ -634,7 +631,6 @@ XDOT err_pass [label="ERROR",shape=plaintext]
static enum req_fsm_nxt static enum req_fsm_nxt
cnt_pass(struct worker *wrk, struct req *req) cnt_pass(struct worker *wrk, struct req *req)
{ {
struct objcore *oc;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC); CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(req, REQ_MAGIC); CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
...@@ -654,9 +650,9 @@ cnt_pass(struct worker *wrk, struct req *req) ...@@ -654,9 +650,9 @@ cnt_pass(struct worker *wrk, struct req *req)
assert (wrk->handling == VCL_RET_FETCH); assert (wrk->handling == VCL_RET_FETCH);
req->acct_req.pass++; req->acct_req.pass++;
oc = HSH_Private(wrk); req->objcore = HSH_Private(wrk);
AN(oc); AN(req->objcore);
req->busyobj = VBF_Fetch(wrk, req, oc, VBF_PASS); req->busyobj = VBF_Fetch(wrk, req, req->objcore, VBF_PASS);
req->req_step = R_STP_FETCH; req->req_step = R_STP_FETCH;
return (REQ_FSM_MORE); return (REQ_FSM_MORE);
} }
......
...@@ -108,6 +108,7 @@ struct objhead { ...@@ -108,6 +108,7 @@ struct objhead {
#define hoh_head _u.n.u_n_hoh_head #define hoh_head _u.n.u_n_hoh_head
}; };
void HSH_Fail(struct objcore *);
void HSH_Unbusy(struct dstat *, struct objcore *); void HSH_Unbusy(struct dstat *, struct objcore *);
void HSH_Complete(struct objcore *oc); void HSH_Complete(struct objcore *oc);
void HSH_DeleteObjHead(struct dstat *, struct objhead *oh); void HSH_DeleteObjHead(struct dstat *, struct objhead *oh);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment