[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(&params, 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.