Skip to content

Commit

Permalink
Merge tag 'for-5.16/drivers-2021-11-09' of git://git.kernel.dk/linux-…
Browse files Browse the repository at this point in the history
…block

Pull more block driver updates from Jens Axboe:

 - Last series adding error handling support for add_disk() in drivers.
   After this one, and once the SCSI side has been merged, we can
   finally annotate add_disk() as must_check. (Luis)

 - bcache fixes (Coly)

 - zram fixes (Ming)

 - ataflop locking fix (Tetsuo)

 - nbd fixes (Ye, Yu)

 - MD merge via Song
      - Cleanup (Yang)
      - sysfs fix (Guoqing)

 - Misc fixes (Geert, Wu, luo)

* tag 'for-5.16/drivers-2021-11-09' of git://git.kernel.dk/linux-block: (34 commits)
  bcache: Revert "bcache: use bvec_virt"
  ataflop: Add missing semicolon to return statement
  floppy: address add_disk() error handling on probe
  ataflop: address add_disk() error handling on probe
  block: update __register_blkdev() probe documentation
  ataflop: remove ataflop_probe_lock mutex
  mtd/ubi/block: add error handling support for add_disk()
  block/sunvdc: add error handling support for add_disk()
  z2ram: add error handling support for add_disk()
  nvdimm/pmem: use add_disk() error handling
  nvdimm/pmem: cleanup the disk if pmem_release_disk() is yet assigned
  nvdimm/blk: add error handling support for add_disk()
  nvdimm/blk: avoid calling del_gendisk() on early failures
  nvdimm/btt: add error handling support for add_disk()
  nvdimm/btt: use goto error labels on btt_blk_init()
  loop: Remove duplicate assignments
  drbd: Fix double free problem in drbd_create_device
  nvdimm/btt: do not call del_gendisk() if not needed
  bcache: fix use-after-free problem in bcache_device_free()
  zram: replace fsync_bdev with sync_blockdev
  ...
  • Loading branch information
Linus Torvalds committed Nov 9, 2021
2 parents 3e28850 + 2878fea commit cb690f5
Show file tree
Hide file tree
Showing 20 changed files with 221 additions and 101 deletions.
5 changes: 4 additions & 1 deletion block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ void blkdev_show(struct seq_file *seqf, off_t offset)
* @major: the requested major device number [1..BLKDEV_MAJOR_MAX-1]. If
* @major = 0, try to allocate any unused major number.
* @name: the name of the new block device as a zero terminated string
* @probe: allback that is called on access to any minor number of @major
* @probe: pre-devtmpfs / pre-udev callback used to create disks when their
* pre-created device node is accessed. When a probe call uses
* add_disk() and it fails the driver must cleanup resources. This
* interface may soon be removed.
*
* The @name must be unique within the system.
*
Expand Down
61 changes: 37 additions & 24 deletions drivers/block/ataflop.c
Original file line number Diff line number Diff line change
Expand Up @@ -2008,8 +2008,6 @@ static int ataflop_alloc_disk(unsigned int drive, unsigned int type)
return 0;
}

static DEFINE_MUTEX(ataflop_probe_lock);

static void ataflop_probe(dev_t dev)
{
int drive = MINOR(dev) & 3;
Expand All @@ -2020,14 +2018,38 @@ static void ataflop_probe(dev_t dev)

if (drive >= FD_MAX_UNITS || type >= NUM_DISK_MINORS)
return;
mutex_lock(&ataflop_probe_lock);
if (!unit[drive].disk[type]) {
if (ataflop_alloc_disk(drive, type) == 0) {
add_disk(unit[drive].disk[type]);
unit[drive].registered[type] = true;
if (unit[drive].disk[type])
return;
if (ataflop_alloc_disk(drive, type))
return;
if (add_disk(unit[drive].disk[type]))
goto cleanup_disk;
unit[drive].registered[type] = true;
return;

cleanup_disk:
blk_cleanup_disk(unit[drive].disk[type]);
unit[drive].disk[type] = NULL;
}

static void atari_floppy_cleanup(void)
{
int i;
int type;

for (i = 0; i < FD_MAX_UNITS; i++) {
for (type = 0; type < NUM_DISK_MINORS; type++) {
if (!unit[i].disk[type])
continue;
del_gendisk(unit[i].disk[type]);
blk_cleanup_queue(unit[i].disk[type]->queue);
put_disk(unit[i].disk[type]);
}
blk_mq_free_tag_set(&unit[i].tag_set);
}
mutex_unlock(&ataflop_probe_lock);

del_timer_sync(&fd_timer);
atari_stram_free(DMABuffer);
}

static void atari_cleanup_floppy_disk(struct atari_floppy_struct *fs)
Expand All @@ -2053,11 +2075,6 @@ static int __init atari_floppy_init (void)
/* Amiga, Mac, ... don't have Atari-compatible floppy :-) */
return -ENODEV;

mutex_lock(&ataflop_probe_lock);
ret = __register_blkdev(FLOPPY_MAJOR, "fd", ataflop_probe);
if (ret)
goto out_unlock;

for (i = 0; i < FD_MAX_UNITS; i++) {
memset(&unit[i].tag_set, 0, sizeof(unit[i].tag_set));
unit[i].tag_set.ops = &ataflop_mq_ops;
Expand Down Expand Up @@ -2113,17 +2130,19 @@ static int __init atari_floppy_init (void)
UseTrackbuffer ? "" : "no ");
config_types();

return 0;
ret = __register_blkdev(FLOPPY_MAJOR, "fd", ataflop_probe);
if (ret) {
printk(KERN_ERR "atari_floppy_init: cannot register block device\n");
atari_floppy_cleanup();
}
return ret;

err_out_dma:
atari_stram_free(DMABuffer);
err:
while (--i >= 0)
atari_cleanup_floppy_disk(&unit[i]);

unregister_blkdev(FLOPPY_MAJOR, "fd");
out_unlock:
mutex_unlock(&ataflop_probe_lock);
return ret;
}

Expand Down Expand Up @@ -2168,14 +2187,8 @@ __setup("floppy=", atari_floppy_setup);

static void __exit atari_floppy_exit(void)
{
int i;

for (i = 0; i < FD_MAX_UNITS; i++)
atari_cleanup_floppy_disk(&unit[i]);
unregister_blkdev(FLOPPY_MAJOR, "fd");

del_timer_sync(&fd_timer);
atari_stram_free( DMABuffer );
atari_floppy_cleanup();
}

module_init(atari_floppy_init)
Expand Down
9 changes: 7 additions & 2 deletions drivers/block/brd.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ static int brd_alloc(int i)
struct brd_device *brd;
struct gendisk *disk;
char buf[DISK_NAME_LEN];
int err = -ENOMEM;

mutex_lock(&brd_devices_mutex);
list_for_each_entry(brd, &brd_devices, brd_list) {
Expand Down Expand Up @@ -420,16 +421,20 @@ static int brd_alloc(int i)
/* Tell the block layer that this is not a rotational device */
blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);
blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, disk->queue);
add_disk(disk);
err = add_disk(disk);
if (err)
goto out_cleanup_disk;

return 0;

out_cleanup_disk:
blk_cleanup_disk(disk);
out_free_dev:
mutex_lock(&brd_devices_mutex);
list_del(&brd->brd_list);
mutex_unlock(&brd_devices_mutex);
kfree(brd);
return -ENOMEM;
return err;
}

static void brd_probe(dev_t dev)
Expand Down
4 changes: 1 addition & 3 deletions drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2796,7 +2796,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig

err = add_disk(disk);
if (err)
goto out_cleanup_disk;
goto out_idr_remove_vol;

/* inherit the connection state */
device->state.conn = first_connection(resource)->cstate;
Expand All @@ -2810,8 +2810,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
drbd_debugfs_device_add(device);
return NO_ERROR;

out_cleanup_disk:
blk_cleanup_disk(disk);
out_idr_remove_vol:
idr_remove(&connection->peer_devices, vnr);
out_idr_remove_from_resource:
Expand Down
17 changes: 13 additions & 4 deletions drivers/block/floppy.c
Original file line number Diff line number Diff line change
Expand Up @@ -4528,10 +4528,19 @@ static void floppy_probe(dev_t dev)
return;

mutex_lock(&floppy_probe_lock);
if (!disks[drive][type]) {
if (floppy_alloc_disk(drive, type) == 0)
add_disk(disks[drive][type]);
}
if (disks[drive][type])
goto out;
if (floppy_alloc_disk(drive, type))
goto out;
if (add_disk(disks[drive][type]))
goto cleanup_disk;
out:
mutex_unlock(&floppy_probe_lock);
return;

cleanup_disk:
blk_cleanup_disk(disks[drive][type]);
disks[drive][type] = NULL;
mutex_unlock(&floppy_probe_lock);
}

Expand Down
1 change: 0 additions & 1 deletion drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -1983,7 +1983,6 @@ static int loop_add(int i)
goto out_free_dev;
i = err;

err = -ENOMEM;
lo->tag_set.ops = &loop_mq_ops;
lo->tag_set.nr_hw_queues = 1;
lo->tag_set.queue_depth = 128;
Expand Down
44 changes: 21 additions & 23 deletions drivers/block/nbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ static void nbd_dev_remove(struct nbd_device *nbd)
mutex_lock(&nbd_index_mutex);
idr_remove(&nbd_index_idr, nbd->index);
mutex_unlock(&nbd_index_mutex);

destroy_workqueue(nbd->recv_workq);
kfree(nbd);
}

Expand Down Expand Up @@ -755,6 +755,8 @@ static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index,
if (cmd->index != index) {
dev_err(disk_to_dev(nbd->disk), "Unexpected reply %d from different sock %d (expected %d)",
tag, index, cmd->index);
ret = -ENOENT;
goto out;
}
if (cmd->cmd_cookie != nbd_handle_to_cookie(handle)) {
dev_err(disk_to_dev(nbd->disk), "Double reply on req %p, cmd_cookie %u, handle cookie %u\n",
Expand Down Expand Up @@ -1314,10 +1316,6 @@ static void nbd_config_put(struct nbd_device *nbd)
kfree(nbd->config);
nbd->config = NULL;

if (nbd->recv_workq)
destroy_workqueue(nbd->recv_workq);
nbd->recv_workq = NULL;

nbd->tag_set.timeout = 0;
nbd->disk->queue->limits.discard_granularity = 0;
nbd->disk->queue->limits.discard_alignment = 0;
Expand Down Expand Up @@ -1346,14 +1344,6 @@ static int nbd_start_device(struct nbd_device *nbd)
return -EINVAL;
}

nbd->recv_workq = alloc_workqueue("knbd%d-recv",
WQ_MEM_RECLAIM | WQ_HIGHPRI |
WQ_UNBOUND, 0, nbd->index);
if (!nbd->recv_workq) {
dev_err(disk_to_dev(nbd->disk), "Could not allocate knbd recv work queue.\n");
return -ENOMEM;
}

blk_mq_update_nr_hw_queues(&nbd->tag_set, config->num_connections);
nbd->pid = task_pid_nr(current);

Expand Down Expand Up @@ -1779,6 +1769,15 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
}
nbd->disk = disk;

nbd->recv_workq = alloc_workqueue("nbd%d-recv",
WQ_MEM_RECLAIM | WQ_HIGHPRI |
WQ_UNBOUND, 0, nbd->index);
if (!nbd->recv_workq) {
dev_err(disk_to_dev(nbd->disk), "Could not allocate knbd recv work queue.\n");
err = -ENOMEM;
goto out_err_disk;
}

/*
* Tell the block layer that we are not a rotational device
*/
Expand All @@ -1803,13 +1802,13 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
disk->major = NBD_MAJOR;

/* Too big first_minor can cause duplicate creation of
* sysfs files/links, since first_minor will be truncated to
* byte in __device_add_disk().
* sysfs files/links, since index << part_shift might overflow, or
* MKDEV() expect that the max bits of first_minor is 20.
*/
disk->first_minor = index << part_shift;
if (disk->first_minor > 0xff) {
if (disk->first_minor < index || disk->first_minor > MINORMASK) {
err = -EINVAL;
goto out_free_idr;
goto out_free_work;
}

disk->minors = 1 << part_shift;
Expand All @@ -1818,7 +1817,7 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
sprintf(disk->disk_name, "nbd%d", index);
err = add_disk(disk);
if (err)
goto out_err_disk;
goto out_free_work;

/*
* Now publish the device.
Expand All @@ -1827,6 +1826,8 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs)
nbd_total_devices++;
return nbd;

out_free_work:
destroy_workqueue(nbd->recv_workq);
out_err_disk:
blk_cleanup_disk(disk);
out_free_idr:
Expand Down Expand Up @@ -2082,13 +2083,10 @@ static void nbd_disconnect_and_put(struct nbd_device *nbd)
nbd_disconnect(nbd);
sock_shutdown(nbd);
/*
* Make sure recv thread has finished, so it does not drop the last
* config ref and try to destroy the workqueue from inside the work
* queue. And this also ensure that we can safely call nbd_clear_que()
* Make sure recv thread has finished, we can safely call nbd_clear_que()
* to cancel the inflight I/Os.
*/
if (nbd->recv_workq)
flush_workqueue(nbd->recv_workq);
flush_workqueue(nbd->recv_workq);
nbd_clear_que(nbd);
nbd->task_setup = NULL;
mutex_unlock(&nbd->config_lock);
Expand Down
8 changes: 6 additions & 2 deletions drivers/block/ps3disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,9 +467,13 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev)
gendisk->disk_name, priv->model, priv->raw_capacity >> 11,
get_capacity(gendisk) >> 11);

device_add_disk(&dev->sbd.core, gendisk, NULL);
return 0;
error = device_add_disk(&dev->sbd.core, gendisk, NULL);
if (error)
goto fail_cleanup_disk;

return 0;
fail_cleanup_disk:
blk_cleanup_disk(gendisk);
fail_free_tag_set:
blk_mq_free_tag_set(&priv->tag_set);
fail_teardown:
Expand Down
7 changes: 6 additions & 1 deletion drivers/block/ps3vram.c
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,14 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev)
dev_info(&dev->core, "%s: Using %llu MiB of GPU memory\n",
gendisk->disk_name, get_capacity(gendisk) >> 11);

device_add_disk(&dev->core, gendisk, NULL);
error = device_add_disk(&dev->core, gendisk, NULL);
if (error)
goto out_cleanup_disk;

return 0;

out_cleanup_disk:
blk_cleanup_disk(gendisk);
out_cache_cleanup:
remove_proc_entry(DEVICE_NAME, NULL);
ps3vram_cache_cleanup(dev);
Expand Down
14 changes: 11 additions & 3 deletions drivers/block/sunvdc.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,8 +826,8 @@ static int probe_disk(struct vdc_port *port)
if (IS_ERR(g)) {
printk(KERN_ERR PFX "%s: Could not allocate gendisk.\n",
port->vio.name);
blk_mq_free_tag_set(&port->tag_set);
return PTR_ERR(g);
err = PTR_ERR(g);
goto out_free_tag;
}

port->disk = g;
Expand Down Expand Up @@ -879,9 +879,17 @@ static int probe_disk(struct vdc_port *port)
port->vdisk_size, (port->vdisk_size >> (20 - 9)),
port->vio.ver.major, port->vio.ver.minor);

device_add_disk(&port->vio.vdev->dev, g, NULL);
err = device_add_disk(&port->vio.vdev->dev, g, NULL);
if (err)
goto out_cleanup_disk;

return 0;

out_cleanup_disk:
blk_cleanup_disk(g);
out_free_tag:
blk_mq_free_tag_set(&port->tag_set);
return err;
}

static struct ldc_channel_config vdc_ldc_cfg = {
Expand Down
7 changes: 5 additions & 2 deletions drivers/block/z2ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ static const struct blk_mq_ops z2_mq_ops = {
static int z2ram_register_disk(int minor)
{
struct gendisk *disk;
int err;

disk = blk_mq_alloc_disk(&tag_set, NULL);
if (IS_ERR(disk))
Expand All @@ -333,8 +334,10 @@ static int z2ram_register_disk(int minor)
sprintf(disk->disk_name, "z2ram");

z2ram_gendisk[minor] = disk;
add_disk(disk);
return 0;
err = add_disk(disk);
if (err)
blk_cleanup_disk(disk);
return err;
}

static int __init z2_init(void)
Expand Down
Loading

0 comments on commit cb690f5

Please sign in to comment.