Merge remote-tracking branch 'sstabellini/xen-2013-04-05' into staging

# By Alex Bligh (2) and Felipe Franciosi (2)
# Via Stefano Stabellini
* sstabellini/xen-2013-04-05:
  Allow xen guests to plug disks of 1 TiB or more
  Introduce 64 bit integer write interface to xenstore
  Xen PV backend: Disable use of O_DIRECT by default as it results in crashes.
  Xen PV backend: Move call to bdrv_new from blk_init to blk_connect
This commit is contained in:
Anthony Liguori 2013-04-05 12:52:32 -05:00
commit 54baa6f3c0
3 changed files with 70 additions and 47 deletions

View File

@ -85,12 +85,20 @@ char *xenstore_read_str(const char *base, const char *node)
int xenstore_write_int(const char *base, const char *node, int ival)
{
char val[32];
char val[12];
snprintf(val, sizeof(val), "%d", ival);
return xenstore_write_str(base, node, val);
}
int xenstore_write_int64(const char *base, const char *node, int64_t ival)
{
char val[21];
snprintf(val, sizeof(val), "%"PRId64, ival);
return xenstore_write_str(base, node, val);
}
int xenstore_read_int(const char *base, const char *node, int *ival)
{
char *val;
@ -114,6 +122,11 @@ int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival)
return xenstore_write_int(xendev->be, node, ival);
}
int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival)
{
return xenstore_write_int64(xendev->be, node, ival);
}
char *xenstore_read_be_str(struct XenDevice *xendev, const char *node)
{
return xenstore_read_str(xendev->be, node);

View File

@ -63,11 +63,13 @@ extern const char *xen_protocol;
/* xenstore helper functions */
int xenstore_write_str(const char *base, const char *node, const char *val);
int xenstore_write_int(const char *base, const char *node, int ival);
int xenstore_write_int64(const char *base, const char *node, int64_t ival);
char *xenstore_read_str(const char *base, const char *node);
int xenstore_read_int(const char *base, const char *node, int *ival);
int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val);
int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival);
int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival);
char *xenstore_read_be_str(struct XenDevice *xendev, const char *node);
int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival);
char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node);

View File

@ -700,7 +700,7 @@ static void blk_alloc(struct XenDevice *xendev)
static int blk_init(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
int index, qflags, info = 0;
int info = 0;
/* read xenstore entries */
if (blkdev->params == NULL) {
@ -743,10 +743,7 @@ static int blk_init(struct XenDevice *xendev)
}
/* read-only ? */
qflags = BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO;
if (strcmp(blkdev->mode, "w") == 0) {
qflags |= BDRV_O_RDWR;
} else {
if (strcmp(blkdev->mode, "w")) {
info |= VDISK_READONLY;
}
@ -755,50 +752,14 @@ static int blk_init(struct XenDevice *xendev)
info |= VDISK_CDROM;
}
/* init qemu block driver */
index = (blkdev->xendev.dev - 202 * 256) / 16;
blkdev->dinfo = drive_get(IF_XEN, 0, index);
if (!blkdev->dinfo) {
/* setup via xenbus -> create new block driver instance */
xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
blkdev->bs = bdrv_new(blkdev->dev);
if (blkdev->bs) {
if (bdrv_open(blkdev->bs, blkdev->filename, NULL, qflags,
bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) {
bdrv_delete(blkdev->bs);
blkdev->bs = NULL;
}
}
if (!blkdev->bs) {
goto out_error;
}
} else {
/* setup via qemu cmdline -> already setup for us */
xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
blkdev->bs = blkdev->dinfo->bdrv;
}
bdrv_attach_dev_nofail(blkdev->bs, blkdev);
blkdev->file_blk = BLOCK_SIZE;
blkdev->file_size = bdrv_getlength(blkdev->bs);
if (blkdev->file_size < 0) {
xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
(int)blkdev->file_size, strerror(-blkdev->file_size),
bdrv_get_format_name(blkdev->bs) ?: "-");
blkdev->file_size = 0;
}
xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
" size %" PRId64 " (%" PRId64 " MB)\n",
blkdev->type, blkdev->fileproto, blkdev->filename,
blkdev->file_size, blkdev->file_size >> 20);
/* fill info */
/* fill info
* blk_connect supplies sector-size and sectors
*/
xenstore_write_be_int(&blkdev->xendev, "feature-flush-cache", 1);
xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
xenstore_write_be_int(&blkdev->xendev, "info", info);
xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk);
xenstore_write_be_int(&blkdev->xendev, "sectors",
blkdev->file_size / blkdev->file_blk);
xenstore_write_be_int(&blkdev->xendev, "info", info);
return 0;
out_error:
@ -818,7 +779,54 @@ out_error:
static int blk_connect(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
int pers;
int pers, index, qflags;
/* read-only ? */
qflags = BDRV_O_CACHE_WB | BDRV_O_NATIVE_AIO;
if (strcmp(blkdev->mode, "w") == 0) {
qflags |= BDRV_O_RDWR;
}
/* init qemu block driver */
index = (blkdev->xendev.dev - 202 * 256) / 16;
blkdev->dinfo = drive_get(IF_XEN, 0, index);
if (!blkdev->dinfo) {
/* setup via xenbus -> create new block driver instance */
xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
blkdev->bs = bdrv_new(blkdev->dev);
if (blkdev->bs) {
if (bdrv_open(blkdev->bs, blkdev->filename, NULL, qflags,
bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) {
bdrv_delete(blkdev->bs);
blkdev->bs = NULL;
}
}
if (!blkdev->bs) {
return -1;
}
} else {
/* setup via qemu cmdline -> already setup for us */
xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n");
blkdev->bs = blkdev->dinfo->bdrv;
}
bdrv_attach_dev_nofail(blkdev->bs, blkdev);
blkdev->file_size = bdrv_getlength(blkdev->bs);
if (blkdev->file_size < 0) {
xen_be_printf(&blkdev->xendev, 1, "bdrv_getlength: %d (%s) | drv %s\n",
(int)blkdev->file_size, strerror(-blkdev->file_size),
bdrv_get_format_name(blkdev->bs) ?: "-");
blkdev->file_size = 0;
}
xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
" size %" PRId64 " (%" PRId64 " MB)\n",
blkdev->type, blkdev->fileproto, blkdev->filename,
blkdev->file_size, blkdev->file_size >> 20);
/* Fill in number of sector size and number of sectors */
xenstore_write_be_int(&blkdev->xendev, "sector-size", blkdev->file_blk);
xenstore_write_be_int64(&blkdev->xendev, "sectors",
blkdev->file_size / blkdev->file_blk);
if (xenstore_read_fe_int(&blkdev->xendev, "ring-ref", &blkdev->ring_ref) == -1) {
return -1;