From: t_jeang Date: Tue, 6 Jan 2009 12:06:01 +0000 (+0000) Subject: imported patch CA-14804-fix-block-unplug-retries X-Git-Tag: blk-fix-sysfs-remove-race X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=5d9a2dea49fa353e551bf7b35e5cb7a6107bc258;p=xenclient%2Fkernel.git imported patch CA-14804-fix-block-unplug-retries --- diff --git a/drivers/xen/blkback/xenbus.c b/drivers/xen/blkback/xenbus.c index c48456d8..dfb54521 100644 --- a/drivers/xen/blkback/xenbus.c +++ b/drivers/xen/blkback/xenbus.c @@ -310,6 +310,30 @@ void blkback_close(blkif_t *blkif) blkif->xenblkd = NULL; } +static int xenbus_write_state(struct xenbus_device *dev, + enum xenbus_state state) +{ + int err; + int current_state; + + if (dev->state != state) + return xenbus_switch_state(dev, state); + + err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d", + ¤t_state); + if (err != 1) + return 0; + + err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state); + if (err) { + if (state != XenbusStateClosing) /* Avoid looping */ + xenbus_dev_fatal(dev, err, "writing new state"); + return err; + } + + return 0; +} + static void start_shutdown(struct xenbus_watch *watch, const char **vec, unsigned int length) { @@ -334,7 +358,7 @@ static void start_shutdown(struct xenbus_watch *watch, return; } - xenbus_switch_state(dev, XenbusStateClosing); + xenbus_write_state(dev, XenbusStateClosing); if (len == sizeof("force") - 1 && !memcmp(type, "force", len)) if (!kthread_remove(be)) diff --git a/drivers/xen/blktap/xenbus.c b/drivers/xen/blktap/xenbus.c index 1150dfd3..9bf32164 100644 --- a/drivers/xen/blktap/xenbus.c +++ b/drivers/xen/blktap/xenbus.c @@ -353,6 +353,30 @@ void blktap_close(blkif_t *blkif) blkif->xenblkd = NULL; } +static int xenbus_write_state(struct xenbus_device *dev, + enum xenbus_state state) +{ + int err; + int current_state; + + if (dev->state != state) + return xenbus_switch_state(dev, state); + + err = xenbus_scanf(XBT_NIL, dev->nodename, "state", "%d", + ¤t_state); + if (err != 1) + return 0; + + err = xenbus_printf(XBT_NIL, dev->nodename, "state", "%d", state); + if (err) { + if (state != XenbusStateClosing) /* Avoid looping */ + xenbus_dev_fatal(dev, err, "writing new state"); + return err; + } + + return 0; +} + static void start_shutdown(struct xenbus_watch *watch, const char **vec, unsigned int length) { @@ -377,7 +401,7 @@ static void start_shutdown(struct xenbus_watch *watch, return; } - xenbus_switch_state(dev, XenbusStateClosing); + xenbus_write_state(dev, XenbusStateClosing); if (len == sizeof("force") - 1 && !memcmp(type, "force", len)) if (!kthread_remove(be))