lkml.org 
[lkml]   [2020]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.5 514/542] nvmet: fix dsm failure when payload does not match sgl descriptor
    Date
    From: Sagi Grimberg <sagi@grimberg.me>

    [ Upstream commit b716e6889c95f64ba32af492461f6cc9341f3f05 ]

    The host is allowed to pass the controller an sgl describing a buffer
    that is larger than the dsm payload itself, allow it when executing
    dsm.

    Reported-by: Dakshaja Uppalapati <dakshaja@chelsio.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>,
    Reviewed-by: Max Gurtovoy <maxg@mellanox.com>
    Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
    Signed-off-by: Keith Busch <kbusch@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/nvme/target/core.c | 11 +++++++++++
    drivers/nvme/target/io-cmd-bdev.c | 2 +-
    drivers/nvme/target/io-cmd-file.c | 2 +-
    drivers/nvme/target/nvmet.h | 1 +
    4 files changed, 14 insertions(+), 2 deletions(-)

    diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
    index 35810a0a8d212..461987f669c50 100644
    --- a/drivers/nvme/target/core.c
    +++ b/drivers/nvme/target/core.c
    @@ -939,6 +939,17 @@ bool nvmet_check_data_len(struct nvmet_req *req, size_t data_len)
    }
    EXPORT_SYMBOL_GPL(nvmet_check_data_len);

    +bool nvmet_check_data_len_lte(struct nvmet_req *req, size_t data_len)
    +{
    + if (unlikely(data_len > req->transfer_len)) {
    + req->error_loc = offsetof(struct nvme_common_command, dptr);
    + nvmet_req_complete(req, NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR);
    + return false;
    + }
    +
    + return true;
    +}
    +
    int nvmet_req_alloc_sgl(struct nvmet_req *req)
    {
    struct pci_dev *p2p_dev = NULL;
    diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
    index b6fca0e421ef1..ea0e596be15dc 100644
    --- a/drivers/nvme/target/io-cmd-bdev.c
    +++ b/drivers/nvme/target/io-cmd-bdev.c
    @@ -280,7 +280,7 @@ static void nvmet_bdev_execute_discard(struct nvmet_req *req)

    static void nvmet_bdev_execute_dsm(struct nvmet_req *req)
    {
    - if (!nvmet_check_data_len(req, nvmet_dsm_len(req)))
    + if (!nvmet_check_data_len_lte(req, nvmet_dsm_len(req)))
    return;

    switch (le32_to_cpu(req->cmd->dsm.attributes)) {
    diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c
    index caebfce066056..cd5670b83118f 100644
    --- a/drivers/nvme/target/io-cmd-file.c
    +++ b/drivers/nvme/target/io-cmd-file.c
    @@ -336,7 +336,7 @@ static void nvmet_file_dsm_work(struct work_struct *w)

    static void nvmet_file_execute_dsm(struct nvmet_req *req)
    {
    - if (!nvmet_check_data_len(req, nvmet_dsm_len(req)))
    + if (!nvmet_check_data_len_lte(req, nvmet_dsm_len(req)))
    return;
    INIT_WORK(&req->f.work, nvmet_file_dsm_work);
    schedule_work(&req->f.work);
    diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
    index 46df45e837c95..eda28b22a2c87 100644
    --- a/drivers/nvme/target/nvmet.h
    +++ b/drivers/nvme/target/nvmet.h
    @@ -374,6 +374,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
    struct nvmet_sq *sq, const struct nvmet_fabrics_ops *ops);
    void nvmet_req_uninit(struct nvmet_req *req);
    bool nvmet_check_data_len(struct nvmet_req *req, size_t data_len);
    +bool nvmet_check_data_len_lte(struct nvmet_req *req, size_t data_len);
    void nvmet_req_complete(struct nvmet_req *req, u16 status);
    int nvmet_req_alloc_sgl(struct nvmet_req *req);
    void nvmet_req_free_sgl(struct nvmet_req *req);
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-02-14 18:49    [W:4.048 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site