[master] a2d16c1 Store cached req.body in a vacuous objcore to avoid a special-case interface to stevedores.

Poul-Henning Kamp phk at FreeBSD.org
Mon Sep 15 16:59:46 CEST 2014


commit a2d16c17db1f51ccf27c280dea6ef6a6053de8cd
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Sep 15 14:58:48 2014 +0000

    Store cached req.body in a vacuous objcore to avoid a special-case
    interface to stevedores.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index fc7a2d9..75c4bdc 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -587,7 +587,7 @@ struct req {
 	VTAILQ_ENTRY(req)	w_list;
 
 	volatile enum req_body_state_e	req_body_status;
-	struct body		body[1];
+	struct objcore		*body_oc;
 
 	/* The busy objhead we sleep on */
 	struct objhead		*hash_objhead;
@@ -1225,7 +1225,6 @@ void STV_open(void);
 void STV_close(void);
 int STV_BanInfo(enum baninfo event, const uint8_t *ban, unsigned len);
 void STV_BanExport(const uint8_t *bans, unsigned len);
-struct storage *STV_alloc_transient(size_t size);
 
 /* storage_persistent.c */
 void SMP_Init(void);
diff --git a/bin/varnishd/cache/cache_obj.c b/bin/varnishd/cache/cache_obj.c
index 1d6399f..f57bd0b 100644
--- a/bin/varnishd/cache/cache_obj.c
+++ b/bin/varnishd/cache/cache_obj.c
@@ -96,7 +96,8 @@ ObjIterBegin(struct worker *wrk, struct objcore *oc)
 	oi->oc = oc;
 	oi->obj = obj;
 	oi->wrk = wrk;
-	oi->bo = HSH_RefBusy(oc);
+	if (oc->objhead != NULL)
+		oi->bo = HSH_RefBusy(oc);
 	return (oi);
 }
 
diff --git a/bin/varnishd/cache/cache_req_body.c b/bin/varnishd/cache/cache_req_body.c
index d39c51a..6eb2590 100644
--- a/bin/varnishd/cache/cache_req_body.c
+++ b/bin/varnishd/cache/cache_req_body.c
@@ -36,6 +36,7 @@
 #include "cache.h"
 #include "vtim.h"
 #include "storage/storage.h"
+#include "hash/hash_slinger.h"
 
 /*----------------------------------------------------------------------
  * Iterate over the req.body.
@@ -48,23 +49,28 @@ int
 VRB_Iterate(struct req *req, req_body_iter_f *func, void *priv)
 {
 	char buf[8192];
-	struct storage *st;
 	ssize_t l;
+	void *p;
 	int i;
 	struct vfp_ctx *vfc;
 	enum vfp_status vfps = VFP_ERROR;
+	struct objiter *oi;
+	enum objiter_status ois;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 	AN(func);
 
 	switch(req->req_body_status) {
 	case REQ_BODY_CACHED:
-		VTAILQ_FOREACH(st, &req->body->list, list) {
-			i = func(req, priv, st->ptr, st->len);
-			if (i)
-				return (i);
-		}
-		return (0);
+		oi = ObjIterBegin(req->wrk, req->body_oc);
+		AN(oi);
+		do {
+			ois = ObjIter(oi, &p, &l);
+			if (l > 0 && func(req, priv, p, l))
+				break;
+		} while (ois == OIS_DATA);
+		ObjIterEnd(&oi);
+		return (ois == OIS_DONE ? 0 : -1);
 	case REQ_BODY_NONE:
 		return (0);
 	case REQ_BODY_WITH_LEN:
@@ -164,14 +170,13 @@ VRB_Ignore(struct req *req)
 void
 VRB_Free(struct req *req)
 {
-	struct storage *st;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 
-	while (!VTAILQ_EMPTY(&req->body->list)) {
-		st = VTAILQ_FIRST(&req->body->list);
-		VTAILQ_REMOVE(&req->body->list, st, list);
-		STV_free(st);
+	if (req->body_oc != NULL) {
+		ObjFreeObj(req->body_oc, &req->wrk->stats);
+		FREE_OBJ(req->body_oc);
+		req->body_oc = NULL;
 	}
 }
 
@@ -185,9 +190,9 @@ VRB_Free(struct req *req)
 int
 VRB_Cache(struct req *req, ssize_t maxsize)
 {
-	struct storage *st;
 	ssize_t l, yet;
 	struct vfp_ctx *vfc;
+	uint8_t *ptr;
 	enum vfp_status vfps = VFP_ERROR;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
@@ -216,9 +221,15 @@ VRB_Cache(struct req *req, ssize_t maxsize)
 		return (-1);
 	}
 
+	req->body_oc = HSH_NewObjCore(req->wrk);
+	XXXAN(STV_NewObject(req->body_oc, req->vsl, &req->wrk->stats,
+	    TRANSIENT_STORAGE, 8));
+
 	VFP_Setup(vfc);
 	vfc->http = req->http;
 	vfc->vsl = req->vsl;
+	vfc->oc = req->body_oc;
+	vfc->stats = &req->wrk->stats;
 	V1F_Setup_Fetch(vfc, req->htc);
 
 	if (VFP_Open(vfc) < 0) {
@@ -229,45 +240,27 @@ VRB_Cache(struct req *req, ssize_t maxsize)
 	yet = req->htc->content_length;
 	if (yet < 0)
 		yet = 0;
-	st = NULL;
 	do {
-		if (st == NULL) {
-			st = STV_alloc_transient(
-			    yet ?  yet : cache_param->fetch_chunksize);
-			if (st == NULL) {
-				req->req_body_status = REQ_BODY_FAIL;
-				l = -1;
-				break;
-			} else {
-				VTAILQ_INSERT_TAIL(&req->body->list, st, list);
-			}
-		}
-		l = st->space - st->len;
-		vfps = VFP_Suck(vfc, st->ptr + st->len, &l);
-		if (vfps == VFP_ERROR) {
-			req->req_body_status = REQ_BODY_FAIL;
-			l = -1;
+		AZ(vfc->failed);
+		l = yet;
+		if (VFP_GetStorage(vfc, &l, &ptr) != VFP_OK)
 			break;
-		}
-		if (l > 0) {
+		AZ(vfc->failed);
+		AN(ptr);
+		AN(l);
+		vfps = VFP_Suck(vfc, ptr, &l);
+		if (l > 0 && vfps != VFP_ERROR) {
 			req->req_bodybytes += l;
 			req->acct.req_bodybytes += l;
-			if (yet > 0)
+			if (yet >= l)
 				yet -= l;
-			st->len += l;
-			if (st->space == st->len)
-				st = NULL;
-			l = 0;
-		}
-		if (req->req_bodybytes > maxsize) {
-			req->req_body_status = REQ_BODY_FAIL;
-			l = -1;
-			break;
+			ObjExtend(req->body_oc, &req->wrk->stats, l);
 		}
+
 	} while (vfps == VFP_OK);
 	VFP_Close(vfc);
 
-	if (l == 0) {
+	if (vfps == VFP_END) {
 
 		if (req->req_bodybytes != req->htc->content_length) {
 			/* We must update also the "pristine" req.* copy */
@@ -283,7 +276,9 @@ VRB_Cache(struct req *req, ssize_t maxsize)
 		}
 
 		req->req_body_status = REQ_BODY_CACHED;
+	} else {
+		req->req_body_status = REQ_BODY_FAIL;
 	}
 	VSLb_ts_req(req, "ReqBody", VTIM_real());
-	return (l);
+	return (vfps == VFP_END ? req->req_bodybytes : 0);
 }
diff --git a/bin/varnishd/cache/cache_session.c b/bin/varnishd/cache/cache_session.c
index b6d8049..6aa07b4 100644
--- a/bin/varnishd/cache/cache_session.c
+++ b/bin/varnishd/cache/cache_session.c
@@ -374,8 +374,6 @@ SES_GetReq(const struct worker *wrk, struct sess *sp)
 	req->t_prev = NAN;
 	req->t_req = NAN;
 
-	VTAILQ_INIT(&req->body->list);
-
 	return (req);
 }
 
diff --git a/bin/varnishd/storage/stevedore.c b/bin/varnishd/storage/stevedore.c
index 58ab16f..2a5e692 100644
--- a/bin/varnishd/storage/stevedore.c
+++ b/bin/varnishd/storage/stevedore.c
@@ -291,13 +291,6 @@ STV_NewObject(struct objcore *oc, struct vsl_log *vsl, struct dstat *stats,
 
 /*-------------------------------------------------------------------*/
 
-struct storage *
-STV_alloc_transient(size_t size)
-{
-
-	return (STV_alloc(stv_transient, size));
-}
-
 void
 STV_trim(struct storage *st, size_t size, int move_ok)
 {



More information about the varnish-commit mailing list