for-5.16/drivers-2021-11-09
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAmGKqOcQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgpr3yEADD9Cx8oNk3KzWV3c3JlIR4JQtvpczS3dho KkGU0D5fOh1sViXbLBNr6VxypcEIKQoHxDQQ6qid1kOu/B3mCNM1duLsVjyj3Qa0 7nbm2dVUsD/EVDuXedRmMvcfCUx6Z23DbpI182wXtIPaCsEEmsANzHnZNg38OV44 25SYG0QUvb9ViSz1Y1GORu0ttEJNF2GhZfiBpb0WveRnY7eTSL/PnHNDzHsSeFv4 zD0W205g7jKbt0+57kgNElTz7DbdM3p8XVex+aXPlFaHz2qx4ZoJJIsaMv/P8tT5 14b50cB41xnPvlGTvqr1WfZZfJocDNq2rG+fh6N5D1sO86ogWpj7psiiADfa0pb6 ZWoJqhk3BvEUMPQ5N/BJ/8j3FWGIYWtKQf4QcyxrJYpqDwtwbBfMlzKkc7JMPFYk JAi6uq1uF5SbA4x99G90tK85LvxsbkseyIYXgBJ/GIyW5doIPkD9TPDEzJMCdHOe laynHS5PMHzuhPLuEDDn9sTVXpZWAMBnoy4j1L4wGmBjiogYWLTSJVobODzCAqHY 1Va2oP6SXfCdVRkCysFbcrdsjJuoIWlMKrdE40tNvkmU0v7sEX0Zd+GLHiaWdIZa fgxC9fmZtDDOowCp+Iw0VaAqPeeptmyUrof06ZktJleOAscX7kSwbxPdmr1FM0jy dbnLDyaq/A== =QaFI -----END PGP SIGNATURE----- Merge tag 'for-5.16/drivers-2021-11-09' of git://git.kernel.dk/linux-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 ...
This commit is contained in:
commit
cb690f5238
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -2113,7 +2130,12 @@ 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);
|
||||
|
@ -2121,9 +2143,6 @@ err:
|
|||
while (--i >= 0)
|
||||
atari_cleanup_floppy_disk(&unit[i]);
|
||||
|
||||
unregister_blkdev(FLOPPY_MAJOR, "fd");
|
||||
out_unlock:
|
||||
mutex_unlock(&ataflop_probe_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
|
|
@ -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))
|
||||
|
@ -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)
|
||||
|
|
|
@ -1734,12 +1734,13 @@ static void zram_reset_device(struct zram *zram)
|
|||
set_capacity_and_notify(zram->disk, 0);
|
||||
part_stat_set_all(zram->disk->part0, 0);
|
||||
|
||||
up_write(&zram->init_lock);
|
||||
/* I/O operation under all of CPU are done so let's free */
|
||||
zram_meta_free(zram, disksize);
|
||||
memset(&zram->stats, 0, sizeof(zram->stats));
|
||||
zcomp_destroy(comp);
|
||||
reset_bdev(zram);
|
||||
|
||||
up_write(&zram->init_lock);
|
||||
}
|
||||
|
||||
static ssize_t disksize_store(struct device *dev,
|
||||
|
@ -1819,7 +1820,7 @@ static ssize_t reset_store(struct device *dev,
|
|||
mutex_unlock(&bdev->bd_disk->open_mutex);
|
||||
|
||||
/* Make sure all the pending I/O are finished */
|
||||
fsync_bdev(bdev);
|
||||
sync_blockdev(bdev);
|
||||
zram_reset_device(zram);
|
||||
|
||||
mutex_lock(&bdev->bd_disk->open_mutex);
|
||||
|
@ -1979,7 +1980,9 @@ static int zram_add(void)
|
|||
blk_queue_max_write_zeroes_sectors(zram->disk->queue, UINT_MAX);
|
||||
|
||||
blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, zram->disk->queue);
|
||||
device_add_disk(NULL, zram->disk, zram_disk_attr_groups);
|
||||
ret = device_add_disk(NULL, zram->disk, zram_disk_attr_groups);
|
||||
if (ret)
|
||||
goto out_cleanup_disk;
|
||||
|
||||
strlcpy(zram->compressor, default_compressor, sizeof(zram->compressor));
|
||||
|
||||
|
@ -1987,6 +1990,8 @@ static int zram_add(void)
|
|||
pr_info("Added device: %s\n", zram->disk->disk_name);
|
||||
return device_id;
|
||||
|
||||
out_cleanup_disk:
|
||||
blk_cleanup_disk(zram->disk);
|
||||
out_free_idr:
|
||||
idr_remove(&zram_index_idr, device_id);
|
||||
out_free_dev:
|
||||
|
@ -1997,25 +2002,47 @@ out_free_dev:
|
|||
static int zram_remove(struct zram *zram)
|
||||
{
|
||||
struct block_device *bdev = zram->disk->part0;
|
||||
bool claimed;
|
||||
|
||||
mutex_lock(&bdev->bd_disk->open_mutex);
|
||||
if (bdev->bd_openers || zram->claim) {
|
||||
if (bdev->bd_openers) {
|
||||
mutex_unlock(&bdev->bd_disk->open_mutex);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
zram->claim = true;
|
||||
claimed = zram->claim;
|
||||
if (!claimed)
|
||||
zram->claim = true;
|
||||
mutex_unlock(&bdev->bd_disk->open_mutex);
|
||||
|
||||
zram_debugfs_unregister(zram);
|
||||
|
||||
/* Make sure all the pending I/O are finished */
|
||||
fsync_bdev(bdev);
|
||||
zram_reset_device(zram);
|
||||
if (claimed) {
|
||||
/*
|
||||
* If we were claimed by reset_store(), del_gendisk() will
|
||||
* wait until reset_store() is done, so nothing need to do.
|
||||
*/
|
||||
;
|
||||
} else {
|
||||
/* Make sure all the pending I/O are finished */
|
||||
sync_blockdev(bdev);
|
||||
zram_reset_device(zram);
|
||||
}
|
||||
|
||||
pr_info("Removed device: %s\n", zram->disk->disk_name);
|
||||
|
||||
del_gendisk(zram->disk);
|
||||
|
||||
/* del_gendisk drains pending reset_store */
|
||||
WARN_ON_ONCE(claimed && zram->claim);
|
||||
|
||||
/*
|
||||
* disksize_store() may be called in between zram_reset_device()
|
||||
* and del_gendisk(), so run the last reset to avoid leaking
|
||||
* anything allocated with disksize_store()
|
||||
*/
|
||||
zram_reset_device(zram);
|
||||
|
||||
blk_cleanup_disk(zram->disk);
|
||||
kfree(zram);
|
||||
return 0;
|
||||
|
@ -2092,7 +2119,7 @@ static struct class zram_control_class = {
|
|||
|
||||
static int zram_remove_cb(int id, void *ptr, void *data)
|
||||
{
|
||||
zram_remove(ptr);
|
||||
WARN_ON_ONCE(zram_remove(ptr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -378,7 +378,7 @@ static void do_btree_node_write(struct btree *b)
|
|||
struct bvec_iter_all iter_all;
|
||||
|
||||
bio_for_each_segment_all(bv, b->bio, iter_all) {
|
||||
memcpy(bvec_virt(bv), addr, PAGE_SIZE);
|
||||
memcpy(page_address(bv->bv_page), addr, PAGE_SIZE);
|
||||
addr += PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
|
|
@ -885,9 +885,9 @@ static void bcache_device_free(struct bcache_device *d)
|
|||
bcache_device_detach(d);
|
||||
|
||||
if (disk) {
|
||||
blk_cleanup_disk(disk);
|
||||
ida_simple_remove(&bcache_device_idx,
|
||||
first_minor_to_idx(disk->first_minor));
|
||||
blk_cleanup_disk(disk);
|
||||
}
|
||||
|
||||
bioset_exit(&d->bio_split);
|
||||
|
|
|
@ -2469,11 +2469,30 @@ backlog_store(struct mddev *mddev, const char *buf, size_t len)
|
|||
{
|
||||
unsigned long backlog;
|
||||
unsigned long old_mwb = mddev->bitmap_info.max_write_behind;
|
||||
struct md_rdev *rdev;
|
||||
bool has_write_mostly = false;
|
||||
int rv = kstrtoul(buf, 10, &backlog);
|
||||
if (rv)
|
||||
return rv;
|
||||
if (backlog > COUNTER_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Without write mostly device, it doesn't make sense to set
|
||||
* backlog for max_write_behind.
|
||||
*/
|
||||
rdev_for_each(rdev, mddev) {
|
||||
if (test_bit(WriteMostly, &rdev->flags)) {
|
||||
has_write_mostly = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_write_mostly) {
|
||||
pr_warn_ratelimited("%s: can't set backlog, no write mostly device available\n",
|
||||
mdname(mddev));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mddev->bitmap_info.max_write_behind = backlog;
|
||||
if (!backlog && mddev->serial_info_pool) {
|
||||
/* serial_info_pool is not needed if backlog is zero */
|
||||
|
|
|
@ -1081,7 +1081,7 @@ static int ppl_load_distributed(struct ppl_log *log)
|
|||
struct ppl_conf *ppl_conf = log->ppl_conf;
|
||||
struct md_rdev *rdev = log->rdev;
|
||||
struct mddev *mddev = rdev->mddev;
|
||||
struct page *page, *page2, *tmp;
|
||||
struct page *page, *page2;
|
||||
struct ppl_header *pplhdr = NULL, *prev_pplhdr = NULL;
|
||||
u32 crc, crc_stored;
|
||||
u32 signature;
|
||||
|
@ -1156,9 +1156,7 @@ static int ppl_load_distributed(struct ppl_log *log)
|
|||
prev_pplhdr_offset = pplhdr_offset;
|
||||
prev_pplhdr = pplhdr;
|
||||
|
||||
tmp = page;
|
||||
page = page2;
|
||||
page2 = tmp;
|
||||
swap(page, page2);
|
||||
|
||||
/* calculate next potential ppl offset */
|
||||
for (i = 0; i < le32_to_cpu(pplhdr->entries_count); i++)
|
||||
|
|
|
@ -447,12 +447,18 @@ int ubiblock_create(struct ubi_volume_info *vi)
|
|||
list_add_tail(&dev->list, &ubiblock_devices);
|
||||
|
||||
/* Must be the last step: anyone can call file ops from now on */
|
||||
add_disk(dev->gd);
|
||||
ret = add_disk(dev->gd);
|
||||
if (ret)
|
||||
goto out_destroy_wq;
|
||||
|
||||
dev_info(disk_to_dev(dev->gd), "created from ubi%d:%d(%s)",
|
||||
dev->ubi_num, dev->vol_id, vi->name);
|
||||
mutex_unlock(&devices_mutex);
|
||||
return 0;
|
||||
|
||||
out_destroy_wq:
|
||||
list_del(&dev->list);
|
||||
destroy_workqueue(dev->wq);
|
||||
out_remove_minor:
|
||||
idr_remove(&ubiblock_minor_idr, gd->first_minor);
|
||||
out_cleanup_disk:
|
||||
|
|
|
@ -239,6 +239,7 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
|
|||
resource_size_t available_disk_size;
|
||||
struct gendisk *disk;
|
||||
u64 internal_nlba;
|
||||
int rc;
|
||||
|
||||
internal_nlba = div_u64(nsblk->size, nsblk_internal_lbasize(nsblk));
|
||||
available_disk_size = internal_nlba * nsblk_sector_size(nsblk);
|
||||
|
@ -255,20 +256,28 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk)
|
|||
blk_queue_logical_block_size(disk->queue, nsblk_sector_size(nsblk));
|
||||
blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);
|
||||
|
||||
if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk))
|
||||
return -ENOMEM;
|
||||
|
||||
if (nsblk_meta_size(nsblk)) {
|
||||
int rc = nd_integrity_init(disk, nsblk_meta_size(nsblk));
|
||||
rc = nd_integrity_init(disk, nsblk_meta_size(nsblk));
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
goto out_before_devm_err;
|
||||
}
|
||||
|
||||
set_capacity(disk, available_disk_size >> SECTOR_SHIFT);
|
||||
device_add_disk(dev, disk, NULL);
|
||||
rc = device_add_disk(dev, disk, NULL);
|
||||
if (rc)
|
||||
goto out_before_devm_err;
|
||||
|
||||
/* nd_blk_release_disk() is called if this fails */
|
||||
if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk))
|
||||
return -ENOMEM;
|
||||
|
||||
nvdimm_check_and_set_ro(disk);
|
||||
return 0;
|
||||
|
||||
out_before_devm_err:
|
||||
blk_cleanup_disk(disk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int nd_blk_probe(struct device *dev)
|
||||
|
|
|
@ -1519,6 +1519,7 @@ static int btt_blk_init(struct btt *btt)
|
|||
{
|
||||
struct nd_btt *nd_btt = btt->nd_btt;
|
||||
struct nd_namespace_common *ndns = nd_btt->ndns;
|
||||
int rc = -ENOMEM;
|
||||
|
||||
btt->btt_disk = blk_alloc_disk(NUMA_NO_NODE);
|
||||
if (!btt->btt_disk)
|
||||
|
@ -1534,20 +1535,24 @@ static int btt_blk_init(struct btt *btt)
|
|||
blk_queue_flag_set(QUEUE_FLAG_NONROT, btt->btt_disk->queue);
|
||||
|
||||
if (btt_meta_size(btt)) {
|
||||
int rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt));
|
||||
|
||||
if (rc) {
|
||||
del_gendisk(btt->btt_disk);
|
||||
blk_cleanup_disk(btt->btt_disk);
|
||||
return rc;
|
||||
}
|
||||
rc = nd_integrity_init(btt->btt_disk, btt_meta_size(btt));
|
||||
if (rc)
|
||||
goto out_cleanup_disk;
|
||||
}
|
||||
|
||||
set_capacity(btt->btt_disk, btt->nlba * btt->sector_size >> 9);
|
||||
device_add_disk(&btt->nd_btt->dev, btt->btt_disk, NULL);
|
||||
rc = device_add_disk(&btt->nd_btt->dev, btt->btt_disk, NULL);
|
||||
if (rc)
|
||||
goto out_cleanup_disk;
|
||||
|
||||
btt->nd_btt->size = btt->nlba * (u64)btt->sector_size;
|
||||
nvdimm_check_and_set_ro(btt->btt_disk);
|
||||
|
||||
return 0;
|
||||
|
||||
out_cleanup_disk:
|
||||
blk_cleanup_disk(btt->btt_disk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void btt_blk_cleanup(struct btt *btt)
|
||||
|
|
|
@ -428,8 +428,10 @@ static int pmem_attach_disk(struct device *dev,
|
|||
bb_range.end = res->end;
|
||||
}
|
||||
|
||||
if (IS_ERR(addr))
|
||||
return PTR_ERR(addr);
|
||||
if (IS_ERR(addr)) {
|
||||
rc = PTR_ERR(addr);
|
||||
goto out;
|
||||
}
|
||||
pmem->virt_addr = addr;
|
||||
|
||||
blk_queue_write_cache(q, true, fua);
|
||||
|
@ -454,12 +456,15 @@ static int pmem_attach_disk(struct device *dev,
|
|||
flags = DAXDEV_F_SYNC;
|
||||
dax_dev = alloc_dax(pmem, disk->disk_name, &pmem_dax_ops, flags);
|
||||
if (IS_ERR(dax_dev)) {
|
||||
return PTR_ERR(dax_dev);
|
||||
rc = PTR_ERR(dax_dev);
|
||||
goto out;
|
||||
}
|
||||
dax_write_cache(dax_dev, nvdimm_has_cache(nd_region));
|
||||
pmem->dax_dev = dax_dev;
|
||||
|
||||
device_add_disk(dev, disk, pmem_attribute_groups);
|
||||
rc = device_add_disk(dev, disk, pmem_attribute_groups);
|
||||
if (rc)
|
||||
goto out_cleanup_dax;
|
||||
if (devm_add_action_or_reset(dev, pmem_release_disk, pmem))
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -469,8 +474,14 @@ static int pmem_attach_disk(struct device *dev,
|
|||
"badblocks");
|
||||
if (!pmem->bb_state)
|
||||
dev_warn(dev, "'badblocks' notification disabled\n");
|
||||
|
||||
return 0;
|
||||
|
||||
out_cleanup_dax:
|
||||
kill_dax(pmem->dax_dev);
|
||||
put_dax(pmem->dax_dev);
|
||||
out:
|
||||
blk_cleanup_disk(pmem->disk);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int nd_pmem_probe(struct device *dev)
|
||||
|
|
Loading…
Reference in New Issue