Commit 99c0a172 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Hmm, I still don't understand the args to git commit it seems...

Commit the code that prevents all the evils mentionend in the
previous commit message (see tests/p00007.vtc)
parent f9a8797d
...@@ -101,7 +101,9 @@ struct smp_seg { ...@@ -101,7 +101,9 @@ struct smp_seg {
struct smp_segptr p; struct smp_segptr p;
unsigned must_load; unsigned flags;
#define SMP_SEG_MUSTLOAD (1 << 0)
#define SMP_SEG_LOADED (1 << 1)
uint32_t nobj; /* Number of objects */ uint32_t nobj; /* Number of objects */
uint32_t nalloc; /* Allocations */ uint32_t nalloc; /* Allocations */
...@@ -120,7 +122,7 @@ struct smp_sc { ...@@ -120,7 +122,7 @@ struct smp_sc {
struct stevedore *parent; struct stevedore *parent;
unsigned flags; unsigned flags;
#define SMP_F_LOADED (1 << 0) #define SMP_SC_LOADED (1 << 0)
const struct stevedore *stevedore; const struct stevedore *stevedore;
int fd; int fd;
...@@ -675,6 +677,54 @@ smp_find_so(const struct smp_seg *sg, const struct objcore *oc) ...@@ -675,6 +677,54 @@ smp_find_so(const struct smp_seg *sg, const struct objcore *oc)
return (so); return (so);
} }
/*---------------------------------------------------------------------
* Check if a given storage structure is valid to use
*/
static int
smp_loaded_st(const struct smp_sc *sc, const struct smp_seg *sg,
const struct storage *st)
{
struct smp_seg *sg2;
const uint8_t *pst;
uint64_t o;
(void)sg; /* XXX: faster: Start search from here */
pst = (const void *)st;
if (pst < (sc->base + sc->ident->stuff[SMP_SPC_STUFF]))
return (0x01); /* Before silo payload start */
if (pst > (sc->base + sc->ident->stuff[SMP_END_STUFF]))
return (0x02); /* After silo end */
o = pst - sc->base;
/* Find which segment contains the storage structure */
VTAILQ_FOREACH(sg2, &sc->segments, list)
if (o > sg2->p.offset && (o + sizeof(*st)) < sg2->p.objlist)
break;
if (sg2 == NULL)
return (0x04); /* No claiming segment */
if (!(sg2->flags & SMP_SEG_LOADED))
return (0x08); /* Claiming segment not loaded */
/* It is now safe to access the storage structure */
if (st->magic != STORAGE_MAGIC)
return (0x10); /* Not enough magic */
if (o + st->space >= sg2->p.objlist)
return (0x20); /* Allocation not inside segment */
if (st->len > st->space)
return (0x40); /* Plain bad... */
/*
* XXX: We could patch up st->stevedore and st->priv here
* XXX: but if things go right, we will never need them.
*/
return (0);
}
/*--------------------------------------------------------------------- /*---------------------------------------------------------------------
* objcore methods for persistent objects * objcore methods for persistent objects
*/ */
...@@ -685,6 +735,9 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc) ...@@ -685,6 +735,9 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc)
struct object *o; struct object *o;
struct smp_seg *sg; struct smp_seg *sg;
struct smp_object *so; struct smp_object *so;
struct storage *st;
uint64_t l;
int bad;
/* Some calls are direct, but they should match anyway */ /* Some calls are direct, but they should match anyway */
assert(oc->methods->getobj == smp_oc_getobj); assert(oc->methods->getobj == smp_oc_getobj);
...@@ -717,9 +770,26 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc) ...@@ -717,9 +770,26 @@ smp_oc_getobj(struct worker *wrk, struct objcore *oc)
Lck_Lock(&sg->sc->mtx); Lck_Lock(&sg->sc->mtx);
/* Check again, we might have raced. */ /* Check again, we might have raced. */
if (oc->flags & OC_F_NEEDFIXUP) { if (oc->flags & OC_F_NEEDFIXUP) {
/* refcnt is >=1 because the object is in the hash */ /* We trust caller to have a refcnt for us */
o->objcore = oc; o->objcore = oc;
bad = 0;
l = 0;
VTAILQ_FOREACH(st, &o->store, list) {
bad |= smp_loaded_st(sg->sc, sg, st);
if (bad)
break;
l += st->len;
}
if (l != o->len)
bad |= 0x100;
if(bad) {
o->ttl = 0;
o->grace = 0;
so->ttl = 0;
}
sg->nfixed++; sg->nfixed++;
wrk->stats.n_object++; wrk->stats.n_object++;
wrk->stats.n_vampireobject--; wrk->stats.n_vampireobject--;
...@@ -939,8 +1009,8 @@ smp_load_seg(const struct sess *sp, const struct smp_sc *sc, struct smp_seg *sg) ...@@ -939,8 +1009,8 @@ smp_load_seg(const struct sess *sp, const struct smp_sc *sc, struct smp_seg *sg)
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC); CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC);
CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC);
assert(sg->must_load == 1); assert(sg->flags & SMP_SEG_MUSTLOAD);
sg->must_load = 0; sg->flags &= ~SMP_SEG_MUSTLOAD;
AN(sg->p.offset); AN(sg->p.offset);
if (sg->p.objlist == 0) if (sg->p.objlist == 0)
return; return;
...@@ -975,6 +1045,7 @@ smp_load_seg(const struct sess *sp, const struct smp_sc *sc, struct smp_seg *sg) ...@@ -975,6 +1045,7 @@ smp_load_seg(const struct sess *sp, const struct smp_sc *sc, struct smp_seg *sg)
sg->nobj++; sg->nobj++;
} }
WRK_SumStat(sp->wrk); WRK_SumStat(sp->wrk);
sg->flags |= SMP_SEG_LOADED;
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -1062,7 +1133,7 @@ smp_open_segs(struct smp_sc *sc, struct smp_signctx *ctx) ...@@ -1062,7 +1133,7 @@ smp_open_segs(struct smp_sc *sc, struct smp_signctx *ctx)
CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC);
sg->p = *ss; sg->p = *ss;
sg->must_load = 1; sg->flags |= SMP_SEG_MUSTLOAD;
/* /*
* HACK: prevent save_segs from nuking segment until we have * HACK: prevent save_segs from nuking segment until we have
...@@ -1248,10 +1319,10 @@ smp_thread(struct sess *sp, void *priv) ...@@ -1248,10 +1319,10 @@ smp_thread(struct sess *sp, void *priv)
/* First, load all the objects from all segments */ /* First, load all the objects from all segments */
VTAILQ_FOREACH(sg, &sc->segments, list) VTAILQ_FOREACH(sg, &sc->segments, list)
if (sg->must_load) if (sg->flags & SMP_SEG_MUSTLOAD)
smp_load_seg(sp, sc, sg); smp_load_seg(sp, sc, sg);
sc->flags |= SMP_F_LOADED; sc->flags |= SMP_SC_LOADED;
BAN_Deref(&sc->tailban); BAN_Deref(&sc->tailban);
sc->tailban = NULL; sc->tailban = NULL;
printf("Silo completely loaded\n"); printf("Silo completely loaded\n");
...@@ -1535,7 +1606,7 @@ SMP_Ready(void) ...@@ -1535,7 +1606,7 @@ SMP_Ready(void)
ASSERT_CLI(); ASSERT_CLI();
do { do {
VTAILQ_FOREACH(sc, &silos, list) VTAILQ_FOREACH(sc, &silos, list)
if (!(sc->flags & SMP_F_LOADED)) if (!(sc->flags & SMP_SC_LOADED))
break; break;
if (sc != NULL) if (sc != NULL)
(void)sleep(1); (void)sleep(1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment