]> Pileus Git - ~andy/linux/blobdiff - drivers/infiniband/ulp/srpt/ib_srpt.c
ib_srpt: Fix srpt_handle_cmd send_ioctx->ioctx_kref leak on exception
[~andy/linux] / drivers / infiniband / ulp / srpt / ib_srpt.c
index 6735b63d96f0fce09e89ca158b0b70ed1403a8ca..c3cb907d810559dcb09b834ee9b3c0649e6258e6 100644 (file)
@@ -1757,6 +1757,7 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
                       srp_cmd->tag);
                cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
                cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD;
+               kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
                goto send_sense;
        }
 
@@ -1764,15 +1765,19 @@ static int srpt_handle_cmd(struct srpt_rdma_ch *ch,
        cmd->data_direction = dir;
        unpacked_lun = srpt_unpack_lun((uint8_t *)&srp_cmd->lun,
                                       sizeof(srp_cmd->lun));
-       if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0)
+       if (transport_lookup_cmd_lun(cmd, unpacked_lun) < 0) {
+               kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
                goto send_sense;
+       }
        ret = transport_generic_allocate_tasks(cmd, srp_cmd->cdb);
-       if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
-               srpt_queue_status(cmd);
-       else if (cmd->se_cmd_flags & SCF_SCSI_CDB_EXCEPTION)
-               goto send_sense;
-       else
-               WARN_ON_ONCE(ret);
+       if (ret < 0) {
+               kref_put(&send_ioctx->kref, srpt_put_send_ioctx_kref);
+               if (cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) {
+                       srpt_queue_status(cmd);
+                       return 0;
+               } else
+                       goto send_sense;
+       }
 
        transport_handle_cdb_direct(cmd);
        return 0;