Commit f9cb9091 authored by Martin Blix Grydeland's avatar Martin Blix Grydeland

Don't exit on full silo

This then also breaks the previous expectation that cur_seg would
always be non-NULL. Change the code to take this into account.
parent c74c4574
......@@ -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);
......
......@@ -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 = RDN2(tmpsg.p.length, 8);
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;
......
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