From 4005bba43735bb8075aed6b78678562ee597c3f5 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Sun, 11 Dec 2011 22:36:19 +0100 Subject: [PATCH] libblockdriver: clear IPC only on stateful restart This removes a race condition when the block driver performs a complete restart after a crash (the new default). If any user of the driver finds out its new endpoint and sends a request to the new driver instance before this instance has had the chance to initialize, then its initialization would clear all IPC state and thereby erroneously cancel the incoming request. Clearing IPC state is only desired upon a stateful restart (where the driver's endpoint is retained). This information is now passed to and used by libblockdriver accordingly. --- common/include/minix/blockdriver.h | 2 +- drivers/ahci/ahci.c | 4 ++-- drivers/at_wini/at_wini.c | 4 ++-- drivers/bios_wini/bios_wini.c | 4 ++-- drivers/filter/main.c | 6 +++--- drivers/floppy/floppy.c | 4 ++-- lib/libblockdriver/driver.c | 11 +++++++---- 7 files changed, 19 insertions(+), 16 deletions(-) diff --git a/common/include/minix/blockdriver.h b/common/include/minix/blockdriver.h index ef0f00809..588e7e576 100644 --- a/common/include/minix/blockdriver.h +++ b/common/include/minix/blockdriver.h @@ -32,7 +32,7 @@ struct blockdriver { /* Functions defined by libblockdriver. These can be used for both * singlethreaded and multithreaded drivers. */ -_PROTOTYPE( void blockdriver_announce, (void) ); +_PROTOTYPE( void blockdriver_announce, (int type) ); #ifndef _BLOCKDRIVER_MT_API /* Additional functions for the singlethreaded version. These allow the driver diff --git a/drivers/ahci/ahci.c b/drivers/ahci/ahci.c index 75912841a..1f21aa341 100644 --- a/drivers/ahci/ahci.c +++ b/drivers/ahci/ahci.c @@ -2071,7 +2071,7 @@ PRIVATE void ahci_set_mapping(void) /*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the driver. */ @@ -2093,7 +2093,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) ahci_set_mapping(); /* Announce that we are up. */ - blockdriver_announce(); + blockdriver_announce(type); return OK; } diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index bc732207f..d03cafcbe 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -257,7 +257,7 @@ PRIVATE void sef_local_startup(void) /*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the at_wini driver. */ system_hz = sys_hz(); @@ -272,7 +272,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) init_params(); /* Announce we are up! */ - blockdriver_announce(); + blockdriver_announce(type); return(OK); } diff --git a/drivers/bios_wini/bios_wini.c b/drivers/bios_wini/bios_wini.c index 733fbe600..674e1728d 100644 --- a/drivers/bios_wini/bios_wini.c +++ b/drivers/bios_wini/bios_wini.c @@ -122,7 +122,7 @@ PRIVATE void sef_local_startup(void) /*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the bios_wini driver. */ long v; @@ -132,7 +132,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) remap_first = v; /* Announce we are up! */ - blockdriver_announce(); + blockdriver_announce(type); return(OK); } diff --git a/drivers/filter/main.c b/drivers/filter/main.c index a2a6a404d..602870a3b 100644 --- a/drivers/filter/main.c +++ b/drivers/filter/main.c @@ -443,9 +443,9 @@ PRIVATE void sef_local_startup(void) /*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { -/* Initialize the filter driver. */ + /* Initialize the filter driver. */ int r; r = parse_arguments(env_argc, env_argv); @@ -468,7 +468,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) } /* Announce we are up! */ - blockdriver_announce(); + blockdriver_announce(type); return(OK); } diff --git a/drivers/floppy/floppy.c b/drivers/floppy/floppy.c index 4a026741f..01c2bdacd 100644 --- a/drivers/floppy/floppy.c +++ b/drivers/floppy/floppy.c @@ -331,7 +331,7 @@ PRIVATE void sef_local_startup(void) /*===========================================================================* * sef_cb_init_fresh * *===========================================================================*/ -PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) +PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { /* Initialize the floppy driver. */ struct floppy *fp; @@ -363,7 +363,7 @@ PRIVATE int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) panic("Couldn't enable IRQs: %d", s); /* Announce we are up! */ - blockdriver_announce(); + blockdriver_announce(type); return(OK); } diff --git a/lib/libblockdriver/driver.c b/lib/libblockdriver/driver.c index d97b58542..b72223b27 100644 --- a/lib/libblockdriver/driver.c +++ b/lib/libblockdriver/driver.c @@ -92,7 +92,7 @@ PRIVATE void set_open_dev(int device) /*===========================================================================* * blockdriver_announce * *===========================================================================*/ -PUBLIC void blockdriver_announce(void) +PUBLIC void blockdriver_announce(int type) { /* Announce we are up after a fresh start or a restart. */ int r; @@ -102,12 +102,15 @@ PUBLIC void blockdriver_announce(void) /* Callers are allowed to use sendrec to communicate with drivers. * For this reason, there may blocked callers when a driver restarts. - * Ask the kernel to unblock them (if any). + * Ask the kernel to unblock them (if any). Note that most block drivers + * will not restart statefully, and thus will skip this code. */ + if (type == SEF_INIT_RESTART) { #if USE_STATECTL - if ((r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK) - panic("blockdriver_init: sys_statectl failed: %d", r); + if ((r = sys_statectl(SYS_STATE_CLEAR_IPC_REFS)) != OK) + panic("blockdriver_init: sys_statectl failed: %d", r); #endif + } /* Publish a driver up event. */ if ((r = ds_retrieve_label_name(label, getprocnr())) != OK)