]> xenbits.xensource.com Git - xenclient/kernel.git/commitdiff
imported patch CA-14804-fix-block-unplug-retries blk-fix-sysfs-remove-race
authort_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:06:01 +0000 (12:06 +0000)
committert_jeang <devnull@localhost>
Tue, 6 Jan 2009 12:06:01 +0000 (12:06 +0000)
drivers/xen/blkback/xenbus.c
drivers/xen/blktap/xenbus.c

index c48456d822c5b9ab5c6cb4a0f6c86e2718db2dab..dfb54521c02d344462a54d1b13ab1f62affa8d47 100644 (file)
@@ -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",
+                          &current_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))
index 1150dfd3f7fb54da83d0dfef371fcce505384e2c..9bf321647ddbd5ab341fcd4379fff3518a6ebaff 100644 (file)
@@ -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",
+                          &current_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))