diff options
author | Keisuke Nishimura <keisuke.nishimura@inria.fr> | 2024-12-16 18:27:20 +0300 |
---|---|---|
committer | Keith Busch <kbusch@kernel.org> | 2025-01-13 01:11:29 +0300 |
commit | d4a95adeabc6b5a39405e49c6d5ed14dd83682c4 (patch) | |
tree | 61513dd862de05c5c1616790c226b140040659b1 | |
parent | e4a0a3058de85bc623f1ba90eec68f239d0a11b2 (diff) | |
download | linux-d4a95adeabc6b5a39405e49c6d5ed14dd83682c4.tar.xz |
nvme: Add error path for xa_store in nvme_init_effects
The xa_store() may fail due to memory allocation failure because there
is no guarantee that the index NVME_CSI_NVM is already used. This fix
introduces a new function to handle the error path.
Fixes: cc115cbe12d9 ("nvme: always initialize known command effects")
Signed-off-by: Keisuke Nishimura <keisuke.nishimura@inria.fr>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
-rw-r--r-- | drivers/nvme/host/core.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 4bdd5144af7c..2a0555856795 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3175,6 +3175,25 @@ free_data: return ret; } +static int nvme_init_effects_log(struct nvme_ctrl *ctrl, + u8 csi, struct nvme_effects_log **log) +{ + struct nvme_effects_log *effects, *old; + + effects = kzalloc(sizeof(*effects), GFP_KERNEL); + if (effects) + return -ENOMEM; + + old = xa_store(&ctrl->cels, csi, effects, GFP_KERNEL); + if (xa_is_err(old)) { + kfree(effects); + return xa_err(old); + } + + *log = effects; + return 0; +} + static void nvme_init_known_nvm_effects(struct nvme_ctrl *ctrl) { struct nvme_effects_log *log = ctrl->effects; @@ -3221,10 +3240,9 @@ static int nvme_init_effects(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) } if (!ctrl->effects) { - ctrl->effects = kzalloc(sizeof(*ctrl->effects), GFP_KERNEL); - if (!ctrl->effects) - return -ENOMEM; - xa_store(&ctrl->cels, NVME_CSI_NVM, ctrl->effects, GFP_KERNEL); + ret = nvme_init_effects_log(ctrl, NVME_CSI_NVM, &ctrl->effects); + if (ret < 0) + return ret; } nvme_init_known_nvm_effects(ctrl); |