block, xen/blkback: remove blk_[get|put]_queue calls.
[firefly-linux-kernel-4.4.55.git] / drivers / xen / blkback / xenbus.c
index 80d9aa6e6ba36bea2905e28d171ed6ed88f382cb..b41ed65db2d316ed892b1d7ea7f2198d48233b6c 100644 (file)
 #undef DPRINTK
 #define DPRINTK(fmt, args...)                          \
        pr_debug("blkback/xenbus (%s:%d) " fmt ".\n",   \
-                __FUNCTION__, __LINE__, ##args)
+                __func__, __LINE__, ##args)
 
-struct backend_info
-{
+struct backend_info {
        struct xenbus_device *dev;
-       blkif_t *blkif;
+       struct blkif_st *blkif;
        struct xenbus_watch backend_watch;
        unsigned major;
        unsigned minor;
@@ -42,7 +41,12 @@ static int connect_ring(struct backend_info *);
 static void backend_changed(struct xenbus_watch *, const char **,
                            unsigned int);
 
-static int blkback_name(blkif_t *blkif, char *buf)
+struct xenbus_device *blkback_xenbus(struct backend_info *be)
+{
+       return be->dev;
+}
+
+static int blkback_name(struct blkif_st *blkif, char *buf)
 {
        char *devpath, *devname;
        struct xenbus_device *dev = blkif->be->dev;
@@ -51,7 +55,8 @@ static int blkback_name(blkif_t *blkif, char *buf)
        if (IS_ERR(devpath))
                return PTR_ERR(devpath);
 
-       if ((devname = strstr(devpath, "/dev/")) != NULL)
+       devname = strstr(devpath, "/dev/");
+       if (devname != NULL)
                devname += strlen("/dev/");
        else
                devname  = devpath;
@@ -62,7 +67,7 @@ static int blkback_name(blkif_t *blkif, char *buf)
        return 0;
 }
 
-static void update_blkif_status(blkif_t *blkif)
+static void update_blkif_status(struct blkif_st *blkif)
 {
        int err;
        char name[TASK_COMM_LEN];
@@ -86,6 +91,13 @@ static void update_blkif_status(blkif_t *blkif)
                return;
        }
 
+       err = filemap_write_and_wait(blkif->vbd.bdev->bd_inode->i_mapping);
+       if (err) {
+               xenbus_dev_error(blkif->be->dev, err, "block flush");
+               return;
+       }
+       invalidate_inode_pages2(blkif->vbd.bdev->bd_inode->i_mapping);
+
        blkif->xenblkd = kthread_run(blkif_schedule, blkif, name);
        if (IS_ERR(blkif->xenblkd)) {
                err = PTR_ERR(blkif->xenblkd);
@@ -95,7 +107,7 @@ static void update_blkif_status(blkif_t *blkif)
 }
 
 
-/****************************************************************
+/*
  *  sysfs interface for VBD I/O requests
  */
 
@@ -105,7 +117,7 @@ static void update_blkif_status(blkif_t *blkif)
                                   char *buf)                           \
        {                                                               \
                struct xenbus_device *dev = to_xenbus_device(_dev);     \
-               struct backend_info *be = dev->dev.driver_data;         \
+               struct backend_info *be = dev_get_drvdata(&dev->dev);   \
                                                                        \
                return sprintf(buf, format, ##args);                    \
        }                                                               \
@@ -141,7 +153,7 @@ int xenvbd_sysfs_addif(struct xenbus_device *dev)
        int error;
 
        error = device_create_file(&dev->dev, &dev_attr_physical_device);
-       if (error)
+       if (error)
                goto fail1;
 
        error = device_create_file(&dev->dev, &dev_attr_mode);
@@ -169,7 +181,7 @@ void xenvbd_sysfs_delif(struct xenbus_device *dev)
 
 static int blkback_remove(struct xenbus_device *dev)
 {
-       struct backend_info *be = dev->dev.driver_data;
+       struct backend_info *be = dev_get_drvdata(&dev->dev);
 
        DPRINTK("");
 
@@ -190,7 +202,7 @@ static int blkback_remove(struct xenbus_device *dev)
        }
 
        kfree(be);
-       dev->dev.driver_data = NULL;
+       dev_set_drvdata(&dev->dev, NULL);
        return 0;
 }
 
@@ -225,7 +237,7 @@ static int blkback_probe(struct xenbus_device *dev,
                return -ENOMEM;
        }
        be->dev = dev;
-       dev->dev.driver_data = be;
+       dev_set_drvdata(&dev->dev, be);
 
        be->blkif = blkif_alloc(dev->otherend_id);
        if (IS_ERR(be->blkif)) {
@@ -238,8 +250,8 @@ static int blkback_probe(struct xenbus_device *dev,
        /* setup back pointer */
        be->blkif->be = be;
 
-       err = xenbus_watch_path2(dev, dev->nodename, "physical-device",
-                                &be->backend_watch, backend_changed);
+       err = xenbus_watch_pathfmt(dev, &be->backend_watch, backend_changed,
+                                  "%s/%s", dev->nodename, "physical-device");
        if (err)
                goto fail;
 
@@ -315,7 +327,10 @@ static void backend_changed(struct xenbus_watch *watch,
                /* Front end dir is a number, which is used as the handle. */
 
                char *p = strrchr(dev->otherend, '/') + 1;
-               long handle = simple_strtoul(p, NULL, 0);
+               long handle;
+               err = strict_strtoul(p, 0, &handle);
+               if (err)
+                       return;
 
                be->major = major;
                be->minor = minor;
@@ -348,7 +363,7 @@ static void backend_changed(struct xenbus_watch *watch,
 static void frontend_changed(struct xenbus_device *dev,
                             enum xenbus_state frontend_state)
 {
-       struct backend_info *be = dev->dev.driver_data;
+       struct backend_info *be = dev_get_drvdata(&dev->dev);
        int err;
 
        DPRINTK("%s", xenbus_strstate(frontend_state));
@@ -357,7 +372,7 @@ static void frontend_changed(struct xenbus_device *dev,
        case XenbusStateInitialising:
                if (dev->state == XenbusStateClosed) {
                        printk(KERN_INFO "%s: %s: prepare for reconnect\n",
-                              __FUNCTION__, dev->nodename);
+                              __func__, dev->nodename);
                        xenbus_switch_state(dev, XenbusStateInitWait);
                }
                break;
@@ -370,6 +385,11 @@ static void frontend_changed(struct xenbus_device *dev,
                if (dev->state == XenbusStateConnected)
                        break;
 
+               /* Enforce precondition before potential leak point.
+                * blkif_disconnect() is idempotent.
+                */
+               blkif_disconnect(be->blkif);
+
                err = connect_ring(be);
                if (err)
                        break;
@@ -387,6 +407,7 @@ static void frontend_changed(struct xenbus_device *dev,
                        break;
                /* fall through if not online */
        case XenbusStateUnknown:
+               /* implies blkif_disconnect() via blkback_remove() */
                device_unregister(&dev->dev);
                break;
 
@@ -476,8 +497,8 @@ static int connect_ring(struct backend_info *be)
 
        DPRINTK("%s", dev->otherend);
 
-       err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu", &ring_ref,
-                           "event-channel", "%u", &evtchn, NULL);
+       err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu",
+                           &ring_ref, "event-channel", "%u", &evtchn, NULL);
        if (err) {
                xenbus_dev_fatal(dev, err,
                                 "reading %s/ring-ref and event-channel",
@@ -535,7 +556,7 @@ static struct xenbus_driver blkback = {
 };
 
 
-void blkif_xenbus_init(void)
+int blkif_xenbus_init(void)
 {
-       xenbus_register_backend(&blkback);
+       return xenbus_register_backend(&blkback);
 }