Commit cb690f52 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 3e28850c 2878feae
......@@ -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 @@ static int __init atari_floppy_init (void)
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 @@ static int zram_add(void)
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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment