lkml.org 
[lkml]   [2020]   [Aug]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 18/19] z2ram: use separate gendisk for the different modes
    Date
    Use separate gendisks (which share a tag_set) for the different operating
    modes instead of redirecting the gendisk lookup using a probe callback.
    This avoids potential problems with aliased block_device instances and
    will eventually allow for removing the blk_register_region framework.

    Signed-off-by: Christoph Hellwig <hch@lst.de>
    ---
    drivers/block/z2ram.c | 100 ++++++++++++++++++++++++------------------
    1 file changed, 58 insertions(+), 42 deletions(-)

    diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c
    index 566c653399d8d3..2bf059ba95603c 100644
    --- a/drivers/block/z2ram.c
    +++ b/drivers/block/z2ram.c
    @@ -63,7 +63,7 @@ static int current_device = -1;

    static DEFINE_SPINLOCK(z2ram_lock);

    -static struct gendisk *z2ram_gendisk;
    +static struct gendisk *z2ram_gendisk[Z2MINOR_COUNT];

    static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx *hctx,
    const struct blk_mq_queue_data *bd)
    @@ -281,7 +281,7 @@ static int z2_open(struct block_device *bdev, fmode_t mode)

    current_device = device;
    z2ram_size <<= Z2RAM_CHUNKSHIFT;
    - set_capacity(z2ram_gendisk, z2ram_size >> 9);
    + set_capacity(z2ram_gendisk[device], z2ram_size >> 9);
    }

    mutex_unlock(&z2ram_mutex);
    @@ -313,71 +313,87 @@ static const struct block_device_operations z2_fops = {
    .release = z2_release,
    };

    -static struct kobject *z2_find(dev_t dev, int *part, void *data)
    -{
    - *part = 0;
    - return get_disk_and_module(z2ram_gendisk);
    -}
    -
    -static struct request_queue *z2_queue;
    static struct blk_mq_tag_set tag_set;

    static const struct blk_mq_ops z2_mq_ops = {
    .queue_rq = z2_queue_rq,
    };

    +static int z2ram_register_disk(int minor)
    +{
    + struct request_queue *q;
    + struct gendisk *disk;
    +
    + disk = alloc_disk(1);
    + if (!disk)
    + return -ENOMEM;
    +
    + q = blk_mq_init_queue(&tag_set);
    + if (IS_ERR(q)) {
    + put_disk(disk);
    + return PTR_ERR(q);
    + }
    +
    + disk->major = Z2RAM_MAJOR;
    + disk->first_minor = minor;
    + disk->fops = &z2_fops;
    + if (minor)
    + sprintf(disk->disk_name, "z2ram%d", minor);
    + else
    + sprintf(disk->disk_name, "z2ram");
    + disk->queue = q;
    +
    + z2ram_gendisk[minor] = disk;
    + add_disk(disk);
    + return 0;
    +}
    +
    static int __init z2_init(void)
    {
    - int ret;
    + int ret, i;

    if (!MACH_IS_AMIGA)
    return -ENODEV;

    - ret = -EBUSY;
    if (register_blkdev(Z2RAM_MAJOR, DEVICE_NAME))
    - goto err;
    -
    - ret = -ENOMEM;
    - z2ram_gendisk = alloc_disk(1);
    - if (!z2ram_gendisk)
    - goto out_disk;
    -
    - z2_queue = blk_mq_init_sq_queue(&tag_set, &z2_mq_ops, 16,
    - BLK_MQ_F_SHOULD_MERGE);
    - if (IS_ERR(z2_queue)) {
    - ret = PTR_ERR(z2_queue);
    - z2_queue = NULL;
    - goto out_queue;
    + return -EBUSY;
    +
    + tag_set.ops = &z2_mq_ops;
    + tag_set.nr_hw_queues = 1;
    + tag_set.nr_maps = 1;
    + tag_set.queue_depth = 16;
    + tag_set.numa_node = NUMA_NO_NODE;
    + tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
    + ret = blk_mq_alloc_tag_set(&tag_set);
    + if (ret)
    + goto out_unregister_blkdev;
    +
    + for (i = 0; i < Z2MINOR_COUNT; i++) {
    + ret = z2ram_register_disk(i);
    + if (ret && i == 0)
    + goto out_free_tagset;
    }

    - z2ram_gendisk->major = Z2RAM_MAJOR;
    - z2ram_gendisk->first_minor = 0;
    - z2ram_gendisk->fops = &z2_fops;
    - sprintf(z2ram_gendisk->disk_name, "z2ram");
    -
    - z2ram_gendisk->queue = z2_queue;
    - add_disk(z2ram_gendisk);
    - blk_register_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT, THIS_MODULE,
    - z2_find, NULL, NULL);
    -
    return 0;

    -out_queue:
    - put_disk(z2ram_gendisk);
    -out_disk:
    +out_free_tagset:
    + blk_mq_free_tag_set(&tag_set);
    +out_unregister_blkdev:
    unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME);
    -err:
    return ret;
    }

    static void __exit z2_exit(void)
    {
    int i, j;
    - blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT);
    +
    unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME);
    - del_gendisk(z2ram_gendisk);
    - put_disk(z2ram_gendisk);
    - blk_cleanup_queue(z2_queue);
    +
    + for (i = 0; i < Z2MINOR_COUNT; i++) {
    + del_gendisk(z2ram_gendisk[i]);
    + blk_cleanup_queue(z2ram_gendisk[i]->queue);
    + put_disk(z2ram_gendisk[i]);
    + }
    blk_mq_free_tag_set(&tag_set);

    if (current_device != -1) {
    --
    2.28.0
    \
     
     \ /
      Last update: 2020-08-26 09:03    [W:2.375 / U:0.496 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site