X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fswap.c;h=1ef672f7e9e7a3ce565b57ce9597bd7ff60d3ff3;hb=b57b06258e0b1894edb6d1fc52a80b3c33164892;hp=cc03b14e7688cac83f61bce5f4898ddabc455041;hpb=976dec6e7b2d193533191be2969dd4eee95fc6bb;p=elogind.git diff --git a/src/core/swap.c b/src/core/swap.c index cc03b14e7..1ef672f7e 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -473,6 +473,7 @@ static int swap_process_new_swap(Manager *m, const char *device, int prio, bool static void swap_set_state(Swap *s, SwapState state) { SwapState old_state; + Swap *other; assert(s); @@ -500,6 +501,15 @@ static void swap_set_state(Swap *s, SwapState state) { swap_state_to_string(state)); unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true); + + /* If there other units for the same device node have a job + queued it might be worth checking again if it is runnable + now. This is necessary, since swap_start() refuses + operation with EAGAIN if there's already another job for + the same device node queued. */ + LIST_FOREACH_OTHERS(same_devnode, other, s) + if (UNIT(other)->job) + job_add_to_run_queue(UNIT(other)->job); } static int swap_coldplug(Unit *u) { @@ -796,7 +806,7 @@ fail: } static int swap_start(Unit *u) { - Swap *s = SWAP(u); + Swap *s = SWAP(u), *other; assert(s); @@ -818,6 +828,13 @@ static int swap_start(Unit *u) { if (detect_container(NULL) > 0) return -EPERM; + /* If there's a job for another swap unit for the same node + * running, then let's not dispatch this one for now, and wait + * until that other job has finished. */ + LIST_FOREACH_OTHERS(same_devnode, other, s) + if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING) + return -EAGAIN; + s->result = SWAP_SUCCESS; swap_enter_activating(s); return 0; @@ -1178,11 +1195,7 @@ static Unit *swap_following(Unit *u) { if (s->from_fragment) return NULL; - LIST_FOREACH_AFTER(same_devnode, other, s) - if (other->from_fragment) - return UNIT(other); - - LIST_FOREACH_BEFORE(same_devnode, other, s) + LIST_FOREACH_OTHERS(same_devnode, other, s) if (other->from_fragment) return UNIT(other); @@ -1224,13 +1237,7 @@ static int swap_following_set(Unit *u, Set **_set) { if (!set) return -ENOMEM; - LIST_FOREACH_AFTER(same_devnode, other, s) { - r = set_put(set, other); - if (r < 0) - goto fail; - } - - LIST_FOREACH_BEFORE(same_devnode, other, s) { + LIST_FOREACH_OTHERS(same_devnode, other, s) { r = set_put(set, other); if (r < 0) goto fail;