Commit 4ff2473b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'block-5.13-2021-05-22' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:

 - Fix BLKRRPART and deletion race (Gulam, Christoph)

 - NVMe pull request (Christoph):
      - nvme-tcp corruption and timeout fixes (Sagi Grimberg, Keith
        Busch)
      - nvme-fc teardown fix (James Smart)
      - nvmet/nvme-loop memory leak fixes (Wu Bo)"

* tag 'block-5.13-2021-05-22' of git://git.kernel.dk/linux-block:
  block: fix a race between del_gendisk and BLKRRPART
  block: prevent block device lookups at the beginning of del_gendisk
  nvme-fc: clear q_live at beginning of association teardown
  nvme-tcp: rerun io_work if req_list is not empty
  nvme-tcp: fix possible use-after-completion
  nvme-loop: fix memory leak in nvme_loop_create_ctrl()
  nvmet: fix memory leak in nvmet_alloc_ctrl()
parents b9231dfb bc6a3851
...@@ -29,8 +29,6 @@ ...@@ -29,8 +29,6 @@
static struct kobject *block_depr; static struct kobject *block_depr;
DECLARE_RWSEM(bdev_lookup_sem);
/* for extended dynamic devt allocation, currently only one major is used */ /* for extended dynamic devt allocation, currently only one major is used */
#define NR_EXT_DEVT (1 << MINORBITS) #define NR_EXT_DEVT (1 << MINORBITS)
static DEFINE_IDA(ext_devt_ida); static DEFINE_IDA(ext_devt_ida);
...@@ -609,13 +607,8 @@ void del_gendisk(struct gendisk *disk) ...@@ -609,13 +607,8 @@ void del_gendisk(struct gendisk *disk)
blk_integrity_del(disk); blk_integrity_del(disk);
disk_del_events(disk); disk_del_events(disk);
/*
* Block lookups of the disk until all bdevs are unhashed and the
* disk is marked as dead (GENHD_FL_UP cleared).
*/
down_write(&bdev_lookup_sem);
mutex_lock(&disk->part0->bd_mutex); mutex_lock(&disk->part0->bd_mutex);
disk->flags &= ~GENHD_FL_UP;
blk_drop_partitions(disk); blk_drop_partitions(disk);
mutex_unlock(&disk->part0->bd_mutex); mutex_unlock(&disk->part0->bd_mutex);
...@@ -629,8 +622,6 @@ void del_gendisk(struct gendisk *disk) ...@@ -629,8 +622,6 @@ void del_gendisk(struct gendisk *disk)
remove_inode_hash(disk->part0->bd_inode); remove_inode_hash(disk->part0->bd_inode);
set_capacity(disk, 0); set_capacity(disk, 0);
disk->flags &= ~GENHD_FL_UP;
up_write(&bdev_lookup_sem);
if (!(disk->flags & GENHD_FL_HIDDEN)) { if (!(disk->flags & GENHD_FL_HIDDEN)) {
sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi");
......
...@@ -2461,6 +2461,18 @@ nvme_fc_terminate_exchange(struct request *req, void *data, bool reserved) ...@@ -2461,6 +2461,18 @@ nvme_fc_terminate_exchange(struct request *req, void *data, bool reserved)
static void static void
__nvme_fc_abort_outstanding_ios(struct nvme_fc_ctrl *ctrl, bool start_queues) __nvme_fc_abort_outstanding_ios(struct nvme_fc_ctrl *ctrl, bool start_queues)
{ {
int q;
/*
* if aborting io, the queues are no longer good, mark them
* all as not live.
*/
if (ctrl->ctrl.queue_count > 1) {
for (q = 1; q < ctrl->ctrl.queue_count; q++)
clear_bit(NVME_FC_Q_LIVE, &ctrl->queues[q].flags);
}
clear_bit(NVME_FC_Q_LIVE, &ctrl->queues[0].flags);
/* /*
* If io queues are present, stop them and terminate all outstanding * If io queues are present, stop them and terminate all outstanding
* ios on them. As FC allocates FC exchange for each io, the * ios on them. As FC allocates FC exchange for each io, the
......
...@@ -943,7 +943,6 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req) ...@@ -943,7 +943,6 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
if (ret <= 0) if (ret <= 0)
return ret; return ret;
nvme_tcp_advance_req(req, ret);
if (queue->data_digest) if (queue->data_digest)
nvme_tcp_ddgst_update(queue->snd_hash, page, nvme_tcp_ddgst_update(queue->snd_hash, page,
offset, ret); offset, ret);
...@@ -960,6 +959,7 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req) ...@@ -960,6 +959,7 @@ static int nvme_tcp_try_send_data(struct nvme_tcp_request *req)
} }
return 1; return 1;
} }
nvme_tcp_advance_req(req, ret);
} }
return -EAGAIN; return -EAGAIN;
} }
...@@ -1140,7 +1140,8 @@ static void nvme_tcp_io_work(struct work_struct *w) ...@@ -1140,7 +1140,8 @@ static void nvme_tcp_io_work(struct work_struct *w)
pending = true; pending = true;
else if (unlikely(result < 0)) else if (unlikely(result < 0))
break; break;
} } else
pending = !llist_empty(&queue->req_list);
result = nvme_tcp_try_recv(queue); result = nvme_tcp_try_recv(queue);
if (result > 0) if (result > 0)
......
...@@ -1372,7 +1372,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, ...@@ -1372,7 +1372,7 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn,
goto out_free_changed_ns_list; goto out_free_changed_ns_list;
if (subsys->cntlid_min > subsys->cntlid_max) if (subsys->cntlid_min > subsys->cntlid_max)
goto out_free_changed_ns_list; goto out_free_sqs;
ret = ida_simple_get(&cntlid_ida, ret = ida_simple_get(&cntlid_ida,
subsys->cntlid_min, subsys->cntlid_max, subsys->cntlid_min, subsys->cntlid_max,
......
...@@ -590,8 +590,10 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev, ...@@ -590,8 +590,10 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev,
ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_loop_ctrl_ops, ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_loop_ctrl_ops,
0 /* no quirks, we're perfect! */); 0 /* no quirks, we're perfect! */);
if (ret) if (ret) {
kfree(ctrl);
goto out; goto out;
}
if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING))
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
......
...@@ -1244,6 +1244,9 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate) ...@@ -1244,6 +1244,9 @@ int bdev_disk_changed(struct block_device *bdev, bool invalidate)
lockdep_assert_held(&bdev->bd_mutex); lockdep_assert_held(&bdev->bd_mutex);
if (!(disk->flags & GENHD_FL_UP))
return -ENXIO;
rescan: rescan:
if (bdev->bd_part_count) if (bdev->bd_part_count)
return -EBUSY; return -EBUSY;
...@@ -1298,6 +1301,9 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode) ...@@ -1298,6 +1301,9 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode)
struct gendisk *disk = bdev->bd_disk; struct gendisk *disk = bdev->bd_disk;
int ret = 0; int ret = 0;
if (!(disk->flags & GENHD_FL_UP))
return -ENXIO;
if (!bdev->bd_openers) { if (!bdev->bd_openers) {
if (!bdev_is_partition(bdev)) { if (!bdev_is_partition(bdev)) {
ret = 0; ret = 0;
...@@ -1332,8 +1338,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode) ...@@ -1332,8 +1338,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode)
whole->bd_part_count++; whole->bd_part_count++;
mutex_unlock(&whole->bd_mutex); mutex_unlock(&whole->bd_mutex);
if (!(disk->flags & GENHD_FL_UP) || if (!bdev_nr_sectors(bdev)) {
!bdev_nr_sectors(bdev)) {
__blkdev_put(whole, mode, 1); __blkdev_put(whole, mode, 1);
bdput(whole); bdput(whole);
return -ENXIO; return -ENXIO;
...@@ -1364,16 +1369,12 @@ struct block_device *blkdev_get_no_open(dev_t dev) ...@@ -1364,16 +1369,12 @@ struct block_device *blkdev_get_no_open(dev_t dev)
struct block_device *bdev; struct block_device *bdev;
struct gendisk *disk; struct gendisk *disk;
down_read(&bdev_lookup_sem);
bdev = bdget(dev); bdev = bdget(dev);
if (!bdev) { if (!bdev) {
up_read(&bdev_lookup_sem);
blk_request_module(dev); blk_request_module(dev);
down_read(&bdev_lookup_sem);
bdev = bdget(dev); bdev = bdget(dev);
if (!bdev) if (!bdev)
goto unlock; return NULL;
} }
disk = bdev->bd_disk; disk = bdev->bd_disk;
...@@ -1383,14 +1384,11 @@ struct block_device *blkdev_get_no_open(dev_t dev) ...@@ -1383,14 +1384,11 @@ struct block_device *blkdev_get_no_open(dev_t dev)
goto put_disk; goto put_disk;
if (!try_module_get(bdev->bd_disk->fops->owner)) if (!try_module_get(bdev->bd_disk->fops->owner))
goto put_disk; goto put_disk;
up_read(&bdev_lookup_sem);
return bdev; return bdev;
put_disk: put_disk:
put_disk(disk); put_disk(disk);
bdput: bdput:
bdput(bdev); bdput(bdev);
unlock:
up_read(&bdev_lookup_sem);
return NULL; return NULL;
} }
......
...@@ -306,8 +306,6 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev, ...@@ -306,8 +306,6 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev,
} }
#endif /* CONFIG_SYSFS */ #endif /* CONFIG_SYSFS */
extern struct rw_semaphore bdev_lookup_sem;
dev_t blk_lookup_devt(const char *name, int partno); dev_t blk_lookup_devt(const char *name, int partno);
void blk_request_module(dev_t devt); void blk_request_module(dev_t devt);
#ifdef CONFIG_BLOCK #ifdef CONFIG_BLOCK
......
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