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

Reply via email to