Skip to content

Commit

Permalink
target: Return descriptor format sense data in case the LU spans 64bi…
Browse files Browse the repository at this point in the history
…t sectors

In case a LU spans 64bit sectors, fixed size sense data information
field is only 32 bits which means the sector information will be truncated.

Thus, if the LU spans 64bit sectors, use descriptor format sense data to
correctly report sector information.

Reported-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
  • Loading branch information
Sagi Grimberg authored and Nicholas Bellinger committed Jul 24, 2015
1 parent f5a8b3a commit 4e4937e
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 4 deletions.
5 changes: 5 additions & 0 deletions drivers/target/target_core_hba.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,8 @@ core_delete_hba(struct se_hba *hba)
kfree(hba);
return 0;
}

bool target_sense_desc_format(struct se_device *dev)
{
return dev->transport->get_blocks(dev) > U32_MAX;
}
12 changes: 9 additions & 3 deletions drivers/target/target_core_spc.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,12 @@ static int spc_modesense_control(struct se_cmd *cmd, u8 pc, u8 *p)
if (pc == 1)
goto out;

p[2] = 2;
/* GLTSD: No implicit save of log parameters */
p[2] = (1 << 1);
if (target_sense_desc_format(dev))
/* D_SENSE: Descriptor format sense data for 64bit sectors */
p[2] |= (1 << 2);

/*
* From spc4r23, 7.4.7 Control mode page
*
Expand Down Expand Up @@ -1144,6 +1149,7 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd)
unsigned char *rbuf;
u8 ua_asc = 0, ua_ascq = 0;
unsigned char buf[SE_SENSE_BUF];
bool desc_format = target_sense_desc_format(cmd->se_dev);

memset(buf, 0, SE_SENSE_BUF);

Expand All @@ -1158,10 +1164,10 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd)
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;

if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq))
scsi_build_sense_buffer(0, buf, UNIT_ATTENTION,
scsi_build_sense_buffer(desc_format, buf, UNIT_ATTENTION,
ua_asc, ua_ascq);
else
scsi_build_sense_buffer(0, buf, NO_SENSE, 0x0, 0x0);
scsi_build_sense_buffer(desc_format, buf, NO_SENSE, 0x0, 0x0);

memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length));
transport_kunmap_data_sg(cmd);
Expand Down
3 changes: 2 additions & 1 deletion drivers/target/target_core_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -2735,6 +2735,7 @@ static int translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason)
u8 *buffer = cmd->sense_buffer;
int r = (__force int)reason;
u8 asc, ascq;
bool desc_format = target_sense_desc_format(cmd->se_dev);

if (r < ARRAY_SIZE(sense_info_table) && sense_info_table[r].key)
si = &sense_info_table[r];
Expand All @@ -2754,7 +2755,7 @@ static int translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason)
ascq = si->ascq;
}

scsi_build_sense_buffer(0, buffer, si->key, asc, ascq);
scsi_build_sense_buffer(desc_format, buffer, si->key, asc, ascq);
if (si->add_sector_info)
return scsi_set_sense_information(buffer,
cmd->scsi_sense_length,
Expand Down
2 changes: 2 additions & 0 deletions include/target/target_core_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,6 @@ bool target_lun_is_rdonly(struct se_cmd *);
sense_reason_t passthrough_parse_cdb(struct se_cmd *cmd,
sense_reason_t (*exec_cmd)(struct se_cmd *cmd));

bool target_sense_desc_format(struct se_device *dev);

#endif /* TARGET_CORE_BACKEND_H */

0 comments on commit 4e4937e

Please sign in to comment.