mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 16:41:25 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target fixes from Nicholas Bellinger: "This contains a v4.2-rc specific RCU module unload regression bug-fix, a long-standing iscsi-target bug-fix for duplicate target_xfer_tags during NOP processing from Alexei, and two more small REPORT_LUNs emulation related patches to make Solaris FC host LUN scanning happy from Roland. There is also one patch not included that allows target-core to limit the number of fabric driver SGLs per I/O request using residuals, that is currently required as a work-around for FC hosts which don't honor EVPD block-limits settings. At this point, it will most likely become for-next material" * git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: target: Fix handling of small allocation lengths in REPORT LUNS target: REPORT LUNS should return LUN 0 even for dynamic ACLs target/iscsi: Fix double free of a TUR followed by a solicited NOPOUT target: Perform RCU callback barrier before backend/fabric unload
This commit is contained in:
commit
3243f50b0c
4 changed files with 44 additions and 23 deletions
|
@ -968,9 +968,9 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
|
||||||
cmd->cmd_flags |= ICF_NON_IMMEDIATE_UNSOLICITED_DATA;
|
cmd->cmd_flags |= ICF_NON_IMMEDIATE_UNSOLICITED_DATA;
|
||||||
|
|
||||||
conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
|
conn->sess->init_task_tag = cmd->init_task_tag = hdr->itt;
|
||||||
if (hdr->flags & ISCSI_FLAG_CMD_READ) {
|
if (hdr->flags & ISCSI_FLAG_CMD_READ)
|
||||||
cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
|
cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
|
||||||
} else if (hdr->flags & ISCSI_FLAG_CMD_WRITE)
|
else
|
||||||
cmd->targ_xfer_tag = 0xFFFFFFFF;
|
cmd->targ_xfer_tag = 0xFFFFFFFF;
|
||||||
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
|
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
|
||||||
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
|
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
|
||||||
|
|
|
@ -457,8 +457,15 @@ void target_unregister_template(const struct target_core_fabric_ops *fo)
|
||||||
if (!strcmp(t->tf_ops->name, fo->name)) {
|
if (!strcmp(t->tf_ops->name, fo->name)) {
|
||||||
BUG_ON(atomic_read(&t->tf_access_cnt));
|
BUG_ON(atomic_read(&t->tf_access_cnt));
|
||||||
list_del(&t->tf_list);
|
list_del(&t->tf_list);
|
||||||
|
mutex_unlock(&g_tf_lock);
|
||||||
|
/*
|
||||||
|
* Wait for any outstanding fabric se_deve_entry->rcu_head
|
||||||
|
* callbacks to complete post kfree_rcu(), before allowing
|
||||||
|
* fabric driver unload of TFO->module to proceed.
|
||||||
|
*/
|
||||||
|
rcu_barrier();
|
||||||
kfree(t);
|
kfree(t);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&g_tf_lock);
|
mutex_unlock(&g_tf_lock);
|
||||||
|
|
|
@ -84,8 +84,16 @@ void target_backend_unregister(const struct target_backend_ops *ops)
|
||||||
list_for_each_entry(tb, &backend_list, list) {
|
list_for_each_entry(tb, &backend_list, list) {
|
||||||
if (tb->ops == ops) {
|
if (tb->ops == ops) {
|
||||||
list_del(&tb->list);
|
list_del(&tb->list);
|
||||||
|
mutex_unlock(&backend_mutex);
|
||||||
|
/*
|
||||||
|
* Wait for any outstanding backend driver ->rcu_head
|
||||||
|
* callbacks to complete post TBO->free_device() ->
|
||||||
|
* call_rcu(), before allowing backend driver module
|
||||||
|
* unload of target_backend_ops->owner to proceed.
|
||||||
|
*/
|
||||||
|
rcu_barrier();
|
||||||
kfree(tb);
|
kfree(tb);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mutex_unlock(&backend_mutex);
|
mutex_unlock(&backend_mutex);
|
||||||
|
|
|
@ -1203,17 +1203,13 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd)
|
||||||
struct se_dev_entry *deve;
|
struct se_dev_entry *deve;
|
||||||
struct se_session *sess = cmd->se_sess;
|
struct se_session *sess = cmd->se_sess;
|
||||||
struct se_node_acl *nacl;
|
struct se_node_acl *nacl;
|
||||||
|
struct scsi_lun slun;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
u32 lun_count = 0, offset = 8;
|
u32 lun_count = 0, offset = 8;
|
||||||
|
__be32 len;
|
||||||
if (cmd->data_length < 16) {
|
|
||||||
pr_warn("REPORT LUNS allocation length %u too small\n",
|
|
||||||
cmd->data_length);
|
|
||||||
return TCM_INVALID_CDB_FIELD;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = transport_kmap_data_sg(cmd);
|
buf = transport_kmap_data_sg(cmd);
|
||||||
if (!buf)
|
if (cmd->data_length && !buf)
|
||||||
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1221,11 +1217,9 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd)
|
||||||
* coming via a target_core_mod PASSTHROUGH op, and not through
|
* coming via a target_core_mod PASSTHROUGH op, and not through
|
||||||
* a $FABRIC_MOD. In that case, report LUN=0 only.
|
* a $FABRIC_MOD. In that case, report LUN=0 only.
|
||||||
*/
|
*/
|
||||||
if (!sess) {
|
if (!sess)
|
||||||
int_to_scsilun(0, (struct scsi_lun *)&buf[offset]);
|
|
||||||
lun_count = 1;
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
nacl = sess->se_node_acl;
|
nacl = sess->se_node_acl;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
@ -1236,10 +1230,12 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd)
|
||||||
* See SPC2-R20 7.19.
|
* See SPC2-R20 7.19.
|
||||||
*/
|
*/
|
||||||
lun_count++;
|
lun_count++;
|
||||||
if ((offset + 8) > cmd->data_length)
|
if (offset >= cmd->data_length)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]);
|
int_to_scsilun(deve->mapped_lun, &slun);
|
||||||
|
memcpy(buf + offset, &slun,
|
||||||
|
min(8u, cmd->data_length - offset));
|
||||||
offset += 8;
|
offset += 8;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
@ -1248,12 +1244,22 @@ sense_reason_t spc_emulate_report_luns(struct se_cmd *cmd)
|
||||||
* See SPC3 r07, page 159.
|
* See SPC3 r07, page 159.
|
||||||
*/
|
*/
|
||||||
done:
|
done:
|
||||||
lun_count *= 8;
|
/*
|
||||||
buf[0] = ((lun_count >> 24) & 0xff);
|
* If no LUNs are accessible, report virtual LUN 0.
|
||||||
buf[1] = ((lun_count >> 16) & 0xff);
|
*/
|
||||||
buf[2] = ((lun_count >> 8) & 0xff);
|
if (lun_count == 0) {
|
||||||
buf[3] = (lun_count & 0xff);
|
int_to_scsilun(0, &slun);
|
||||||
transport_kunmap_data_sg(cmd);
|
if (cmd->data_length > 8)
|
||||||
|
memcpy(buf + offset, &slun,
|
||||||
|
min(8u, cmd->data_length - offset));
|
||||||
|
lun_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf) {
|
||||||
|
len = cpu_to_be32(lun_count * 8);
|
||||||
|
memcpy(buf, &len, min_t(int, sizeof len, cmd->data_length));
|
||||||
|
transport_kunmap_data_sg(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8);
|
target_complete_cmd_with_length(cmd, GOOD, 8 + lun_count * 8);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue