[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 02/10] blktap: Upgrade CREATE_DEVICE ioctl.
Alternative for the blktap2_params-compatible call. * drops the image name parameter. * flags: adds support for disk R/O-mode, and later extensions. Bumps up the relevant ioctl nr, for new tapdisk sources. The old slot remains supported through translation. Note that set_disk_ro might sleep, so just drop a gratuitous spinlock. Signed-off-by: Daniel Stodden <daniel.stodden@xxxxxxxxxx> --- drivers/xen/blktap/device.c | 55 ++++++++++++++++-------------------------- drivers/xen/blktap/ring.c | 48 ++++++++++++++++++++++++++++++++++--- include/linux/blktap.h | 18 ++++++++++---- 3 files changed, 78 insertions(+), 43 deletions(-) diff --git a/drivers/xen/blktap/device.c b/drivers/xen/blktap/device.c index 6bb04bd..9a09457 100644 --- a/drivers/xen/blktap/device.c +++ b/drivers/xen/blktap/device.c @@ -276,20 +276,17 @@ blktap_device_do_request(struct request_queue *rq) static void blktap_device_configure(struct blktap *tap, - struct blktap_device_info *params) + struct blktap_device_info *info) { - struct request_queue *rq; - struct blktap_device *dev = &tap->device; - - dev = &tap->device; - rq = dev->gd->queue; - - spin_lock_irq(&dev->lock); + struct blktap_device *tapdev = &tap->device; + struct gendisk *gd = tapdev->gd; + struct request_queue *rq = gd->queue; - set_capacity(dev->gd, params->capacity); + set_capacity(gd, info->capacity); + set_disk_ro(gd, !!(info->flags & BLKTAP_DEVICE_FLAG_RO)); /* Hard sector size and max sectors impersonate the equiv. hardware. */ - blk_queue_logical_block_size(rq, params->sector_size); + blk_queue_logical_block_size(rq, info->sector_size); blk_queue_max_sectors(rq, 512); /* Each segment in a request is up to an aligned page in size. */ @@ -305,38 +302,30 @@ blktap_device_configure(struct blktap *tap, /* We are reordering, but cacheless. */ blk_queue_ordered(rq, QUEUE_ORDERED_DRAIN, NULL); - - spin_unlock_irq(&dev->lock); } static int -blktap_device_validate_params(struct blktap *tap, - struct blktap_device_info *params) +blktap_device_validate_info(struct blktap *tap, + struct blktap_device_info *info) { struct device *dev = tap->ring.dev; - int sector_order, name_sz; - - sector_order = ffs(params->sector_size) - 1; + int sector_order; + sector_order = ffs(info->sector_size) - 1; if (sector_order < 9 || sector_order > 12 || - params->sector_size != 1U<<sector_order) - goto fail; - - if (!params->capacity || - (params->capacity > ULLONG_MAX >> sector_order)) + info->sector_size != 1U<<sector_order) goto fail; - name_sz = min(sizeof(params->name), sizeof(tap->name)); - if (strnlen(params->name, name_sz) >= name_sz) + if (!info->capacity || + (info->capacity > ULLONG_MAX >> sector_order)) goto fail; return 0; fail: - params->name[name_sz-1] = 0; - dev_err(dev, "capacity: %llu, sector-size: %lu, name: %s\n", - params->capacity, params->sector_size, params->name); + dev_err(dev, "capacity: %llu, sector-size: %u\n", + info->capacity, info->sector_size); return -EINVAL; } @@ -425,7 +414,7 @@ blktap_device_destroy_sync(struct blktap *tap) } int -blktap_device_create(struct blktap *tap, struct blktap_device_info *params) +blktap_device_create(struct blktap *tap, struct blktap_device_info *info) { int minor, err; struct gendisk *gd; @@ -440,7 +429,7 @@ blktap_device_create(struct blktap *tap, struct blktap_device_info *params) if (test_bit(BLKTAP_DEVICE, &tap->dev_inuse)) return -EEXIST; - if (blktap_device_validate_params(tap, params)) + if (blktap_device_validate_info(tap, info)) return -EINVAL; gd = alloc_disk(1); @@ -479,16 +468,14 @@ blktap_device_create(struct blktap *tap, struct blktap_device_info *params) rq->queuedata = tapdev; tapdev->gd = gd; - blktap_device_configure(tap, params); + blktap_device_configure(tap, info); add_disk(gd); - if (params->name[0]) - strncpy(tap->name, params->name, sizeof(tap->name)-1); - set_bit(BLKTAP_DEVICE, &tap->dev_inuse); - dev_info(disk_to_dev(gd), "sector-size: %u capacity: %llu\n", + dev_info(disk_to_dev(gd), "sector-size: %u/%u capacity: %llu\n", queue_logical_block_size(rq), + queue_physical_block_size(rq), (unsigned long long)get_capacity(gd)); return 0; diff --git a/drivers/xen/blktap/ring.c b/drivers/xen/blktap/ring.c index 9442a64..635f1fd 100644 --- a/drivers/xen/blktap/ring.c +++ b/drivers/xen/blktap/ring.c @@ -16,6 +16,10 @@ static struct cdev blktap_ring_cdev; */ #define RING_PAGES 1 +#define BLKTAP_INFO_SIZE_AT(_memb) \ + offsetof(struct blktap_device_info, _memb) + \ + sizeof(((struct blktap_device_info*)0)->_memb) + static void blktap_ring_read_response(struct blktap *tap, const blktap_ring_rsp_t *rsp) @@ -382,6 +386,8 @@ blktap_ring_ioctl(struct inode *inode, struct file *filp, { struct blktap *tap = filp->private_data; struct blktap_ring *ring = &tap->ring; + void __user *ptr = (void *)arg; + int err; BTDBG("%d: cmd: %u, arg: %lu\n", tap->minor, cmd, arg); @@ -394,14 +400,48 @@ blktap_ring_ioctl(struct inode *inode, struct file *filp, blktap_read_ring(tap); return 0; + case BLKTAP_IOCTL_CREATE_DEVICE_COMPAT: { + struct blktap_device_info info; + struct blktap2_params params; + + if (copy_from_user(¶ms, ptr, sizeof(params))) + return -EFAULT; + + info.capacity = params.capacity; + info.sector_size = params.sector_size; + info.flags = 0; + + err = blktap_device_create(tap, &info); + if (err) + return err; + + if (params.name[0]) { + strncpy(tap->name, params.name, sizeof(params.name)); + tap->name[sizeof(tap->name)-1] = 0; + } + + return 0; + } + case BLKTAP_IOCTL_CREATE_DEVICE: { + struct blktap_device_info __user *ptr = (void *)arg; struct blktap_device_info info; - void __user *ptr = (void *)arg; + unsigned long mask; + size_t base_sz, sz; + + mask = BLKTAP_DEVICE_FLAG_RO; + + memset(&info, 0, sizeof(info)); + sz = base_sz = BLKTAP_INFO_SIZE_AT(flags); + + if (copy_from_user(&info, ptr, sz)) + return -EFAULT; - if (!arg) - return -EINVAL; + if (sz > base_sz) + if (copy_from_user(&info, ptr, sz)) + return -EFAULT; - if (copy_from_user(&info, ptr, sizeof(info))) + if (put_user(info.flags & mask, &ptr->flags)) return -EFAULT; return blktap_device_create(tap, &info); diff --git a/include/linux/blktap.h b/include/linux/blktap.h index ec33429..2c3c924 100644 --- a/include/linux/blktap.h +++ b/include/linux/blktap.h @@ -13,10 +13,10 @@ #define BLKTAP_IOCTL_RESPOND 1 #define BLKTAP_IOCTL_ALLOC_TAP 200 #define BLKTAP_IOCTL_FREE_TAP 201 -#define BLKTAP_IOCTL_CREATE_DEVICE 202 +#define BLKTAP_IOCTL_CREATE_DEVICE 208 #define BLKTAP_IOCTL_REMOVE_DEVICE 207 -#define BLKTAP_NAME_MAX 256 +#define BLKTAP_DEVICE_FLAG_RO 0x00000001UL /* disk is R/O */ struct blktap_info { unsigned int ring_major; @@ -25,9 +25,9 @@ struct blktap_info { }; struct blktap_device_info { - char name[BLKTAP_NAME_MAX]; unsigned long long capacity; - unsigned long sector_size; + unsigned int sector_size; + unsigned long flags; }; /* @@ -77,9 +77,17 @@ DEFINE_RING_TYPES(blktap, struct blktap_ring_request, struct blktap_ring_respons #define BLKTAP_RING_SIZE __CONST_RING_SIZE(blktap, BLKTAP_PAGE_SIZE) /* - * Ring messages (DEPRECATED) + * Ring messages + old ioctls (DEPRECATED) */ #define BLKTAP_RING_MESSAGE_CLOSE 3 +#define BLKTAP_IOCTL_CREATE_DEVICE_COMPAT 202 +#define BLKTAP_NAME_MAX 256 + +struct blktap2_params { + char name[BLKTAP_NAME_MAX]; + unsigned long long capacity; + unsigned long sector_size; +}; #endif /* _LINUX_BLKTAP_H */ -- 1.7.0.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |