Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

z2ram: use separate gendisk for the different modes

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>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
76487f02 6c3a05e1

+56 -40
+56 -40
drivers/block/z2ram.c
··· 63 63 64 64 static DEFINE_SPINLOCK(z2ram_lock); 65 65 66 - static struct gendisk *z2ram_gendisk; 66 + static struct gendisk *z2ram_gendisk[Z2MINOR_COUNT]; 67 67 68 68 static blk_status_t z2_queue_rq(struct blk_mq_hw_ctx *hctx, 69 69 const struct blk_mq_queue_data *bd) ··· 283 283 284 284 current_device = device; 285 285 z2ram_size <<= Z2RAM_CHUNKSHIFT; 286 - set_capacity(z2ram_gendisk, z2ram_size >> 9); 286 + set_capacity(z2ram_gendisk[device], z2ram_size >> 9); 287 287 } 288 288 289 289 mutex_unlock(&z2ram_mutex); ··· 315 315 .release = z2_release, 316 316 }; 317 317 318 - static struct kobject *z2_find(dev_t dev, int *part, void *data) 319 - { 320 - *part = 0; 321 - return get_disk_and_module(z2ram_gendisk); 322 - } 323 - 324 - static struct request_queue *z2_queue; 325 318 static struct blk_mq_tag_set tag_set; 326 319 327 320 static const struct blk_mq_ops z2_mq_ops = { 328 321 .queue_rq = z2_queue_rq, 329 322 }; 330 323 324 + static int z2ram_register_disk(int minor) 325 + { 326 + struct request_queue *q; 327 + struct gendisk *disk; 328 + 329 + disk = alloc_disk(1); 330 + if (!disk) 331 + return -ENOMEM; 332 + 333 + q = blk_mq_init_queue(&tag_set); 334 + if (IS_ERR(q)) { 335 + put_disk(disk); 336 + return PTR_ERR(q); 337 + } 338 + 339 + disk->major = Z2RAM_MAJOR; 340 + disk->first_minor = minor; 341 + disk->fops = &z2_fops; 342 + if (minor) 343 + sprintf(disk->disk_name, "z2ram%d", minor); 344 + else 345 + sprintf(disk->disk_name, "z2ram"); 346 + disk->queue = q; 347 + 348 + z2ram_gendisk[minor] = disk; 349 + add_disk(disk); 350 + return 0; 351 + } 352 + 331 353 static int __init z2_init(void) 332 354 { 333 - int ret; 355 + int ret, i; 334 356 335 357 if (!MACH_IS_AMIGA) 336 358 return -ENODEV; 337 359 338 - ret = -EBUSY; 339 360 if (register_blkdev(Z2RAM_MAJOR, DEVICE_NAME)) 340 - goto err; 361 + return -EBUSY; 341 362 342 - ret = -ENOMEM; 343 - z2ram_gendisk = alloc_disk(1); 344 - if (!z2ram_gendisk) 345 - goto out_disk; 363 + tag_set.ops = &z2_mq_ops; 364 + tag_set.nr_hw_queues = 1; 365 + tag_set.nr_maps = 1; 366 + tag_set.queue_depth = 16; 367 + tag_set.numa_node = NUMA_NO_NODE; 368 + tag_set.flags = BLK_MQ_F_SHOULD_MERGE; 369 + ret = blk_mq_alloc_tag_set(&tag_set); 370 + if (ret) 371 + goto out_unregister_blkdev; 346 372 347 - z2_queue = blk_mq_init_sq_queue(&tag_set, &z2_mq_ops, 16, 348 - BLK_MQ_F_SHOULD_MERGE); 349 - if (IS_ERR(z2_queue)) { 350 - ret = PTR_ERR(z2_queue); 351 - z2_queue = NULL; 352 - goto out_queue; 373 + for (i = 0; i < Z2MINOR_COUNT; i++) { 374 + ret = z2ram_register_disk(i); 375 + if (ret && i == 0) 376 + goto out_free_tagset; 353 377 } 354 - 355 - z2ram_gendisk->major = Z2RAM_MAJOR; 356 - z2ram_gendisk->first_minor = 0; 357 - z2ram_gendisk->fops = &z2_fops; 358 - sprintf(z2ram_gendisk->disk_name, "z2ram"); 359 - 360 - z2ram_gendisk->queue = z2_queue; 361 - add_disk(z2ram_gendisk); 362 - blk_register_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT, THIS_MODULE, 363 - z2_find, NULL, NULL); 364 378 365 379 return 0; 366 380 367 - out_queue: 368 - put_disk(z2ram_gendisk); 369 - out_disk: 381 + out_free_tagset: 382 + blk_mq_free_tag_set(&tag_set); 383 + out_unregister_blkdev: 370 384 unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); 371 - err: 372 385 return ret; 373 386 } 374 387 375 388 static void __exit z2_exit(void) 376 389 { 377 390 int i, j; 378 - blk_unregister_region(MKDEV(Z2RAM_MAJOR, 0), Z2MINOR_COUNT); 391 + 379 392 unregister_blkdev(Z2RAM_MAJOR, DEVICE_NAME); 380 - del_gendisk(z2ram_gendisk); 381 - put_disk(z2ram_gendisk); 382 - blk_cleanup_queue(z2_queue); 393 + 394 + for (i = 0; i < Z2MINOR_COUNT; i++) { 395 + del_gendisk(z2ram_gendisk[i]); 396 + blk_cleanup_queue(z2ram_gendisk[i]->queue); 397 + put_disk(z2ram_gendisk[i]); 398 + } 383 399 blk_mq_free_tag_set(&tag_set); 384 400 385 401 if (current_device != -1) {