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