This then also breaks the previous expectation that cur_seg would always be non-NULL. Change the code to take this into account. --- bin/varnishd/storage/storage_persistent.c | 24 +++++--- bin/varnishd/storage/storage_persistent_silo.c | 71 ++++++++++++------------ 2 files changed, 54 insertions(+), 41 deletions(-)
diff --git a/bin/varnishd/storage/storage_persistent.c b/bin/varnishd/storage/storage_persistent.c index b54f497..744a5da 100644 --- a/bin/varnishd/storage/storage_persistent.c +++ b/bin/varnishd/storage/storage_persistent.c @@ -368,7 +368,9 @@ smp_close(const struct stevedore *st) CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); Lck_Lock(&sc->mtx); - smp_close_seg(sc, sc->cur_seg); + if (sc->cur_seg != NULL) + smp_close_seg(sc, sc->cur_seg); + AZ(sc->cur_seg); Lck_Unlock(&sc->mtx); /* XXX: reap thread */ @@ -393,7 +395,6 @@ smp_allocx(struct stevedore *st, size_t min_size, size_t max_size, struct smp_sc *sc; struct storage *ss; struct smp_seg *sg; - unsigned tries; uint64_t left, extra; CAST_OBJ_NOTNULL(sc, st->priv, SMP_SC_MAGIC); @@ -411,14 +412,22 @@ smp_allocx(struct stevedore *st, size_t min_size, size_t max_size, Lck_Lock(&sc->mtx); sg = NULL; ss = NULL; - for (tries = 0; tries < 3; tries++) { + + left = 0; + if (sc->cur_seg != NULL) left = smp_spaceleft(sc, sc->cur_seg); - if (left >= extra + min_size) - break; - smp_close_seg(sc, sc->cur_seg); + if (left < extra + min_size) { + if (sc->cur_seg != NULL) + smp_close_seg(sc, sc->cur_seg); smp_new_seg(sc); + if (sc->cur_seg != NULL) + left = smp_spaceleft(sc, sc->cur_seg); + else + left = 0; } + if (left >= extra + min_size) { + AN(sc->cur_seg); if (left < extra + max_size) max_size = IRNDN(sc, left - extra); @@ -611,7 +620,8 @@ debug_persistent(struct cli *cli, const char * const * av, void *priv) } Lck_Lock(&sc->mtx); if (!strcmp(av[3], "sync")) { - smp_close_seg(sc, sc->cur_seg); + if (sc->cur_seg != NULL) + smp_close_seg(sc, sc->cur_seg); smp_new_seg(sc); } else if (!strcmp(av[3], "dump")) { debug_report_silo(cli, sc, 1); diff --git a/bin/varnishd/storage/storage_persistent_silo.c b/bin/varnishd/storage/storage_persistent_silo.c index d433cde..0014647 100644 --- a/bin/varnishd/storage/storage_persistent_silo.c +++ b/bin/varnishd/storage/storage_persistent_silo.c @@ -171,48 +171,50 @@ smp_load_seg(struct worker *wrk, const struct smp_sc *sc, void smp_new_seg(struct smp_sc *sc) { - struct smp_seg *sg, *sg2; + struct smp_seg tmpsg; + struct smp_seg *sg; + AZ(sc->cur_seg); Lck_AssertHeld(&sc->mtx); - ALLOC_OBJ(sg, SMP_SEG_MAGIC); - AN(sg); - sg->sc = sc; - sg->lru = LRU_Alloc(); - CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); /* XXX: find where it goes in silo */ - sg->p.offset = sc->free_offset; - // XXX: align */ - assert(sg->p.offset >= sc->ident->stuff[SMP_SPC_STUFF]); - assert(sg->p.offset < sc->mediasize); - - sg->p.length = sc->aim_segl; - sg->p.length &= ~7; - - if (smp_segend(sg) > sc->mediasize) { - sc->free_offset = sc->ident->stuff[SMP_SPC_STUFF]; - sg->p.offset = sc->free_offset; - sg2 = VTAILQ_FIRST(&sc->segments); - if (smp_segend(sg) > sg2->p.offset) { - printf("Out of space in persistent silo\n"); - printf("Committing suicide, restart will make space\n"); - exit (0); - } + memset(&tmpsg, 0, sizeof tmpsg); + tmpsg.magic = SMP_SEG_MAGIC; + tmpsg.sc = sc; + tmpsg.p.offset = sc->free_offset; + /* XXX: align */ + assert(tmpsg.p.offset >= sc->ident->stuff[SMP_SPC_STUFF]); + assert(tmpsg.p.offset < sc->mediasize); + + tmpsg.p.length = sc->aim_segl; + tmpsg.p.length &= ~7; + + if (smp_segend(&tmpsg) > sc->mediasize) + /* XXX: Consider truncation in this case */ + tmpsg.p.offset = sc->ident->stuff[SMP_SPC_STUFF]; + + assert(smp_segend(&tmpsg) <= sc->mediasize); + + sg = VTAILQ_FIRST(&sc->segments); + if (sg != NULL && tmpsg.p.offset <= sg->p.offset) { + if (smp_segend(&tmpsg) > sg->p.offset) + /* No more space, return (cur_seg will be NULL) */ + /* XXX: Consider truncation instead of failing */ + return; + assert(smp_segend(&tmpsg) <= sg->p.offset); } + if (tmpsg.p.offset == sc->ident->stuff[SMP_SPC_STUFF]) + printf("Wrapped silo\n"); - assert(smp_segend(sg) <= sc->mediasize); - - sg2 = VTAILQ_FIRST(&sc->segments); - if (sg2 != NULL && sg2->p.offset > sc->free_offset) { - if (smp_segend(sg) > sg2->p.offset) { - printf("Out of space in persistent silo\n"); - printf("Committing suicide, restart will make space\n"); - exit (0); - } - assert(smp_segend(sg) <= sg2->p.offset); - } + ALLOC_OBJ(sg, SMP_SEG_MAGIC); + if (sg == NULL) + /* Failed allocation */ + return; + *sg = tmpsg; + sg->lru = LRU_Alloc(); + CHECK_OBJ_NOTNULL(sg->lru, LRU_MAGIC); sg->p.offset = IRNUP(sc, sg->p.offset); sg->p.length = IRNDN(sc, sg->p.length); @@ -248,6 +250,7 @@ smp_close_seg(struct smp_sc *sc, struct smp_seg *sg) Lck_AssertHeld(&sc->mtx); + CHECK_OBJ_NOTNULL(sg, SMP_SEG_MAGIC); assert(sg == sc->cur_seg); AN(sg->p.offset); sc->cur_seg = NULL; -- 1.7.9.5 _______________________________________________ varnish-dev mailing list varnish-dev@varnish-cache.org https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev