#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;
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;
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;
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];
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);
}
-/****************************************************************
+/*
* sysfs interface for VBD I/O requests
*/
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); \
} \
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);
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("");
}
kfree(be);
- dev->dev.driver_data = NULL;
+ dev_set_drvdata(&dev->dev, NULL);
return 0;
}
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)) {
/* 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;
/* 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;
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));
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;
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;
break;
/* fall through if not online */
case XenbusStateUnknown:
+ /* implies blkif_disconnect() via blkback_remove() */
device_unregister(&dev->dev);
break;
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",
};
-void blkif_xenbus_init(void)
+int blkif_xenbus_init(void)
{
- xenbus_register_backend(&blkback);
+ return xenbus_register_backend(&blkback);
}