[PATCH] target: Move transport_lun_remove_cmd() into target_release_cmd_kref()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instead of invoking transport_lun_remove_cmd() before
transport_cmd_check_stop_to_fabric(), inline that function in
transport_release_cmd_kref(). This makes it easier to verify
that LUN removal occurs before a command is released.

Signed-off-by: Bart Van Assche <bart.vanassche@xxxxxxxxxxx>
---
 drivers/target/target_core_device.c    |  3 +++
 drivers/target/target_core_transport.c | 39 +++++++---------------------------
 2 files changed, 11 insertions(+), 31 deletions(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 88dad15..c803071 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -63,6 +63,9 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd, u32 unpacked_lun)
 	struct se_device *dev;
 	struct se_dev_entry *deve;
 
+	BUG_ON(se_cmd->lun_ref_active);
+	BUG_ON(list_empty(&se_cmd->se_cmd_list));
+
 	if (unpacked_lun >= TRANSPORT_MAX_LUNS_PER_TPG)
 		return TCM_NON_EXISTENT_LUN;
 
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 0de29d8..675123e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -579,15 +579,9 @@ static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists,
 	if (write_pending)
 		cmd->t_state = TRANSPORT_WRITE_PENDING;
 
-	if (remove_from_lists) {
+	if (remove_from_lists)
 		target_remove_from_state_list(cmd);
 
-		/*
-		 * Clear struct se_cmd->se_lun before the handoff to FE.
-		 */
-		cmd->se_lun = NULL;
-	}
-
 	/*
 	 * Determine if frontend context caller is requesting the stopping of
 	 * this command for frontend exceptions.
@@ -628,21 +622,8 @@ static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd)
 	return transport_cmd_check_stop(cmd, true, false);
 }
 
-static void transport_lun_remove_cmd(struct se_cmd *cmd)
-{
-	struct se_lun *lun = cmd->se_lun;
-
-	if (!lun)
-		return;
-
-	if (cmpxchg(&cmd->lun_ref_active, true, false))
-		percpu_ref_put(&lun->lun_ref);
-}
-
 void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
 {
-	if (cmd->se_cmd_flags & SCF_SE_LUN_CMD)
-		transport_lun_remove_cmd(cmd);
 	/*
 	 * Allow the fabric driver to unmap any resources before
 	 * releasing the descriptor via TFO->release_cmd()
@@ -1172,6 +1153,8 @@ void transport_init_se_cmd(
 
 	cmd->se_tfo = tfo;
 	cmd->se_sess = se_sess;
+	cmd->se_lun = NULL;
+	cmd->lun_ref_active = false;
 	cmd->data_length = data_length;
 	cmd->data_direction = data_direction;
 	cmd->sam_task_attr = task_attr;
@@ -1720,7 +1703,6 @@ void transport_generic_request_failure(struct se_cmd *cmd,
 		goto queue_full;
 
 check_stop:
-	transport_lun_remove_cmd(cmd);
 	if (!transport_cmd_check_stop_to_fabric(cmd))
 		;
 	return;
@@ -1972,7 +1954,6 @@ out:
 		transport_handle_queue_full(cmd, cmd->se_dev);
 		return;
 	}
-	transport_lun_remove_cmd(cmd);
 	transport_cmd_check_stop_to_fabric(cmd);
 }
 
@@ -2047,7 +2028,6 @@ static void target_complete_ok_work(struct work_struct *work)
 		if (ret == -EAGAIN || ret == -ENOMEM)
 			goto queue_full;
 
-		transport_lun_remove_cmd(cmd);
 		transport_cmd_check_stop_to_fabric(cmd);
 		return;
 	}
@@ -2071,7 +2051,6 @@ static void target_complete_ok_work(struct work_struct *work)
 			if (ret == -EAGAIN || ret == -ENOMEM)
 				goto queue_full;
 
-			transport_lun_remove_cmd(cmd);
 			transport_cmd_check_stop_to_fabric(cmd);
 			return;
 		}
@@ -2097,7 +2076,6 @@ queue_rsp:
 			if (ret == -EAGAIN || ret == -ENOMEM)
 				goto queue_full;
 
-			transport_lun_remove_cmd(cmd);
 			transport_cmd_check_stop_to_fabric(cmd);
 			return;
 		}
@@ -2140,7 +2118,6 @@ queue_rsp:
 		break;
 	}
 
-	transport_lun_remove_cmd(cmd);
 	transport_cmd_check_stop_to_fabric(cmd);
 	return;
 
@@ -2464,9 +2441,6 @@ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
 			spin_unlock_irqrestore(&cmd->t_state_lock, flags);
 		}
 
-		if (cmd->se_lun)
-			transport_lun_remove_cmd(cmd);
-
 		ret = transport_put_cmd(cmd);
 	}
 	return ret;
@@ -2512,12 +2486,17 @@ static void target_release_cmd_kref(struct kref *kref)
 {
 	struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
 	struct se_session *se_sess = se_cmd->se_sess;
+	struct se_lun *lun = se_cmd->se_lun;
 
 	if (list_empty(&se_cmd->se_cmd_list)) {
 		spin_unlock(&se_sess->sess_cmd_lock);
 		se_cmd->se_tfo->release_cmd(se_cmd);
 		return;
 	}
+
+	if (lun && se_cmd->lun_ref_active)
+		percpu_ref_put(&lun->lun_ref);
+
 	if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
 		spin_unlock(&se_sess->sess_cmd_lock);
 		complete(&se_cmd->cmd_wait_comp);
@@ -3010,8 +2989,6 @@ void transport_send_task_abort(struct se_cmd *cmd)
 	}
 	cmd->scsi_status = SAM_STAT_TASK_ABORTED;
 
-	transport_lun_remove_cmd(cmd);
-
 	pr_debug("Setting SAM_STAT_TASK_ABORTED status for CDB: 0x%02x, ITT: 0x%08llx\n",
 		 cmd->t_task_cdb[0], cmd->tag);
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux