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
|