mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
nvme fix for Linux 5.13
- correct the check for using the inline bio in nvmet (Chaitanya Kulkarni) - demote unsupported command warnings (Chaitanya Kulkarni) - fix corruption due to double initializing ANA state (me, Hou Pu) - reset ns->file when open fails (Daniel Wagner) - fix a NULL deref when SEND is completed with error in nvmet-rdma (Michal Kalderon) -----BEGIN PGP SIGNATURE----- iQI/BAABCgApFiEEgdbnc3r/njty3Iq9D55TZVIEUYMFAmCdW5cLHGhjaEBsc3Qu ZGUACgkQD55TZVIEUYNizRAAomAnNvWi6i/Y/4eYfPeEk31jImL4izV+L4n5LS86 /l8uacsZbtZZjIkUtDP3yjSKy4GbCQQVZHYVeH582vr6VKXztGKgGeckm1HRHUfc 9cV8fQ3Yx8OdYO7SoO7IAhwkOYNNYoiS3fFFPVLp/UlimtahpDzywum2tX05fsLz 1ucJfFwu9edxJfh1/uNKsXbkoBIXd+2NtdpycYqOjrVYTMNwQOvFq7P+Kd/ETDIU mFLeiY1b3BwbUUIDADz7QyTL5Ajk1bcXXLVudBrNdy0jg4Bfvzhn7vxBLwYUFAzK pX54dr8+GQhBqUzrqdRSLg4nfG9mpN+yI5RtqBcxVsGEkRU4w3XABTPgP5MtBQMr nGcy82KNVG3UA0jAe4wEmlr3tadlTtuH9O7aB+jEsDJIMo4S6SBl5ibsVqKyXFHb otYto+I9SpjJC5nRJXaFDqmI1pEX0mwmpDIek3YM3ovTzlLbKswBlDdHBJG9WM7H 3fo+OCj9aqj3D9SNBPD6blqBGUNsf+iPMryPxKCK+wQK6RpF9UQfyEvjVGneTx1+ xgjvem8pSipxsh3p/mz7Ktemqrx5oKSOvq6+jBcYRJbrBfRf5z3XLYn3noC/EAL6 RHAKbp0WKhlj2N/wf7pirf/+wkpXlLmpqtdaskpZWkdWT+xexqUITL8eb81RB/Ra Tew= =ZwLd -----END PGP SIGNATURE----- Merge tag 'nvme-5.13-2021-05-13' of git://git.infradead.org/nvme into block-5.13 Pull NVMe fixes from Christoph: "nvme fix for Linux 5.13 - correct the check for using the inline bio in nvmet (Chaitanya Kulkarni) - demote unsupported command warnings (Chaitanya Kulkarni) - fix corruption due to double initializing ANA state (me, Hou Pu) - reset ns->file when open fails (Daniel Wagner) - fix a NULL deref when SEND is completed with error in nvmet-rdma (Michal Kalderon)" * tag 'nvme-5.13-2021-05-13' of git://git.infradead.org/nvme: nvmet: use new ana_log_size instead the old one nvmet: seset ns->file when open fails nvmet: demote fabrics cmd parse err msg to debug nvmet: use helper to remove the duplicate code nvmet: demote discovery cmd parse err msg to debug nvmet-rdma: Fix NULL deref when SEND is completed with error nvmet: fix inline bio check for passthru nvmet: fix inline bio check for bdev-ns nvme-multipath: fix double initialization of ANA state
This commit is contained in:
commit
6bdf2fbc48
@ -2901,7 +2901,7 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
|
||||
ctrl->hmmaxd = le16_to_cpu(id->hmmaxd);
|
||||
}
|
||||
|
||||
ret = nvme_mpath_init(ctrl, id);
|
||||
ret = nvme_mpath_init_identify(ctrl, id);
|
||||
if (ret < 0)
|
||||
goto out_free;
|
||||
|
||||
@ -4364,6 +4364,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
|
||||
min(default_ps_max_latency_us, (unsigned long)S32_MAX));
|
||||
|
||||
nvme_fault_inject_init(&ctrl->fault_inject, dev_name(ctrl->device));
|
||||
nvme_mpath_init_ctrl(ctrl);
|
||||
|
||||
return 0;
|
||||
out_free_name:
|
||||
|
@ -781,9 +781,18 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
|
||||
put_disk(head->disk);
|
||||
}
|
||||
|
||||
int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
|
||||
void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl)
|
||||
{
|
||||
int error;
|
||||
mutex_init(&ctrl->ana_lock);
|
||||
timer_setup(&ctrl->anatt_timer, nvme_anatt_timeout, 0);
|
||||
INIT_WORK(&ctrl->ana_work, nvme_ana_work);
|
||||
}
|
||||
|
||||
int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
|
||||
{
|
||||
size_t max_transfer_size = ctrl->max_hw_sectors << SECTOR_SHIFT;
|
||||
size_t ana_log_size;
|
||||
int error = 0;
|
||||
|
||||
/* check if multipath is enabled and we have the capability */
|
||||
if (!multipath || !ctrl->subsys ||
|
||||
@ -795,37 +804,31 @@ int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
|
||||
ctrl->nanagrpid = le32_to_cpu(id->nanagrpid);
|
||||
ctrl->anagrpmax = le32_to_cpu(id->anagrpmax);
|
||||
|
||||
mutex_init(&ctrl->ana_lock);
|
||||
timer_setup(&ctrl->anatt_timer, nvme_anatt_timeout, 0);
|
||||
ctrl->ana_log_size = sizeof(struct nvme_ana_rsp_hdr) +
|
||||
ctrl->nanagrpid * sizeof(struct nvme_ana_group_desc);
|
||||
ctrl->ana_log_size += ctrl->max_namespaces * sizeof(__le32);
|
||||
|
||||
if (ctrl->ana_log_size > ctrl->max_hw_sectors << SECTOR_SHIFT) {
|
||||
ana_log_size = sizeof(struct nvme_ana_rsp_hdr) +
|
||||
ctrl->nanagrpid * sizeof(struct nvme_ana_group_desc) +
|
||||
ctrl->max_namespaces * sizeof(__le32);
|
||||
if (ana_log_size > max_transfer_size) {
|
||||
dev_err(ctrl->device,
|
||||
"ANA log page size (%zd) larger than MDTS (%d).\n",
|
||||
ctrl->ana_log_size,
|
||||
ctrl->max_hw_sectors << SECTOR_SHIFT);
|
||||
"ANA log page size (%zd) larger than MDTS (%zd).\n",
|
||||
ana_log_size, max_transfer_size);
|
||||
dev_err(ctrl->device, "disabling ANA support.\n");
|
||||
return 0;
|
||||
goto out_uninit;
|
||||
}
|
||||
|
||||
INIT_WORK(&ctrl->ana_work, nvme_ana_work);
|
||||
kfree(ctrl->ana_log_buf);
|
||||
ctrl->ana_log_buf = kmalloc(ctrl->ana_log_size, GFP_KERNEL);
|
||||
if (!ctrl->ana_log_buf) {
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
if (ana_log_size > ctrl->ana_log_size) {
|
||||
nvme_mpath_stop(ctrl);
|
||||
kfree(ctrl->ana_log_buf);
|
||||
ctrl->ana_log_buf = kmalloc(ana_log_size, GFP_KERNEL);
|
||||
if (!ctrl->ana_log_buf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ctrl->ana_log_size = ana_log_size;
|
||||
error = nvme_read_ana_log(ctrl);
|
||||
if (error)
|
||||
goto out_free_ana_log_buf;
|
||||
goto out_uninit;
|
||||
return 0;
|
||||
out_free_ana_log_buf:
|
||||
kfree(ctrl->ana_log_buf);
|
||||
ctrl->ana_log_buf = NULL;
|
||||
out:
|
||||
|
||||
out_uninit:
|
||||
nvme_mpath_uninit(ctrl);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -712,7 +712,8 @@ void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl);
|
||||
int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head);
|
||||
void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id);
|
||||
void nvme_mpath_remove_disk(struct nvme_ns_head *head);
|
||||
int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id);
|
||||
int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id);
|
||||
void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl);
|
||||
void nvme_mpath_uninit(struct nvme_ctrl *ctrl);
|
||||
void nvme_mpath_stop(struct nvme_ctrl *ctrl);
|
||||
bool nvme_mpath_clear_current_path(struct nvme_ns *ns);
|
||||
@ -780,7 +781,10 @@ static inline void nvme_mpath_check_last_path(struct nvme_ns *ns)
|
||||
static inline void nvme_trace_bio_complete(struct request *req)
|
||||
{
|
||||
}
|
||||
static inline int nvme_mpath_init(struct nvme_ctrl *ctrl,
|
||||
static inline void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl)
|
||||
{
|
||||
}
|
||||
static inline int nvme_mpath_init_identify(struct nvme_ctrl *ctrl,
|
||||
struct nvme_id_ctrl *id)
|
||||
{
|
||||
if (ctrl->subsys->cmic & NVME_CTRL_CMIC_ANA)
|
||||
|
@ -975,10 +975,7 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req)
|
||||
case nvme_admin_keep_alive:
|
||||
req->execute = nvmet_execute_keep_alive;
|
||||
return 0;
|
||||
default:
|
||||
return nvmet_report_invalid_opcode(req);
|
||||
}
|
||||
|
||||
pr_debug("unhandled cmd %d on qid %d\n", cmd->common.opcode,
|
||||
req->sq->qid);
|
||||
req->error_loc = offsetof(struct nvme_common_command, opcode);
|
||||
return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ u16 nvmet_parse_discovery_cmd(struct nvmet_req *req)
|
||||
req->execute = nvmet_execute_disc_identify;
|
||||
return 0;
|
||||
default:
|
||||
pr_err("unhandled cmd %d\n", cmd->common.opcode);
|
||||
pr_debug("unhandled cmd %d\n", cmd->common.opcode);
|
||||
req->error_loc = offsetof(struct nvme_common_command, opcode);
|
||||
return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ u16 nvmet_parse_fabrics_cmd(struct nvmet_req *req)
|
||||
req->execute = nvmet_execute_prop_get;
|
||||
break;
|
||||
default:
|
||||
pr_err("received unknown capsule type 0x%x\n",
|
||||
pr_debug("received unknown capsule type 0x%x\n",
|
||||
cmd->fabrics.fctype);
|
||||
req->error_loc = offsetof(struct nvmf_common_command, fctype);
|
||||
return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
|
||||
@ -284,13 +284,13 @@ u16 nvmet_parse_connect_cmd(struct nvmet_req *req)
|
||||
struct nvme_command *cmd = req->cmd;
|
||||
|
||||
if (!nvme_is_fabrics(cmd)) {
|
||||
pr_err("invalid command 0x%x on unconnected queue.\n",
|
||||
pr_debug("invalid command 0x%x on unconnected queue.\n",
|
||||
cmd->fabrics.opcode);
|
||||
req->error_loc = offsetof(struct nvme_common_command, opcode);
|
||||
return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
|
||||
}
|
||||
if (cmd->fabrics.fctype != nvme_fabrics_type_connect) {
|
||||
pr_err("invalid capsule type 0x%x on unconnected queue.\n",
|
||||
pr_debug("invalid capsule type 0x%x on unconnected queue.\n",
|
||||
cmd->fabrics.fctype);
|
||||
req->error_loc = offsetof(struct nvmf_common_command, fctype);
|
||||
return NVME_SC_INVALID_OPCODE | NVME_SC_DNR;
|
||||
|
@ -258,7 +258,7 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
|
||||
|
||||
sector = nvmet_lba_to_sect(req->ns, req->cmd->rw.slba);
|
||||
|
||||
if (req->transfer_len <= NVMET_MAX_INLINE_DATA_LEN) {
|
||||
if (nvmet_use_inline_bvec(req)) {
|
||||
bio = &req->b.inline_bio;
|
||||
bio_init(bio, req->inline_bvec, ARRAY_SIZE(req->inline_bvec));
|
||||
} else {
|
||||
|
@ -49,9 +49,11 @@ int nvmet_file_ns_enable(struct nvmet_ns *ns)
|
||||
|
||||
ns->file = filp_open(ns->device_path, flags, 0);
|
||||
if (IS_ERR(ns->file)) {
|
||||
pr_err("failed to open file %s: (%ld)\n",
|
||||
ns->device_path, PTR_ERR(ns->file));
|
||||
return PTR_ERR(ns->file);
|
||||
ret = PTR_ERR(ns->file);
|
||||
pr_err("failed to open file %s: (%d)\n",
|
||||
ns->device_path, ret);
|
||||
ns->file = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nvmet_file_ns_revalidate(ns);
|
||||
|
@ -616,4 +616,10 @@ static inline sector_t nvmet_lba_to_sect(struct nvmet_ns *ns, __le64 lba)
|
||||
return le64_to_cpu(lba) << (ns->blksize_shift - SECTOR_SHIFT);
|
||||
}
|
||||
|
||||
static inline bool nvmet_use_inline_bvec(struct nvmet_req *req)
|
||||
{
|
||||
return req->transfer_len <= NVMET_MAX_INLINE_DATA_LEN &&
|
||||
req->sg_cnt <= NVMET_MAX_INLINE_BIOVEC;
|
||||
}
|
||||
|
||||
#endif /* _NVMET_H */
|
||||
|
@ -194,7 +194,7 @@ static int nvmet_passthru_map_sg(struct nvmet_req *req, struct request *rq)
|
||||
if (req->sg_cnt > BIO_MAX_VECS)
|
||||
return -EINVAL;
|
||||
|
||||
if (req->transfer_len <= NVMET_MAX_INLINE_DATA_LEN) {
|
||||
if (nvmet_use_inline_bvec(req)) {
|
||||
bio = &req->p.inline_bio;
|
||||
bio_init(bio, req->inline_bvec, ARRAY_SIZE(req->inline_bvec));
|
||||
} else {
|
||||
|
@ -700,7 +700,7 @@ static void nvmet_rdma_send_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||
{
|
||||
struct nvmet_rdma_rsp *rsp =
|
||||
container_of(wc->wr_cqe, struct nvmet_rdma_rsp, send_cqe);
|
||||
struct nvmet_rdma_queue *queue = cq->cq_context;
|
||||
struct nvmet_rdma_queue *queue = wc->qp->qp_context;
|
||||
|
||||
nvmet_rdma_release_rsp(rsp);
|
||||
|
||||
@ -786,7 +786,7 @@ static void nvmet_rdma_write_data_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||
{
|
||||
struct nvmet_rdma_rsp *rsp =
|
||||
container_of(wc->wr_cqe, struct nvmet_rdma_rsp, write_cqe);
|
||||
struct nvmet_rdma_queue *queue = cq->cq_context;
|
||||
struct nvmet_rdma_queue *queue = wc->qp->qp_context;
|
||||
struct rdma_cm_id *cm_id = rsp->queue->cm_id;
|
||||
u16 status;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user