>From 34ef5e64fc205044e4326fcc5dcf2aa6b219763a Mon Sep 17 00:00:00 2001 From: Hu Tao Date: Mon, 19 Mar 2012 15:58:22 +0800 Subject: [PATCH] fix two problems in tmf This patch fix two problems in tmf: 1. race in virtscsi_tmf that the cmd may have been already freed when waking up from the completion 2. cmd leak if virtscsi_kick_cmd fails. Signed-off-by: Hu Tao --- drivers/scsi/virtio_scsi.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index efccd72..3b8a6e6 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -175,7 +175,8 @@ static void virtscsi_complete_free(void *buf) if (cmd->comp) complete_all(cmd->comp); - mempool_free(cmd, virtscsi_cmd_pool); + else + mempool_free(cmd, virtscsi_cmd_pool); } static void virtscsi_ctrl_done(struct virtqueue *vq) @@ -311,21 +312,23 @@ out: static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) { DECLARE_COMPLETION_ONSTACK(comp); - int ret; + int ret = FAILED; cmd->comp = ∁ ret = virtscsi_kick_cmd(vscsi, vscsi->ctrl_vq, cmd, sizeof cmd->req.tmf, sizeof cmd->resp.tmf, GFP_NOIO); if (ret < 0) - return FAILED; + goto failed; wait_for_completion(&comp); - if (cmd->resp.tmf.response != VIRTIO_SCSI_S_OK && - cmd->resp.tmf.response != VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) - return FAILED; + if (cmd->resp.tmf.response == VIRTIO_SCSI_S_OK || + cmd->resp.tmf.response == VIRTIO_SCSI_S_FUNCTION_SUCCEEDED) + ret = SUCCESS; - return SUCCESS; +failed: + mempool_free(cmd, virtscsi_cmd_pool); + return ret; } static int virtscsi_device_reset(struct scsi_cmnd *sc) -- 1.7.1