Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2fb78e89 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
 "A set of fixes for this series. This contains:

   - Set of fixes for the nvme target code

   - A revert of patch from this merge window, causing a regression with
     WRITE_SAME on iSCSI targets at least.

   - A fix for a use-after-free in the new O_DIRECT bdev code.

   - Two fixes for the xen-blkfront driver"

* 'for-linus' of git://git.kernel.dk/linux-block:
  Revert "sd: remove __data_len hack for WRITE SAME"
  nvme-fc: use blk_rq_nr_phys_segments
  nvmet-rdma: Fix missing dma sync to nvme data structures
  nvmet: Call fatal_error from keep-alive timout expiration
  nvmet: cancel fatal error and flush async work before free controller
  nvmet: delete controllers deletion upon subsystem release
  nvmet_fc: correct logic in disconnect queue LS handling
  block: fix use after free in __blkdev_direct_IO
  xen-blkfront: correct maximum segment accounting
  xen-blkfront: feature flags handling adjustments
parents dd3b9f25 c14024db
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -197,13 +197,13 @@ struct blkfront_info
	/* Number of pages per ring buffer. */
	unsigned int nr_ring_pages;
	struct request_queue *rq;
	unsigned int feature_flush;
	unsigned int feature_fua;
	unsigned int feature_flush:1;
	unsigned int feature_fua:1;
	unsigned int feature_discard:1;
	unsigned int feature_secdiscard:1;
	unsigned int feature_persistent:1;
	unsigned int discard_granularity;
	unsigned int discard_alignment;
	unsigned int feature_persistent:1;
	/* Number of 4KB segments handled */
	unsigned int max_indirect_segments;
	int is_ready;
@@ -2223,7 +2223,7 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo)
	}
	else
		grants = info->max_indirect_segments;
	psegs = grants / GRANTS_PER_PSEG;
	psegs = DIV_ROUND_UP(grants, GRANTS_PER_PSEG);

	err = fill_grant_buffer(rinfo,
				(grants + INDIRECT_GREFS(grants)) * BLK_RING_SIZE(info));
@@ -2323,13 +2323,16 @@ static void blkfront_gather_backend_features(struct blkfront_info *info)
		blkfront_setup_discard(info);

	info->feature_persistent =
		xenbus_read_unsigned(info->xbdev->otherend,
		!!xenbus_read_unsigned(info->xbdev->otherend,
				       "feature-persistent", 0);

	indirect_segments = xenbus_read_unsigned(info->xbdev->otherend,
					"feature-max-indirect-segments", 0);
	info->max_indirect_segments = min(indirect_segments,
					  xen_blkif_max_segments);
	if (indirect_segments > xen_blkif_max_segments)
		indirect_segments = xen_blkif_max_segments;
	if (indirect_segments <= BLKIF_MAX_SEGMENTS_PER_REQUEST)
		indirect_segments = 0;
	info->max_indirect_segments = indirect_segments;
}

/*
@@ -2652,6 +2655,9 @@ static int __init xlblk_init(void)
	if (!xen_domain())
		return -ENODEV;

	if (xen_blkif_max_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
		xen_blkif_max_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;

	if (xen_blkif_max_ring_order > XENBUS_MAX_RING_GRANT_ORDER) {
		pr_info("Invalid max_ring_order (%d), will use default max: %d.\n",
			xen_blkif_max_ring_order, XENBUS_MAX_RING_GRANT_ORDER);
+3 −3
Original line number Diff line number Diff line
@@ -1663,13 +1663,13 @@ nvme_fc_map_data(struct nvme_fc_ctrl *ctrl, struct request *rq,
		return 0;

	freq->sg_table.sgl = freq->first_sgl;
	ret = sg_alloc_table_chained(&freq->sg_table, rq->nr_phys_segments,
			freq->sg_table.sgl);
	ret = sg_alloc_table_chained(&freq->sg_table,
			blk_rq_nr_phys_segments(rq), freq->sg_table.sgl);
	if (ret)
		return -ENOMEM;

	op->nents = blk_rq_map_sg(rq->q, rq, freq->sg_table.sgl);
	WARN_ON(op->nents > rq->nr_phys_segments);
	WARN_ON(op->nents > blk_rq_nr_phys_segments(rq));
	dir = (rq_data_dir(rq) == WRITE) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
	freq->sg_cnt = fc_dma_map_sg(ctrl->lport->dev, freq->sg_table.sgl,
				op->nents, dir);
+1 −0
Original line number Diff line number Diff line
@@ -631,6 +631,7 @@ static void nvmet_subsys_release(struct config_item *item)
{
	struct nvmet_subsys *subsys = to_subsys(item);

	nvmet_subsys_del_ctrls(subsys);
	nvmet_subsys_put(subsys);
}

+14 −1
Original line number Diff line number Diff line
@@ -200,7 +200,7 @@ static void nvmet_keep_alive_timer(struct work_struct *work)
	pr_err("ctrl %d keep-alive timer (%d seconds) expired!\n",
		ctrl->cntlid, ctrl->kato);

	ctrl->ops->delete_ctrl(ctrl);
	nvmet_ctrl_fatal_error(ctrl);
}

static void nvmet_start_keep_alive_timer(struct nvmet_ctrl *ctrl)
@@ -816,6 +816,9 @@ static void nvmet_ctrl_free(struct kref *ref)
	list_del(&ctrl->subsys_entry);
	mutex_unlock(&subsys->lock);

	flush_work(&ctrl->async_event_work);
	cancel_work_sync(&ctrl->fatal_err_work);

	ida_simple_remove(&subsys->cntlid_ida, ctrl->cntlid);
	nvmet_subsys_put(subsys);

@@ -935,6 +938,16 @@ static void nvmet_subsys_free(struct kref *ref)
	kfree(subsys);
}

void nvmet_subsys_del_ctrls(struct nvmet_subsys *subsys)
{
	struct nvmet_ctrl *ctrl;

	mutex_lock(&subsys->lock);
	list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
		ctrl->ops->delete_ctrl(ctrl);
	mutex_unlock(&subsys->lock);
}

void nvmet_subsys_put(struct nvmet_subsys *subsys)
{
	kref_put(&subsys->ref, nvmet_subsys_free);
+22 −14
Original line number Diff line number Diff line
@@ -1314,7 +1314,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
			(struct fcnvme_ls_disconnect_rqst *)iod->rqstbuf;
	struct fcnvme_ls_disconnect_acc *acc =
			(struct fcnvme_ls_disconnect_acc *)iod->rspbuf;
	struct nvmet_fc_tgt_queue *queue;
	struct nvmet_fc_tgt_queue *queue = NULL;
	struct nvmet_fc_tgt_assoc *assoc;
	int ret = 0;
	bool del_assoc = false;
@@ -1348,7 +1348,18 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
		assoc = nvmet_fc_find_target_assoc(tgtport,
				be64_to_cpu(rqst->associd.association_id));
		iod->assoc = assoc;
		if (!assoc)
		if (assoc) {
			if (rqst->discon_cmd.scope ==
					FCNVME_DISCONN_CONNECTION) {
				queue = nvmet_fc_find_target_queue(tgtport,
						be64_to_cpu(
							rqst->discon_cmd.id));
				if (!queue) {
					nvmet_fc_tgt_a_put(assoc);
					ret = VERR_NO_CONN;
				}
			}
		} else
			ret = VERR_NO_ASSOC;
	}

@@ -1373,9 +1384,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
			FCNVME_LS_DISCONNECT);


	if (rqst->discon_cmd.scope == FCNVME_DISCONN_CONNECTION) {
		queue = nvmet_fc_find_target_queue(tgtport,
					be64_to_cpu(rqst->discon_cmd.id));
	/* are we to delete a Connection ID (queue) */
	if (queue) {
		int qid = queue->qid;

@@ -1388,7 +1397,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
		if (!qid)
			del_assoc = true;
	}
	}

	/* release get taken in nvmet_fc_find_target_assoc */
	nvmet_fc_tgt_a_put(iod->assoc);
Loading