[master] ab82163 Propagate BOS_FAILED to the objcore, and ignore OC_F_FAILED objects in HSH_Lookup()
Poul-Henning Kamp
phk at varnish-cache.org
Tue Sep 3 13:57:28 CEST 2013
commit ab821632f695427357849fd63f36523600916e7a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Sep 3 11:56:58 2013 +0000
Propagate BOS_FAILED to the objcore, and ignore OC_F_FAILED objects
in HSH_Lookup()
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 9b68f79..71bff9c 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -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;
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 1f8ec3d..d365158 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -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);
}
diff --git a/bin/varnishd/cache/cache_fetch_proc.c b/bin/varnishd/cache/cache_fetch_proc.c
index 37a2f4d..2871b73 100644
--- a/bin/varnishd/cache/cache_fetch_proc.c
+++ b/bin/varnishd/cache/cache_fetch_proc.c
@@ -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);
diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 6fd51f6..ad63438 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -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)
@@ -624,6 +627,24 @@ HSH_Drop(struct worker *wrk, struct object **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
*/
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 442d7db..f8317b5 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -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);
}
diff --git a/bin/varnishd/hash/hash_slinger.h b/bin/varnishd/hash/hash_slinger.h
index 79443c7..5d9e91d 100644
--- a/bin/varnishd/hash/hash_slinger.h
+++ b/bin/varnishd/hash/hash_slinger.h
@@ -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);
More information about the varnish-commit
mailing list