scsi: target: core: Move buffer clearing hack
authorMike Christie <michael.christie@oracle.com>
Thu, 28 Sep 2023 02:09:03 +0000 (21:09 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 13 Oct 2023 19:53:58 +0000 (15:53 -0400)
Move the hack to clear some buffers to transport_handle_cdb_direct() so we
can eventually merge transport_handle_cdb_direct() and target_submit().

This also fixes up the comment so it's clear it was only for udev and
reflects that the referenced function does not exist and we now allow more
than 1 page for control CDBs.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20230928020907.5730-4-michael.christie@oracle.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/target/target_core_transport.c

index a63f19b..3cb0aa7 100644 (file)
@@ -1592,6 +1592,27 @@ int transport_handle_cdb_direct(
         */
        core_alua_check_nonop_delay(cmd);
 
+       if (cmd->t_data_nents != 0) {
+               /*
+                * This is primarily a hack for udev and tcm loop which sends
+                * INQUIRYs with a single page and expects the data to be
+                * cleared.
+                */
+               if (!(cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
+                   cmd->data_direction == DMA_FROM_DEVICE) {
+                       struct scatterlist *sgl = cmd->t_data_sg;
+                       unsigned char *buf = NULL;
+
+                       BUG_ON(!sgl);
+
+                       buf = kmap_local_page(sg_page(sgl));
+                       if (buf) {
+                               memset(buf + sgl->offset, 0, sgl->length);
+                               kunmap_local(buf);
+                       }
+               }
+       }
+
        if (!cmd->se_lun) {
                dump_stack();
                pr_err("cmd->se_lun is NULL\n");
@@ -1795,34 +1816,6 @@ EXPORT_SYMBOL_GPL(target_submit_prep);
  */
 void target_submit(struct se_cmd *se_cmd)
 {
-       struct scatterlist *sgl = se_cmd->t_data_sg;
-       unsigned char *buf = NULL;
-
-       might_sleep();
-
-       if (se_cmd->t_data_nents != 0) {
-               BUG_ON(!sgl);
-               /*
-                * A work-around for tcm_loop as some userspace code via
-                * scsi-generic do not memset their associated read buffers,
-                * so go ahead and do that here for type non-data CDBs.  Also
-                * note that this is currently guaranteed to be a single SGL
-                * for this case by target core in target_setup_cmd_from_cdb()
-                * -> transport_generic_cmd_sequencer().
-                */
-               if (!(se_cmd->se_cmd_flags & SCF_SCSI_DATA_CDB) &&
-                    se_cmd->data_direction == DMA_FROM_DEVICE) {
-                       if (sgl)
-                               buf = kmap(sg_page(sgl)) + sgl->offset;
-
-                       if (buf) {
-                               memset(buf, 0, sgl->length);
-                               kunmap(sg_page(sgl));
-                       }
-               }
-
-       }
-
        transport_handle_cdb_direct(se_cmd);
 }
 EXPORT_SYMBOL_GPL(target_submit);