From 99644a943ad66896a65ad971294a48439d433e78 Mon Sep 17 00:00:00 2001 From: Thomas Schoebel-Theuer Date: Wed, 25 Sep 2013 17:07:19 +0200 Subject: [PATCH] all: make *_switch() code idempotent New semantics: it must be possible to call the switch functions even when nothing has changed. --- kernel/mars_bio.c | 3 +++ kernel/mars_client.c | 4 ++++ kernel/mars_copy.c | 5 ++++ kernel/mars_dummy.c | 17 ++++++++++++-- kernel/mars_server.c | 8 +++++-- kernel/mars_sio.c | 48 +++++++++++++++++++++++--------------- kernel/mars_trans_logger.c | 1 + 7 files changed, 63 insertions(+), 23 deletions(-) diff --git a/kernel/mars_bio.c b/kernel/mars_bio.c index 657926b3..9468b7c3 100644 --- a/kernel/mars_bio.c +++ b/kernel/mars_bio.c @@ -668,6 +668,9 @@ static int bio_switch(struct bio_brick *brick) { int status = 0; if (brick->power.button) { + if (brick->power.led_on) + goto done; + mars_power_led_off((void*)brick, false); if (!brick->bdev) { diff --git a/kernel/mars_client.c b/kernel/mars_client.c index 2880e13e..c6766070 100644 --- a/kernel/mars_client.c +++ b/kernel/mars_client.c @@ -586,6 +586,8 @@ static int client_switch(struct client_brick *brick) int status = 0; if (brick->power.button) { + if (brick->power.led_on) + goto done; mars_power_led_off((void*)brick, false); if (!output->sender.thread) { brick->connection_state = 1; @@ -600,6 +602,8 @@ static int client_switch(struct client_brick *brick) mars_power_led_on((void*)brick, true); } } else { + if (brick->power.led_off) + goto done; mars_power_led_on((void*)brick, false); _kill_thread(&output->sender, "sender"); brick->connection_state = 0; diff --git a/kernel/mars_copy.c b/kernel/mars_copy.c index 6587fd55..bd1a0f42 100644 --- a/kernel/mars_copy.c +++ b/kernel/mars_copy.c @@ -791,6 +791,8 @@ static int copy_switch(struct copy_brick *brick) MARS_DBG("power.button = %d\n", brick->power.button); if (brick->power.button) { + if (brick->power.led_on) + goto done; mars_power_led_off((void*)brick, false); brick->is_aborting = false; if (!brick->thread) { @@ -804,6 +806,8 @@ static int copy_switch(struct copy_brick *brick) } } } else { + if (brick->power.led_off) + goto done; mars_power_led_on((void*)brick, false); if (brick->thread) { MARS_INF("stopping thread...\n"); @@ -811,6 +815,7 @@ static int copy_switch(struct copy_brick *brick) } } _update_percent(brick); +done: return 0; } diff --git a/kernel/mars_dummy.c b/kernel/mars_dummy.c index e1a6917a..a89c1cc1 100644 --- a/kernel/mars_dummy.c +++ b/kernel/mars_dummy.c @@ -53,14 +53,27 @@ static int dummy_switch(struct dummy_brick *brick) { if (brick->power.button) { + bool success = false; + if (brick->power.led_on) + goto done; mars_power_led_off((void*)brick, false); //... - mars_power_led_on((void*)brick, true); + success = true; + if (success) { + mars_power_led_on((void*)brick, true); + } } else { + bool success = false; + if (brick->power.led_off) + goto done; mars_power_led_on((void*)brick, false); //... - mars_power_led_off((void*)brick, true); + success = true; + if (success) { + mars_power_led_off((void*)brick, true); + } } +done: return 0; } diff --git a/kernel/mars_server.c b/kernel/mars_server.c index 3c66f547..71d713a8 100644 --- a/kernel/mars_server.c +++ b/kernel/mars_server.c @@ -487,8 +487,12 @@ static int server_switch(struct server_brick *brick) if (brick->power.button) { static int version = 0; - bool ok = mars_get_socket(sock); + bool ok; + if (brick->power.led_on) + goto err; + + ok = mars_get_socket(sock); if (unlikely(!ok)) { status = -ENOENT; goto err; @@ -513,7 +517,7 @@ static int server_switch(struct server_brick *brick) } mars_power_led_on((void*)brick, true); - } else if (brick->power.led_on) { + } else if (!brick->power.led_off) { struct task_struct *thread; mars_power_led_on((void*)brick, false); diff --git a/kernel/mars_sio.c b/kernel/mars_sio.c index 075995f8..0ff45ad9 100644 --- a/kernel/mars_sio.c +++ b/kernel/mars_sio.c @@ -568,32 +568,37 @@ static int sio_switch(struct sio_brick *brick) static int sio_nr = 0; struct sio_output *output = brick->outputs[0]; const char *path = output->brick->brick_path; - int flags = O_CREAT | O_RDWR | O_LARGEFILE; int prot = 0600; mm_segment_t oldfs; + int status = 0; - if (brick->o_direct) { - flags |= O_DIRECT; - MARS_INF("using O_DIRECT on %s\n", path); - } if (brick->power.button) { + int flags = O_CREAT | O_RDWR | O_LARGEFILE; struct address_space *mapping; int index; - mars_power_led_off((void*)brick, false); if (brick->power.led_on) goto done; + if (brick->o_direct) { + flags |= O_DIRECT; + MARS_INF("using O_DIRECT on %s\n", path); + } + + mars_power_led_off((void*)brick, false); + + // TODO: convert to mapfree infrastructure + oldfs = get_fs(); set_fs(get_ds()); output->filp = filp_open(path, flags, prot); set_fs(oldfs); if (unlikely(IS_ERR(output->filp))) { - int err = PTR_ERR(output->filp); - MARS_ERR("can't open file '%s' status=%d\n", path, err); + status = PTR_ERR(output->filp); + MARS_ERR("can't open file '%s' status=%d\n", path, status); output->filp = NULL; - return err; + goto done; } if ((mapping = output->filp->f_mapping)) { @@ -610,27 +615,32 @@ static int sio_switch(struct sio_brick *brick) tinfo->thread = brick_thread_create(sio_thread, tinfo, "mars_sio%d", sio_nr++); if (unlikely(!tinfo->thread)) { MARS_ERR("cannot create thread\n"); - return -ENOENT; + status = -ENOENT; + goto done; } } mars_power_led_on((void*)brick, true); - } else { + } +done: + if (unlikely(status < 0) || !brick->power.button) { + int index; mars_power_led_on((void*)brick, false); + for (index = 0; index <= WITH_THREAD; index++) { + struct sio_threadinfo *tinfo = &output->tinfo[index]; + if (!tinfo->thread) + continue; + MARS_DBG("stopping thread %d\n", index); + brick_thread_stop(tinfo->thread); + tinfo->thread = NULL; + } if (output->filp) { - int index; - for (index = 0; index <= WITH_THREAD; index++) { - struct sio_threadinfo *tinfo = &output->tinfo[index]; - MARS_DBG("stopping thread %d\n", index); - brick_thread_stop(tinfo->thread); - } MARS_DBG("closing file\n"); filp_close(output->filp, NULL); output->filp = NULL; } mars_power_led_off((void*)brick, true); } -done: - return 0; + return status; } static int sio_output_construct(struct sio_output *output) diff --git a/kernel/mars_trans_logger.c b/kernel/mars_trans_logger.c index 03b6e102..d08beeac 100644 --- a/kernel/mars_trans_logger.c +++ b/kernel/mars_trans_logger.c @@ -3026,6 +3026,7 @@ int trans_logger_switch(struct trans_logger_brick *brick) if (brick->thread) { MARS_INF("stopping thread...\n"); brick_thread_stop(brick->thread); + brick->thread = NULL; } } return 0;