Commit 091f06d9 authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge tag 'nvme-5.16-2021-12-10' of git://git.infradead.org/nvme into block-5.16

Pull NVMe fixes from Christoph:

"nvme fixes for Linux 5.16

 - set ana_log_size to 0 after freeing ana_log_buf (Hou Tao)
 - show subsys nqn for duplicate cntlids (Keith Busch)
 - disable namespace access for unsupported metadata (Keith Busch)
 - report write pointer for a full zone as zone start + zone len
   (Niklas Cassel)
 - fix use after free when disconnecting a reconnecting ctrl
   (Ruozhu Li)
 - fix a list corruption in nvmet-tcp (Sagi Grimberg)"

* tag 'nvme-5.16-2021-12-10' of git://git.infradead.org/nvme:
  nvmet-tcp: fix possible list corruption for unexpected command failure
  nvme: fix use after free when disconnecting a reconnecting ctrl
  nvme-multipath: set ana_log_size to 0 after free ana_log_buf
  nvme: report write pointer for a full zone as zone start + zone len
  nvme: disable namespace access for unsupported metadata
  nvme: show subsys nqn for duplicate cntlids
parents 75feae73 30e32f30
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -666,6 +666,7 @@ blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl,
		struct request *rq)
{
	if (ctrl->state != NVME_CTRL_DELETING_NOIO &&
	    ctrl->state != NVME_CTRL_DELETING &&
	    ctrl->state != NVME_CTRL_DEAD &&
	    !test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags) &&
	    !blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH))
@@ -1749,9 +1750,20 @@ static int nvme_configure_metadata(struct nvme_ns *ns, struct nvme_id_ns *id)
		 */
		if (WARN_ON_ONCE(!(id->flbas & NVME_NS_FLBAS_META_EXT)))
			return -EINVAL;
		if (ctrl->max_integrity_segments)
			ns->features |=
				(NVME_NS_METADATA_SUPPORTED | NVME_NS_EXT_LBAS);

		ns->features |= NVME_NS_EXT_LBAS;

		/*
		 * The current fabrics transport drivers support namespace
		 * metadata formats only if nvme_ns_has_pi() returns true.
		 * Suppress support for all other formats so the namespace will
		 * have a 0 capacity and not be usable through the block stack.
		 *
		 * Note, this check will need to be modified if any drivers
		 * gain the ability to use other metadata formats.
		 */
		if (ctrl->max_integrity_segments && nvme_ns_has_pi(ns))
			ns->features |= NVME_NS_METADATA_SUPPORTED;
	} else {
		/*
		 * For PCIe controllers, we can't easily remap the separate
@@ -2696,8 +2708,9 @@ static bool nvme_validate_cntlid(struct nvme_subsystem *subsys,

		if (tmp->cntlid == ctrl->cntlid) {
			dev_err(ctrl->device,
				"Duplicate cntlid %u with %s, rejecting\n",
				ctrl->cntlid, dev_name(tmp->device));
				"Duplicate cntlid %u with %s, subsys %s, rejecting\n",
				ctrl->cntlid, dev_name(tmp->device),
				subsys->subnqn);
			return false;
		}

+2 −1
Original line number Diff line number Diff line
@@ -866,7 +866,7 @@ int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
	}
	if (ana_log_size > ctrl->ana_log_size) {
		nvme_mpath_stop(ctrl);
		kfree(ctrl->ana_log_buf);
		nvme_mpath_uninit(ctrl);
		ctrl->ana_log_buf = kmalloc(ana_log_size, GFP_KERNEL);
		if (!ctrl->ana_log_buf)
			return -ENOMEM;
@@ -886,4 +886,5 @@ void nvme_mpath_uninit(struct nvme_ctrl *ctrl)
{
	kfree(ctrl->ana_log_buf);
	ctrl->ana_log_buf = NULL;
	ctrl->ana_log_size = 0;
}
+1 −1
Original line number Diff line number Diff line
@@ -709,7 +709,7 @@ static inline bool nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
		return true;
	if (ctrl->ops->flags & NVME_F_FABRICS &&
	    ctrl->state == NVME_CTRL_DELETING)
		return true;
		return queue_live;
	return __nvme_check_ready(ctrl, rq, queue_live);
}
int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
+4 −1
Original line number Diff line number Diff line
@@ -166,6 +166,9 @@ static int nvme_zone_parse_entry(struct nvme_ns *ns,
	zone.len = ns->zsze;
	zone.capacity = nvme_lba_to_sect(ns, le64_to_cpu(entry->zcap));
	zone.start = nvme_lba_to_sect(ns, le64_to_cpu(entry->zslba));
	if (zone.cond == BLK_ZONE_COND_FULL)
		zone.wp = zone.start + zone.len;
	else
		zone.wp = nvme_lba_to_sect(ns, le64_to_cpu(entry->wp));

	return cb(&zone, idx, data);
+8 −1
Original line number Diff line number Diff line
@@ -922,7 +922,14 @@ static void nvmet_tcp_handle_req_failure(struct nvmet_tcp_queue *queue,
	size_t data_len = le32_to_cpu(req->cmd->common.dptr.sgl.length);
	int ret;

	if (!nvme_is_write(cmd->req.cmd) ||
	/*
	 * This command has not been processed yet, hence we are trying to
	 * figure out if there is still pending data left to receive. If
	 * we don't, we can simply prepare for the next pdu and bail out,
	 * otherwise we will need to prepare a buffer and receive the
	 * stale data before continuing forward.
	 */
	if (!nvme_is_write(cmd->req.cmd) || !data_len ||
	    data_len > cmd->req.port->inline_data_size) {
		nvmet_prepare_receive_pdu(queue);
		return;