[master] e8985f227 Convert req->top to a structure so we can store more stuff in it.

Poul-Henning Kamp phk at FreeBSD.org
Thu Dec 6 10:31:17 UTC 2018


commit e8985f22711fe9a342b27a10052ae3655f64435c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu Dec 6 10:29:46 2018 +0000

    Convert req->top to a structure so we can
    store more stuff in it.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b7e6e1f7e..c202381d6 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -444,6 +444,12 @@ struct busyobj {
 
 /*--------------------------------------------------------------------*/
 
+struct reqtop {
+	unsigned		magic;
+#define REQTOP_MAGIC		0x57fbda52
+	struct req		*topreq;
+};
+
 struct req {
 	unsigned		magic;
 #define REQ_MAGIC		0x2751aaa1
@@ -453,7 +459,7 @@ struct req {
 	enum sess_close		doclose;
 	int			restarts;
 	int			esi_level;
-	struct req		*top;	/* esi_level == 0 request */
+	struct reqtop		*top;	/* esi_level == 0 request */
 
 #define REQ_FLAG(l, r, w, d) unsigned	l:1;
 #include "tbl/req_flags.h"
diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c
index 9d1fd4782..c4733af7d 100644
--- a/bin/varnishd/cache/cache_esi_deliver.c
+++ b/bin/varnishd/cache/cache_esi_deliver.c
@@ -103,6 +103,7 @@ ved_include(struct req *preq, const char *src, const char *host,
 	enum req_fsm_nxt s;
 
 	CHECK_OBJ_NOTNULL(preq, REQ_MAGIC);
+	CHECK_OBJ_NOTNULL(preq->top, REQTOP_MAGIC);
 	sp = preq->sp;
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(ecx, ECX_MAGIC);
@@ -124,11 +125,6 @@ ved_include(struct req *preq, const char *src, const char *host,
 	VSLb(preq->vsl, SLT_Link, "req %u esi", VXID(req->vsl->wid));
 	req->esi_level = preq->esi_level + 1;
 
-	if (preq->esi_level == 0)
-		assert(preq->top == preq);
-	else
-		CHECK_OBJ_NOTNULL(preq->top, REQ_MAGIC);
-
 	req->top = preq->top;
 
 	HTTP_Copy(req->http0, preq->http0);
@@ -263,6 +259,17 @@ ved_vdp_esi_init(struct req *req, void **priv)
 	ecx->preq = req;
 	*priv = ecx;
 	RFC2616_Weaken_Etag(req->resp);
+
+	if (req->esi_level == 0) {
+		Req_MakeTop(req);
+		if (req->top == NULL) {
+			VSLb(req->vsl, SLT_Error,
+			    "(top)request workspace overflow");
+			Req_Fail(req, SC_OVERLOAD);
+			return (-1);
+		}
+	}
+
 	req->res_mode |= RES_ESI;
 	if (req->resp_len != 0)
 		req->resp_len = -1;
diff --git a/bin/varnishd/cache/cache_req.c b/bin/varnishd/cache/cache_req.c
index 5ab13a2cf..e0ade75a6 100644
--- a/bin/varnishd/cache/cache_req.c
+++ b/bin/varnishd/cache/cache_req.c
@@ -93,7 +93,6 @@ Req_New(const struct worker *wrk, struct sess *sp)
 	AN(req);
 	req->magic = REQ_MAGIC;
 	req->sp = sp;
-	req->top = req;	// esi overrides
 
 	e = (char*)req + sz;
 	p = (char*)(req + 1);
@@ -176,6 +175,7 @@ Req_Release(struct req *req)
 	MPL_AssertSane(req);
 	VSL_Flush(req->vsl, 0);
 	req->sp = NULL;
+	req->top = NULL;
 	MPL_Free(pp->mpl_req, req);
 }
 
@@ -194,6 +194,7 @@ Req_Rollback(struct req *req)
 	if (WS_Overflowed(req->ws))
 		req->wrk->stats->ws_client_overflow++;
 	WS_Reset(req->ws, req->ws_req);
+	req->top = NULL;
 }
 
 /*----------------------------------------------------------------------
@@ -211,10 +212,10 @@ Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req)
 
 	req->director_hint = NULL;
 	req->restarts = 0;
+	req->top = 0;
 
 	AZ(req->esi_level);
 	AZ(req->privs->magic);
-	assert(req->top == req);
 
 	if (req->vcl != NULL) {
 		if (wrk->vcl != NULL)
@@ -261,3 +262,20 @@ Req_Fail(struct req *req, enum sess_close reason)
 	AN(req->transport->req_fail);
 	req->transport->req_fail(req, reason);
 }
+
+/*----------------------------------------------------------------------
+ */
+
+void
+Req_MakeTop(struct req *req)
+{
+
+	CHECK_OBJ_ORNULL(req->top, REQTOP_MAGIC);
+	if (req->top != NULL)
+		return;
+	req->top = WS_Alloc(req->ws, sizeof *req->top);
+	if (req->top != NULL) {
+		INIT_OBJ(req->top, REQTOP_MAGIC);
+		req->top->topreq = req;
+	}
+}
diff --git a/bin/varnishd/cache/cache_varnishd.h b/bin/varnishd/cache/cache_varnishd.h
index 8b5ad9ebd..ef3184bed 100644
--- a/bin/varnishd/cache/cache_varnishd.h
+++ b/bin/varnishd/cache/cache_varnishd.h
@@ -314,6 +314,7 @@ void Req_Rollback(struct req *req);
 void Req_Cleanup(struct sess *sp, struct worker *wrk, struct req *req);
 void Req_Fail(struct req *req, enum sess_close reason);
 void Req_AcctLogCharge(struct VSC_main_wrk *, struct req *);
+void Req_MakeTop(struct req *req);
 
 /* cache_req_body.c */
 int VRB_Ignore(struct req *);
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 418c6d7ee..de2c35502 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -94,7 +94,11 @@ VCL_Req2Ctx(struct vrt_ctx *ctx, struct req *req)
 	ctx->vcl = req->vcl;
 	ctx->vsl = req->vsl;
 	ctx->http_req = req->http;
-	ctx->http_req_top = req->top->http;
+	CHECK_OBJ_ORNULL(req->top, REQTOP_MAGIC);
+	if (req->top != NULL)
+		ctx->http_req_top = req->top->topreq->http;
+	else
+		ctx->http_req_top = req->http;
 	ctx->http_resp = req->resp;
 	ctx->req = req;
 	ctx->sp = req->sp;
diff --git a/bin/varnishd/cache/cache_vrt_priv.c b/bin/varnishd/cache/cache_vrt_priv.c
index 0719e203f..f1940ea4d 100644
--- a/bin/varnishd/cache/cache_vrt_priv.c
+++ b/bin/varnishd/cache/cache_vrt_priv.c
@@ -158,17 +158,23 @@ struct vmod_priv *
 VRT_priv_top(VRT_CTX, const void *vmod_id)
 {
 	struct vrt_privs *vps;
+	struct req *req;
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
-	if (ctx->req) {
-		CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
-		CHECK_OBJ_NOTNULL(ctx->req->top, REQ_MAGIC);
-		CAST_OBJ_NOTNULL(vps, ctx->req->top->privs, VRT_PRIVS_MAGIC);
-		return (vrt_priv_dynamic(ctx->req->top->ws, vps,
-		    (uintptr_t)vmod_id));
-	} else
+	if (ctx->req == NULL) {
 		WRONG("PRIV_TOP is only accessible in client VCL context");
-	NEEDLESS(return NULL);
+		NEEDLESS(return NULL);
+	}
+	CHECK_OBJ_NOTNULL(ctx->req, REQ_MAGIC);
+	if (ctx->req->top != NULL) {
+		CHECK_OBJ_NOTNULL(ctx->req->top, REQTOP_MAGIC);
+		CHECK_OBJ_NOTNULL(ctx->req->top->topreq, REQ_MAGIC);
+		req = ctx->req->top->topreq;
+	} else {
+		req = ctx->req;
+	}
+	CAST_OBJ_NOTNULL(vps, req->privs, VRT_PRIVS_MAGIC);
+	return (vrt_priv_dynamic(req->ws, vps, (uintptr_t)vmod_id));
 }
 
 /*--------------------------------------------------------------------
diff --git a/bin/varnishd/cache/cache_vrt_vcl.c b/bin/varnishd/cache/cache_vrt_vcl.c
index 4147e211c..5b443017c 100644
--- a/bin/varnishd/cache/cache_vrt_vcl.c
+++ b/bin/varnishd/cache/cache_vrt_vcl.c
@@ -411,6 +411,7 @@ vcl_call_method(struct worker *wrk, struct req *req, struct busyobj *bo,
 		CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
 		CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC);
 		CHECK_OBJ_NOTNULL(req->vcl, VCL_MAGIC);
+		CHECK_OBJ_ORNULL(req->top, REQTOP_MAGIC);
 		VCL_Req2Ctx(&ctx, req);
 	}
 	if (bo != NULL) {


More information about the varnish-commit mailing list