scst: Add force_close callback in target template (merge r4852 from trunk)

git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.2.x@6054 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Bart Van Assche
2015-02-10 13:45:50 +00:00
parent d0a1d3ae94
commit c0baa8b857
6 changed files with 89 additions and 33 deletions
+19
View File
@@ -3822,6 +3822,24 @@ out_err:
return;
}
static int iscsi_close_sess(struct scst_session *scst_sess)
{
struct iscsi_session *sess = scst_sess_get_tgt_priv(scst_sess);
struct iscsi_target *target = sess->target;
int res;
res = mutex_lock_interruptible(&target->target_mutex);
if (res)
goto out;
iscsi_sess_force_close(sess);
mutex_unlock(&target->target_mutex);
res = 0;
out:
return res;
}
static int iscsi_target_detect(struct scst_tgt_template *templ)
{
/* Nothing to do */
@@ -3869,6 +3887,7 @@ struct scst_tgt_template iscsi_template = {
.add_target = iscsi_sysfs_add_target,
.del_target = iscsi_sysfs_del_target,
.mgmt_cmd = iscsi_sysfs_mgmt_cmd,
.close_session = iscsi_close_sess,
.tgtt_optional_attributes = "IncomingUser, OutgoingUser",
.tgt_optional_attributes = "IncomingUser, OutgoingUser, allowed_portal",
#endif
-32
View File
@@ -540,37 +540,6 @@ static ssize_t iscsi_sess_reinstating_show(struct kobject *kobj,
static struct kobj_attribute iscsi_sess_attr_reinstating =
__ATTR(reinstating, S_IRUGO, iscsi_sess_reinstating_show, NULL);
static ssize_t iscsi_sess_force_close_store(struct kobject *kobj,
struct kobj_attribute *attr, const char *buf, size_t count)
{
int res;
struct scst_session *scst_sess;
struct iscsi_session *sess;
TRACE_ENTRY();
scst_sess = container_of(kobj, struct scst_session, sess_kobj);
sess = (struct iscsi_session *)scst_sess_get_tgt_priv(scst_sess);
if (mutex_lock_interruptible(&sess->target->target_mutex) != 0) {
res = -EINTR;
goto out;
}
iscsi_sess_force_close(sess);
mutex_unlock(&sess->target->target_mutex);
res = count;
out:
TRACE_EXIT_RES(res);
return res;
}
static struct kobj_attribute iscsi_sess_attr_force_close =
__ATTR(force_close, S_IWUSR, NULL, iscsi_sess_force_close_store);
const struct attribute *iscsi_sess_attrs[] = {
&iscsi_sess_attr_initial_r2t.attr,
&iscsi_sess_attr_immediate_data.attr,
@@ -583,7 +552,6 @@ const struct attribute *iscsi_sess_attrs[] = {
&iscsi_sess_attr_data_digest.attr,
&iscsi_attr_sess_sid.attr,
&iscsi_sess_attr_reinstating.attr,
&iscsi_sess_attr_force_close.attr,
NULL,
};
+16
View File
@@ -102,6 +102,7 @@ static int q2t_cut_cmd_data_head(struct q2t_cmd *cmd, unsigned int offset);
static void q2t_clear_tgt_db(struct q2t_tgt *tgt, bool immediately);
static void q2t_on_hw_pending_cmd_timeout(struct scst_cmd *scst_cmd);
static void q2t_unreg_sess(struct q2t_sess *sess);
static int q2t_close_session(struct scst_session *scst_sess);
static uint16_t q2t_get_scsi_transport_version(struct scst_tgt *scst_tgt);
static uint16_t q2t_get_phys_transport_version(struct scst_tgt *scst_tgt);
@@ -219,6 +220,7 @@ static struct scst_tgt_template tgt2x_template = {
.rdy_to_xfer = q2t_rdy_to_xfer,
.on_free_cmd = q2t_on_free_cmd,
.task_mgmt_fn_done = q2t_task_mgmt_fn_done,
.close_session = q2t_close_session,
.get_initiator_port_transport_id = q2t_get_initiator_port_transport_id,
.get_scsi_transport_version = q2t_get_scsi_transport_version,
.get_phys_transport_version = q2t_get_phys_transport_version,
@@ -867,6 +869,20 @@ out:
return;
}
static int q2t_close_session(struct scst_session *scst_sess)
{
struct q2t_sess *sess = scst_sess_get_tgt_priv(scst_sess);
scsi_qla_host_t *ha = sess->tgt->ha;
scsi_qla_host_t *pha = to_qla_parent(ha);
unsigned long flags;
spin_lock_irqsave(&pha->hardware_lock, flags);
q2t_schedule_sess_for_deletion(sess);
spin_unlock_irqrestore(&pha->hardware_lock, flags);
return 0;
}
/* pha->hardware_lock supposed to be held on entry */
static void q2t_clear_tgt_db(struct q2t_tgt *tgt, bool immediately)
{
+13
View File
@@ -984,6 +984,19 @@ struct scst_tgt_template {
*/
ssize_t (*mgmt_cmd) (char *cmd);
/*
* Forcibly close a session. Note: this function may operate
* asynchronously - there is no guarantee the session will actually
* have been closed at the time this function returns. May be called
* with scst_mutex held. Activity may be suspended while this function
* is invoked. May sleep but must not wait until session
* unregistration finished. Must return 0 upon success and -EINTR if
* the session has not been closed because a signal has been received.
*
* OPTIONAL
*/
int (*close_session)(struct scst_session *sess);
/*
* Should return physical transport version. Used in the corresponding
* INQUIRY version descriptor. See SPC for the list of available codes.
+32
View File
@@ -3562,6 +3562,28 @@ SCST_SESS_SYSFS_STAT_ATTR(cmd_count, bidi_cmd_count, SCST_DATA_BIDI, 0);
SCST_SESS_SYSFS_STAT_ATTR(io_byte_count, bidi_io_count_kb, SCST_DATA_BIDI, 1);
SCST_SESS_SYSFS_STAT_ATTR(cmd_count, none_cmd_count, SCST_DATA_NONE, 0);
static ssize_t scst_sess_force_close_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
struct scst_session *sess = container_of(kobj, struct scst_session,
sess_kobj);
int res;
res = sess->tgt->tgtt->close_session(sess);
if (res < 0)
goto out;
res = count;
out:
return res;
}
static struct kobj_attribute session_force_close_attr =
__ATTR(force_close, S_IWUSR, NULL, scst_sess_force_close_store);
static struct attribute *scst_session_attrs[] = {
&session_commands_attr.attr,
&session_active_commands_attr.attr,
@@ -3649,6 +3671,16 @@ int scst_sess_sysfs_create(struct scst_session *sess)
sess->sess_kobj_ready = 1;
if (sess->tgt->tgtt->close_session) {
res = sysfs_create_file(&sess->sess_kobj,
&session_force_close_attr.attr);
if (res != 0) {
PRINT_ERROR("Adding force_close sysfs attribute to session %s failed (%d)",
name, res);
goto out_del;
}
}
if (sess->tgt->tgtt->sess_attrs) {
res = sysfs_create_files(&sess->sess_kobj,
sess->tgt->tgtt->sess_attrs);
+9 -1
View File
@@ -166,7 +166,6 @@ static enum rdma_ch_state srpt_set_ch_state_to_disc(struct srpt_rdma_ch *ch)
case CH_LIVE:
ch->state = CH_DISCONNECTING;
wake_up_process(ch->thread);
changed = true;
break;
default:
break;
@@ -3430,6 +3429,14 @@ static int srpt_detect(struct scst_tgt_template *tp)
return device_count;
}
static int srpt_close_session(struct scst_session *sess)
{
struct srpt_rdma_ch *ch = scst_sess_get_tgt_priv(sess);
srpt_close_ch(ch);
return 0;
}
static int srpt_ch_list_empty(struct srpt_device *sdev)
{
int res;
@@ -3653,6 +3660,7 @@ static struct scst_tgt_template srpt_template = {
.on_hw_pending_cmd_timeout = srpt_pending_cmd_timeout,
.on_free_cmd = srpt_on_free_cmd,
.task_mgmt_fn_done = srpt_tsk_mgmt_done,
.close_session = srpt_close_session,
.get_initiator_port_transport_id = srpt_get_initiator_port_transport_id,
.get_scsi_transport_version = srpt_get_scsi_transport_version,
};