@@ -611,6 +611,25 @@ static void scsiback_disconnect(struct vscsibk_info *info)
611611 xenbus_unmap_ring_vfree (info -> dev , info -> ring .sring );
612612}
613613
614+ /*
615+ * Send the error response for a request that did not reach the target core
616+ * and return its tag. Free the tag before the response drops the v2p
617+ * reference that keeps the session alive, and snapshot what the response
618+ * needs since returning the tag can let the slot be reused.
619+ */
620+ static void scsiback_resp_and_free (struct vscsibk_pend * pending_req ,
621+ int32_t result )
622+ {
623+ struct vscsibk_info * info = pending_req -> info ;
624+ struct v2p_entry * v2p = pending_req -> v2p ;
625+ struct se_session * se_sess = v2p -> tpg -> tpg_nexus -> tvn_se_sess ;
626+ u16 rqid = pending_req -> rqid ;
627+
628+ target_free_tag (se_sess , & pending_req -> se_cmd );
629+ scsiback_send_response (info , NULL , result , 0 , rqid );
630+ kref_put (& v2p -> kref , scsiback_free_translation_entry );
631+ }
632+
614633static void scsiback_device_action (struct vscsibk_pend * pending_req ,
615634 enum tcm_tmreq_table act , int tag )
616635{
@@ -639,7 +658,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
639658 return ;
640659
641660err :
642- scsiback_do_resp_with_sense ( NULL , err , 0 , pending_req );
661+ scsiback_resp_and_free ( pending_req , err );
643662}
644663
645664/*
@@ -792,9 +811,8 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info,
792811 case VSCSIIF_ACT_SCSI_CDB :
793812 if (scsiback_gnttab_data_map (& ring_req , pending_req )) {
794813 scsiback_fast_flush_area (pending_req );
795- scsiback_do_resp_with_sense (NULL ,
796- DID_ERROR << 16 , 0 , pending_req );
797- transport_generic_free_cmd (& pending_req -> se_cmd , 0 );
814+ scsiback_resp_and_free (pending_req ,
815+ DID_ERROR << 16 );
798816 } else {
799817 scsiback_cmd_exec (pending_req );
800818 }
@@ -808,9 +826,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info,
808826 break ;
809827 default :
810828 pr_err_ratelimited ("invalid request\n" );
811- scsiback_do_resp_with_sense (NULL , DID_ERROR << 16 , 0 ,
812- pending_req );
813- transport_generic_free_cmd (& pending_req -> se_cmd , 0 );
829+ scsiback_resp_and_free (pending_req , DID_ERROR << 16 );
814830 break ;
815831 }
816832
0 commit comments