Commit 8a05ef70 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'block-6.9-20240405' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

 - NVMe pull request via Keith:
      - Atomic queue limits fixes (Christoph)
      - Fabrics fixes (Hannes, Daniel)

 - Discard overflow fix (Li)

 - Cleanup fix for null_blk (Damien)

* tag 'block-6.9-20240405' of git://git.kernel.dk/linux:
  nvme-fc: rename free_ctrl callback to match name pattern
  nvmet-fc: move RCU read lock to nvmet_fc_assoc_exists
  nvmet: implement unique discovery NQN
  nvme: don't create a multipath node for zero capacity devices
  nvme: split nvme_update_zone_info
  nvme-multipath: don't inherit LBA-related fields for the multipath node
  block: fix overflow in blk_ioctl_discard()
  nullblk: Fix cleanup order in null_add_dev() error path
parents 4f72ed49 9d0e8524
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
		unsigned long arg)
{
	uint64_t range[2];
	uint64_t start, len;
	uint64_t start, len, end;
	struct inode *inode = bdev->bd_inode;
	int err;

@@ -117,7 +117,8 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
	if (len & 511)
		return -EINVAL;

	if (start + len > bdev_nr_bytes(bdev))
	if (check_add_overflow(start, len, &end) ||
	    end > bdev_nr_bytes(bdev))
		return -EINVAL;

	filemap_invalidate_lock(inode->i_mapping);
+2 −2
Original line number Diff line number Diff line
@@ -1965,10 +1965,10 @@ static int null_add_dev(struct nullb_device *dev)

out_ida_free:
	ida_free(&nullb_indexes, nullb->index);
out_cleanup_zone:
	null_free_zoned_dev(dev);
out_cleanup_disk:
	put_disk(nullb->disk);
out_cleanup_zone:
	null_free_zoned_dev(dev);
out_cleanup_tags:
	if (nullb->tag_set == &nullb->__tag_set)
		blk_mq_free_tag_set(nullb->tag_set);
+32 −9
Original line number Diff line number Diff line
@@ -2076,6 +2076,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
	bool vwc = ns->ctrl->vwc & NVME_CTRL_VWC_PRESENT;
	struct queue_limits lim;
	struct nvme_id_ns_nvm *nvm = NULL;
	struct nvme_zone_info zi = {};
	struct nvme_id_ns *id;
	sector_t capacity;
	unsigned lbaf;
@@ -2088,9 +2089,10 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
	if (id->ncap == 0) {
		/* namespace not allocated or attached */
		info->is_removed = true;
		ret = -ENODEV;
		ret = -ENXIO;
		goto out;
	}
	lbaf = nvme_lbaf_index(id->flbas);

	if (ns->ctrl->ctratt & NVME_CTRL_ATTR_ELBAS) {
		ret = nvme_identify_ns_nvm(ns->ctrl, info->nsid, &nvm);
@@ -2098,8 +2100,14 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
			goto out;
	}

	if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
	    ns->head->ids.csi == NVME_CSI_ZNS) {
		ret = nvme_query_zone_info(ns, lbaf, &zi);
		if (ret < 0)
			goto out;
	}

	blk_mq_freeze_queue(ns->disk->queue);
	lbaf = nvme_lbaf_index(id->flbas);
	ns->head->lba_shift = id->lbaf[lbaf].ds;
	ns->head->nuse = le64_to_cpu(id->nuse);
	capacity = nvme_lba_to_sect(ns->head, le64_to_cpu(id->nsze));
@@ -2112,13 +2120,8 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
		capacity = 0;
	nvme_config_discard(ns, &lim);
	if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
	    ns->head->ids.csi == NVME_CSI_ZNS) {
		ret = nvme_update_zone_info(ns, lbaf, &lim);
		if (ret) {
			blk_mq_unfreeze_queue(ns->disk->queue);
			goto out;
		}
	}
	    ns->head->ids.csi == NVME_CSI_ZNS)
		nvme_update_zone_info(ns, &lim, &zi);
	ret = queue_limits_commit_update(ns->disk->queue, &lim);
	if (ret) {
		blk_mq_unfreeze_queue(ns->disk->queue);
@@ -2201,6 +2204,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
	}

	if (!ret && nvme_ns_head_multipath(ns->head)) {
		struct queue_limits *ns_lim = &ns->disk->queue->limits;
		struct queue_limits lim;

		blk_mq_freeze_queue(ns->head->disk->queue);
@@ -2212,7 +2216,26 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_ns_info *info)
		set_disk_ro(ns->head->disk, nvme_ns_is_readonly(ns, info));
		nvme_mpath_revalidate_paths(ns);

		/*
		 * queue_limits mixes values that are the hardware limitations
		 * for bio splitting with what is the device configuration.
		 *
		 * For NVMe the device configuration can change after e.g. a
		 * Format command, and we really want to pick up the new format
		 * value here.  But we must still stack the queue limits to the
		 * least common denominator for multipathing to split the bios
		 * properly.
		 *
		 * To work around this, we explicitly set the device
		 * configuration to those that we just queried, but only stack
		 * the splitting limits in to make sure we still obey possibly
		 * lower limitations of other controllers.
		 */
		lim = queue_limits_start_update(ns->head->disk->queue);
		lim.logical_block_size = ns_lim->logical_block_size;
		lim.physical_block_size = ns_lim->physical_block_size;
		lim.io_min = ns_lim->io_min;
		lim.io_opt = ns_lim->io_opt;
		queue_limits_stack_bdev(&lim, ns->disk->part0, 0,
					ns->head->disk->disk_name);
		ret = queue_limits_commit_update(ns->head->disk->queue, &lim);
+2 −2
Original line number Diff line number Diff line
@@ -2428,7 +2428,7 @@ nvme_fc_ctrl_get(struct nvme_fc_ctrl *ctrl)
 * controller. Called after last nvme_put_ctrl() call
 */
static void
nvme_fc_nvme_ctrl_freed(struct nvme_ctrl *nctrl)
nvme_fc_free_ctrl(struct nvme_ctrl *nctrl)
{
	struct nvme_fc_ctrl *ctrl = to_fc_ctrl(nctrl);

@@ -3384,7 +3384,7 @@ static const struct nvme_ctrl_ops nvme_fc_ctrl_ops = {
	.reg_read32		= nvmf_reg_read32,
	.reg_read64		= nvmf_reg_read64,
	.reg_write32		= nvmf_reg_write32,
	.free_ctrl		= nvme_fc_nvme_ctrl_freed,
	.free_ctrl		= nvme_fc_free_ctrl,
	.submit_async_event	= nvme_fc_submit_async_event,
	.delete_ctrl		= nvme_fc_delete_ctrl,
	.get_address		= nvmf_get_address,
+10 −2
Original line number Diff line number Diff line
@@ -1036,10 +1036,18 @@ static inline bool nvme_disk_is_ns_head(struct gendisk *disk)
}
#endif /* CONFIG_NVME_MULTIPATH */

struct nvme_zone_info {
	u64 zone_size;
	unsigned int max_open_zones;
	unsigned int max_active_zones;
};

int nvme_ns_report_zones(struct nvme_ns *ns, sector_t sector,
		unsigned int nr_zones, report_zones_cb cb, void *data);
int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf,
		struct queue_limits *lim);
int nvme_query_zone_info(struct nvme_ns *ns, unsigned lbaf,
		struct nvme_zone_info *zi);
void nvme_update_zone_info(struct nvme_ns *ns, struct queue_limits *lim,
		struct nvme_zone_info *zi);
#ifdef CONFIG_BLK_DEV_ZONED
blk_status_t nvme_setup_zone_mgmt_send(struct nvme_ns *ns, struct request *req,
				       struct nvme_command *cmnd,
Loading