On 12/17/2013 09:06 PM, Nicholas A. Bellinger wrote: > On Tue, 2013-12-17 at 09:18 +0100, Hannes Reinecke wrote: >> Add infrastructure for referrals. >> >> Signed-off-by: Hannes Reinecke <hare@xxxxxxx> >> --- >> drivers/target/target_core_alua.c | 153 ++++++++++++++++++++++++++++++++++ >> drivers/target/target_core_alua.h | 4 +- >> drivers/target/target_core_configfs.c | 9 +- >> drivers/target/target_core_device.c | 2 + >> drivers/target/target_core_sbc.c | 5 +- >> drivers/target/target_core_spc.c | 20 +++++ >> include/scsi/scsi.h | 1 + >> include/target/target_core_base.h | 18 ++++ >> 8 files changed, 209 insertions(+), 3 deletions(-) >> > > Applied, with one comment below.. > >> diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c >> index 01f0c71..dbfbf14 100644 >> --- a/drivers/target/target_core_alua.c >> +++ b/drivers/target/target_core_alua.c >> @@ -58,6 +58,75 @@ static LIST_HEAD(lu_gps_list); >> struct t10_alua_lu_gp *default_lu_gp; >> >> /* >> + * REPORT REFERRALS >> + * >> + * See sbc3r35 section 5.23 >> + */ >> +sense_reason_t >> +target_emulate_report_referrals(struct se_cmd *cmd) >> +{ >> + struct se_device *dev = cmd->se_dev; >> + struct t10_alua_lba_map *map; >> + struct t10_alua_lba_map_member *map_mem; >> + unsigned char *buf; >> + u32 rd_len = 0, off; >> + >> + if (cmd->data_length < 4) { >> + pr_warn("REPORT REFERRALS allocation length %u too" >> + " small\n", cmd->data_length); >> + return TCM_INVALID_CDB_FIELD; >> + } >> + >> + buf = transport_kmap_data_sg(cmd); >> + if (!buf) >> + return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; >> + >> + off = 4; >> + spin_lock(&dev->t10_alua.lba_map_lock); >> + if (list_empty(&dev->t10_alua.lba_map_list)) { >> + spin_unlock(&dev->t10_alua.lba_map_lock); >> + transport_kunmap_data_sg(cmd); >> + >> + return TCM_UNSUPPORTED_SCSI_OPCODE; >> + } >> + >> + list_for_each_entry(map, &dev->t10_alua.lba_map_list, >> + lba_map_list) { >> + int desc_num = off + 3; >> + int pg_num; >> + >> + off += 4; >> + put_unaligned_be64(map->lba_map_first_lba, &buf[off]); >> + off += 8; >> + put_unaligned_be64(map->lba_map_last_lba, &buf[off]); >> + off += 8; >> + rd_len += 20; >> + pg_num = 0; >> + list_for_each_entry(map_mem, &map->lba_map_mem_list, >> + lba_map_mem_list) { >> + buf[off++] = map_mem->lba_map_mem_alua_state & 0x0f; >> + off++; >> + buf[off++] = (map_mem->lba_map_mem_alua_pg_id >> 8) & 0xff; >> + buf[off++] = (map_mem->lba_map_mem_alua_pg_id & 0xff); >> + rd_len += 4; >> + pg_num++; >> + } >> + buf[desc_num] = pg_num; >> + } >> + spin_unlock(&dev->t10_alua.lba_map_lock); >> + > > The above loop needs a check based on cmd->data_length to not overflow > buf here.. > > Care to send an incremental patch for this..? > On its way. Alongside a patch for the inquiry buffer size. Cheers, Hannes -- Dr. Hannes Reinecke zSeries & Storage hare@xxxxxxx +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html