r5565 - trunk/varnish-cache/bin/varnishd

phk at varnish-cache.org phk at varnish-cache.org
Sun Nov 21 00:59:48 CET 2010


Author: phk
Date: 2010-11-21 00:59:48 +0100 (Sun, 21 Nov 2010)
New Revision: 5565

Modified:
   trunk/varnish-cache/bin/varnishd/storage_persistent.c
Log:
The -spersistemt objcore->obj translation must use the object index
rather than the pointer, otherwise a number of nasty issues appear.



Modified: trunk/varnish-cache/bin/varnishd/storage_persistent.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/storage_persistent.c	2010-11-20 23:58:43 UTC (rev 5564)
+++ trunk/varnish-cache/bin/varnishd/storage_persistent.c	2010-11-20 23:59:48 UTC (rev 5565)
@@ -645,7 +645,7 @@
 }
 
 /*---------------------------------------------------------------------
- * objcore methods for zombie objects
+ * objcore methods for persistent objects
  */
 
 static struct object *
@@ -653,38 +653,42 @@
 {
 	struct object *o;
 	struct smp_seg *sg;
-	struct smp_object *so;
+	unsigned smp_index;
 
-	CAST_OBJ_NOTNULL(sg, oc->priv2, SMP_SEG_MAGIC);
+	/* Some calls are direct, but they should match anyway */
+	assert(oc->methods->getobj == smp_oc_getobj);
 
-	/*
-	 * XXX: failed checks here should fail gracefully and not assert
-	 */
-	so = oc->priv;
-	xxxassert(so >= sg->objs && so <= sg->objs + sg->nalloc2);
+	CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
+	if (wrk == NULL)
+		AZ(oc->flags & OC_F_NEEDFIXUP);
 
-	o = so->ptr;
+	CAST_OBJ_NOTNULL(sg, oc->priv2, SMP_SEG_MAGIC);
+	smp_index = (uintptr_t) oc->priv;
+	assert(smp_index < sg->nalloc2);
 
+	o = sg->objs[smp_index].ptr;
 	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 
-	if (wrk == NULL)
-		AZ(oc->flags & OC_F_NEEDFIXUP);
+	/*
+	 * If this flag is not set, it will not be, and the lock is not
+	 * needed to test it.
+	 */
+	if (!(oc->flags & OC_F_NEEDFIXUP))
+		return (o);
 
+	AN(wrk);
+	Lck_Lock(&sg->sc->mtx);
+	/* Check again, we might have raced. */
 	if (oc->flags & OC_F_NEEDFIXUP) {
-		AN(wrk);
-		Lck_Lock(&sg->sc->mtx);
-		if (oc->flags & OC_F_NEEDFIXUP) {
-			oc->flags &= ~OC_F_NEEDFIXUP;
+		/* refcnt is >=1 because the object is in the hash */
+		o->objcore = oc;
 
-			/* refcnt is one because the object is in the hash */
-			o->objcore = oc;
-
-			sg->nfixed++;
-			wrk->stats.n_object++;
-			wrk->stats.n_vampireobject--;
-		}
-		Lck_Unlock(&sg->sc->mtx);
+		sg->nfixed++;
+		wrk->stats.n_object++;
+		wrk->stats.n_vampireobject--;
+		oc->flags &= ~OC_F_NEEDFIXUP;
 	}
+	Lck_Unlock(&sg->sc->mtx);
 	return (o);
 }
 
@@ -880,7 +884,7 @@
 {
 	struct smp_object *so;
 	struct objcore *oc;
-	uint32_t no;
+	uint32_t no, n;
 	double t_now = TIM_real();
 	struct smp_signctx ctx[1];
 
@@ -902,14 +906,15 @@
 	no = sg->p.nalloc;
 	/* Clear the bogus "hold" count */
 	sg->nobj = 0;
-	for (;no > 0; so++,no--) {
+	n = 0;
+	for (;no > 0; so++,no--,n++) {
 		if (so->ttl < t_now)
 			continue;
 		HSH_Prealloc(sp);
 		oc = sp->wrk->nobjcore;
 		oc->flags |= OC_F_NEEDFIXUP | OC_F_LRUDONTMOVE;
 		oc->flags &= ~OC_F_BUSY;
-		oc->priv = so;
+		oc->priv = (void*)(uintptr_t)n;
 		oc->priv2 = sg;
 		oc->methods = &smp_oc_methods;
 		oc->ban = BAN_RefBan(oc, so->ban, sc->tailban);
@@ -1373,14 +1378,6 @@
 		sg->nalloc1++;
 		sc->objreserv += sizeof (struct smp_object);
 		assert(sc->objreserv <= smp_spaceleft(sg));
-		/*
-		 * NB: Tricky.
-		 * We can not use the smp_getobj() method yet, because the
-		 * smp_object's position is not finalized until the segment
-		 * closes.  Fortunately we don't need to either, because newly
-		 * created objects will never regress into NEEDFIXUP state, 
-		 * so the default oc->methods, will do just fine.
-		 */
 		*sgp = sg;
 	}
 
@@ -1453,6 +1450,10 @@
 	so->ptr = o;
 	so->ban = o->ban_t;
 
+	oc->priv = (void*)(uintptr_t)(o->smp_index);
+	oc->priv2 = sg;
+	oc->methods = &smp_oc_methods;
+
 	Lck_Unlock(&sc->mtx);
 	return (o);
 }




More information about the varnish-commit mailing list