[master] 6d86cd1 Don't hand objects over to EXP until we have fetched the body.

Poul-Henning Kamp phk at varnish-cache.org
Tue Nov 5 09:23:20 CET 2013


commit 6d86cd16afaddf546ef1d6e362a9b80e30c642f6
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Nov 5 08:22:26 2013 +0000

    Don't hand objects over to EXP until we have fetched the body.
    
    This closes (some of) a race where EXP would start to dismantle
    an object while it was still being streamed.
    
    Also spotted by: jw

diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 6a177b5..49ea75f 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -422,13 +422,8 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	assert(bo->refcount >= 1);
 
 	AZ(bo->ws_o->overflow);
-	if (bo->do_stream) {
+	if (bo->do_stream)
 		HSH_Unbusy(&wrk->stats, obj->objcore);
-		if (!(obj->objcore->flags & OC_F_PRIVATE)) {
-			EXP_Insert(obj->objcore);
-			AN(obj->objcore->ban);
-		}
-	}
 
 	if (bo->vfp == NULL)
 		bo->vfp = &VFP_nop;
@@ -437,13 +432,14 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	VBO_setstate(bo, BOS_FETCHING);
 
 	V1F_fetch_body(wrk, bo);
-	if (!bo->do_stream && bo->state != BOS_FAILED) {
+	if (!bo->do_stream && bo->state != BOS_FAILED)
 		HSH_Unbusy(&wrk->stats, obj->objcore);
-		if (!(bo->fetch_obj->objcore->flags & OC_F_PRIVATE)) {
-			EXP_Insert(obj->objcore);
-			AN(obj->objcore->ban);
-		}
+
+	if (bo->state != BOS_FAILED && !(obj->objcore->flags & OC_F_PRIVATE)) {
+		EXP_Insert(obj->objcore);
+		AN(obj->objcore->ban);
 	}
+
 	HSH_Complete(obj->objcore);
 
 	assert(bo->refcount >= 1);
diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c
index 95862ae..b7bd8d8 100644
--- a/bin/varnishd/cache/cache_obj.c
+++ b/bin/varnishd/cache/cache_obj.c
@@ -94,6 +94,7 @@ ObjIter(struct objiter *oi, void **p, ssize_t *l)
 				return (OIS_ERROR);
 		}
 		Lck_Lock(&oi->bo->mtx);
+		AZ(VTAILQ_EMPTY(&oi->obj->store));
 		VTAILQ_FOREACH(oi->st, &oi->obj->store, list) {
 			if (oi->st->len > ol) {
 				*p = oi->st->ptr + ol;
@@ -104,6 +105,7 @@ ObjIter(struct objiter *oi, void **p, ssize_t *l)
 			ol -= oi->st->len;
 			nl -= oi->st->len;
 		}
+		CHECK_OBJ_NOTNULL(oi->st, STORAGE_MAGIC);
 		oi->st = VTAILQ_NEXT(oi->st, list);
 		if (oi->st != NULL && oi->st->len == 0)
 			oi->st = NULL;
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 37ec19e..9218584 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -105,7 +105,8 @@ cnt_deliver(struct worker *wrk, struct req *req)
 
 	req->t_resp = W_TIM_real(wrk);
 	if (!(req->obj->objcore->flags & OC_F_PRIVATE)) {
-		if ((req->t_resp - req->obj->objcore->last_lru) >
+		if (req->obj->objcore->busyobj == NULL &&
+		    (req->t_resp - req->obj->objcore->last_lru) >
 		    cache_param->lru_timeout && EXP_Touch(req->obj->objcore))
 			req->obj->objcore->last_lru = req->t_resp;
 	}



More information about the varnish-commit mailing list