/** * Write the physical details regarding the block device to the store, and * switch to Connected state. */ static void connect(struct backend_info *be) { xenbus_transaction_t xbt; int err; struct xenbus_device *dev = be->dev; DPRINTK("%s", dev->otherend); /* Supply the information about the device the frontend needs */ again: err = xenbus_transaction_start(&xbt); if (err) { xenbus_dev_fatal(dev, err, "starting transaction"); return; } err = xenbus_printf(xbt, dev->nodename, "sectors", "%lu", vbd_size(&be->blkif->vbd)); if (err) { xenbus_dev_fatal(dev, err, "writing %s/sectors", dev->nodename); goto abort; } /* FIXME: use a typename instead */ err = xenbus_printf(xbt, dev->nodename, "info", "%u", vbd_info(&be->blkif->vbd)); if (err) { xenbus_dev_fatal(dev, err, "writing %s/info", dev->nodename); goto abort; } err = xenbus_printf(xbt, dev->nodename, "sector-size", "%lu", vbd_secsize(&be->blkif->vbd)); if (err) { xenbus_dev_fatal(dev, err, "writing %s/sector-size", dev->nodename); goto abort; } err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) goto again; if (err) xenbus_dev_fatal(dev, err, "ending transaction"); err = xenbus_switch_state(dev, XenbusStateConnected); if (err) xenbus_dev_fatal(dev, err, "switching to Connected state", dev->nodename); return; abort: xenbus_transaction_end(xbt, 1); }
void vbd_resize(blkif_t *blkif) { struct vbd *vbd = &blkif->vbd; struct xenbus_transaction xbt; int err; struct xenbus_device *dev = blkback_xenbus(blkif->be); unsigned long long new_size = vbd_size(vbd); printk(KERN_INFO "VBD Resize: new size %Lu\n", new_size); vbd->size = new_size; again: err = xenbus_transaction_start(&xbt); if (err) { printk(KERN_WARNING "Error starting transaction"); return; } err = xenbus_printf(xbt, dev->nodename, "sectors", "%Lu", vbd_size(vbd)); if (err) { printk(KERN_WARNING "Error writing new size"); goto abort; } /* * Write the current state; we will use this to synchronize * the front-end. If the current state is "connected" the * front-end will get the new size information online. */ err = xenbus_printf(xbt, dev->nodename, "state", "%d", dev->state); if (err) { printk(KERN_WARNING "Error writing the state"); goto abort; } err = xenbus_transaction_end(xbt, 0); if (err == -EAGAIN) goto again; if (err) printk(KERN_WARNING "Error ending transaction"); abort: xenbus_transaction_end(xbt, 1); }
int vbd_create(blkif_t *blkif, blkif_vdev_t handle, unsigned major, unsigned minor, int readonly, int cdrom) { struct vbd *vbd; struct block_device *bdev; vbd = &blkif->vbd; vbd->handle = handle; vbd->readonly = readonly; vbd->type = 0; vbd->pdevice = MKDEV(major, minor); bdev = open_by_devnum(vbd->pdevice, vbd->readonly ? FMODE_READ : FMODE_WRITE); if (IS_ERR(bdev)) { DPRINTK("vbd_creat: device %08x could not be opened.\n", vbd->pdevice); return -ENOENT; } vbd->bdev = bdev; vbd->size = vbd_size(vbd); if (vbd->bdev->bd_disk == NULL) { DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice); vbd_free(vbd); return -ENOENT; } if (vbd->bdev->bd_disk->flags & GENHD_FL_CD || cdrom) vbd->type |= VDISK_CDROM; if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE) vbd->type |= VDISK_REMOVABLE; DPRINTK("Successful creation of handle=%04x (dom=%u)\n", handle, blkif->domid); return 0; }