mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-19 19:51:27 +00:00
iscsi-scst: Do not clear reservations during nexus loss (merge r4546 from trunk)
git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.2.x@4701 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -3573,8 +3573,12 @@ static void iscsi_task_mgmt_fn_done(struct scst_mgmt_cmd *scst_mcmd)
|
||||
|
||||
switch (fn) {
|
||||
case SCST_NEXUS_LOSS_SESS:
|
||||
/* Internal */
|
||||
break;
|
||||
case SCST_ABORT_ALL_TASKS_SESS:
|
||||
/* They are internal */
|
||||
case SCST_ABORT_ALL_TASKS:
|
||||
case SCST_NEXUS_LOSS:
|
||||
sBUG_ON(1);
|
||||
break;
|
||||
default:
|
||||
iscsi_send_task_mgmt_resp(req, status);
|
||||
|
||||
@@ -325,14 +325,13 @@ void iscsi_task_mgmt_affected_cmds_done(struct scst_mgmt_cmd *scst_mcmd)
|
||||
|
||||
switch (fn) {
|
||||
case SCST_NEXUS_LOSS_SESS:
|
||||
case SCST_ABORT_ALL_TASKS_SESS:
|
||||
{
|
||||
struct iscsi_conn *conn = (struct iscsi_conn *)priv;
|
||||
struct iscsi_session *sess = conn->session;
|
||||
struct iscsi_conn *c;
|
||||
|
||||
if (sess->sess_reinst_successor != NULL)
|
||||
scst_reassign_persistent_sess_states(
|
||||
scst_reassign_retained_sess_states(
|
||||
sess->sess_reinst_successor->scst_sess,
|
||||
sess->scst_sess);
|
||||
|
||||
@@ -367,6 +366,11 @@ void iscsi_task_mgmt_affected_cmds_done(struct scst_mgmt_cmd *scst_mcmd)
|
||||
complete_all(&conn->ready_to_free);
|
||||
break;
|
||||
}
|
||||
case SCST_ABORT_ALL_TASKS_SESS:
|
||||
case SCST_ABORT_ALL_TASKS:
|
||||
case SCST_NEXUS_LOSS:
|
||||
sBUG_ON(1);
|
||||
break;
|
||||
default:
|
||||
/* Nothing to do */
|
||||
break;
|
||||
@@ -383,9 +387,10 @@ static void close_conn(struct iscsi_conn *conn)
|
||||
typeof(jiffies) start_waiting = jiffies;
|
||||
typeof(jiffies) shut_start_waiting = start_waiting;
|
||||
bool pending_reported = 0, wait_expired = 0, shut_expired = 0;
|
||||
bool reinst;
|
||||
uint32_t tid, cid;
|
||||
uint64_t sid;
|
||||
int rc;
|
||||
int lun = 0;
|
||||
|
||||
#define CONN_PENDING_TIMEOUT ((typeof(jiffies))10*HZ)
|
||||
#define CONN_WAIT_TIMEOUT ((typeof(jiffies))10*HZ)
|
||||
@@ -412,30 +417,14 @@ static void close_conn(struct iscsi_conn *conn)
|
||||
mutex_lock(&session->target->target_mutex);
|
||||
|
||||
set_bit(ISCSI_CONN_SHUTTINGDOWN, &conn->conn_aflags);
|
||||
reinst = (conn->conn_reinst_successor != NULL);
|
||||
|
||||
mutex_unlock(&session->target->target_mutex);
|
||||
|
||||
if (reinst) {
|
||||
int rc;
|
||||
int lun = 0;
|
||||
|
||||
/* Abort all outstanding commands */
|
||||
rc = scst_rx_mgmt_fn_lun(session->scst_sess,
|
||||
SCST_ABORT_ALL_TASKS_SESS, (uint8_t *)&lun, sizeof(lun),
|
||||
SCST_NON_ATOMIC, conn);
|
||||
if (rc != 0)
|
||||
PRINT_ERROR("SCST_ABORT_ALL_TASKS_SESS failed %d", rc);
|
||||
} else {
|
||||
int rc;
|
||||
int lun = 0;
|
||||
|
||||
rc = scst_rx_mgmt_fn_lun(session->scst_sess,
|
||||
SCST_NEXUS_LOSS_SESS, (uint8_t *)&lun, sizeof(lun),
|
||||
SCST_NON_ATOMIC, conn);
|
||||
if (rc != 0)
|
||||
PRINT_ERROR("SCST_NEXUS_LOSS_SESS failed %d", rc);
|
||||
}
|
||||
rc = scst_rx_mgmt_fn_lun(session->scst_sess,
|
||||
SCST_NEXUS_LOSS_SESS, (uint8_t *)&lun, sizeof(lun),
|
||||
SCST_NON_ATOMIC, conn);
|
||||
if (rc != 0)
|
||||
PRINT_ERROR("SCST_NEXUS_LOSS_SESS failed %d", rc);
|
||||
|
||||
if (conn->read_state != RX_INIT_BHS) {
|
||||
struct iscsi_cmnd *cmnd = conn->read_cmnd;
|
||||
|
||||
@@ -1262,6 +1262,18 @@ struct scst_dev_type {
|
||||
int (*task_mgmt_fn) (struct scst_mgmt_cmd *mgmt_cmd,
|
||||
struct scst_tgt_dev *tgt_dev);
|
||||
|
||||
/*
|
||||
* Called to reassign retained states (mode pages, etc.) from
|
||||
* old_tgt_dev to new_tgt_dev during nexus loss (iSCSI sessions
|
||||
* reinstatement, etc.) processing.
|
||||
*
|
||||
* Can be called under scst_mutex.
|
||||
*
|
||||
* OPTIONAL
|
||||
*/
|
||||
void (*reassign_retained_states) (struct scst_tgt_dev *new_tgt_dev,
|
||||
struct scst_tgt_dev *old_tgt_dev);
|
||||
|
||||
/*
|
||||
* Called to notify dev handler that its sg_tablesize is too low to
|
||||
* satisfy this command's data transfer requirements. Should return
|
||||
@@ -4109,7 +4121,7 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd,
|
||||
|
||||
int scst_obtain_device_parameters(struct scst_device *dev);
|
||||
|
||||
void scst_reassign_persistent_sess_states(struct scst_session *new_sess,
|
||||
void scst_reassign_retained_sess_states(struct scst_session *new_sess,
|
||||
struct scst_session *old_sess);
|
||||
|
||||
int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun);
|
||||
|
||||
@@ -97,8 +97,7 @@
|
||||
|
||||
/*
|
||||
* Notifies about I_T nexus loss event in the corresponding session.
|
||||
* Aborts all tasks there, resets the reservation, if any, and sets
|
||||
* up the I_T Nexus loss UA.
|
||||
* Aborts all tasks there and sets up the I_T Nexus loss UA.
|
||||
*/
|
||||
#define SCST_NEXUS_LOSS_SESS 6
|
||||
|
||||
@@ -107,8 +106,7 @@
|
||||
|
||||
/*
|
||||
* Notifies about I_T nexus loss event. Aborts all tasks in all sessions
|
||||
* of the tgt, resets the reservations, if any, and sets up the I_T Nexus
|
||||
* loss UA.
|
||||
* of the tgt, and sets up in them the I_T Nexus loss UA.
|
||||
*/
|
||||
#define SCST_NEXUS_LOSS 8
|
||||
|
||||
|
||||
@@ -3482,25 +3482,13 @@ void scst_nexus_loss(struct scst_tgt_dev *tgt_dev, bool queue_UA)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
scst_clear_reservation(tgt_dev);
|
||||
|
||||
#if 0 /* Clearing UAs and last sense isn't required by SAM and it looks to be
|
||||
* better to not clear them to not loose important events, so let's
|
||||
* disable it.
|
||||
*/
|
||||
/* With activity suspended the lock isn't needed, but let's be safe */
|
||||
spin_lock_bh(&tgt_dev->tgt_dev_lock);
|
||||
scst_free_all_UA(tgt_dev);
|
||||
memset(tgt_dev->tgt_dev_sense, 0, sizeof(tgt_dev->tgt_dev_sense));
|
||||
spin_unlock_bh(&tgt_dev->tgt_dev_lock);
|
||||
#endif
|
||||
|
||||
if (queue_UA) {
|
||||
uint8_t sense_buffer[SCST_STANDARD_SENSE_LEN];
|
||||
int sl = scst_set_sense(sense_buffer, sizeof(sense_buffer),
|
||||
tgt_dev->dev->d_sense,
|
||||
SCST_LOAD_SENSE(scst_sense_nexus_loss_UA));
|
||||
scst_check_set_UA(tgt_dev, sense_buffer, sl, 0);
|
||||
scst_check_set_UA(tgt_dev, sense_buffer, sl,
|
||||
SCST_SET_UA_FLAG_AT_HEAD);
|
||||
}
|
||||
|
||||
TRACE_EXIT();
|
||||
@@ -6930,18 +6918,18 @@ int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun)
|
||||
EXPORT_SYMBOL(scst_get_max_lun_commands);
|
||||
|
||||
/**
|
||||
* scst_reassign_persistent_sess_states() - reassigns persistent states
|
||||
* scst_reassign_retained_sess_states() - reassigns retained states
|
||||
*
|
||||
* Reassigns persistent states from old_sess to new_sess.
|
||||
* Reassigns retained during nexus loss states from old_sess to new_sess.
|
||||
*/
|
||||
void scst_reassign_persistent_sess_states(struct scst_session *new_sess,
|
||||
void scst_reassign_retained_sess_states(struct scst_session *new_sess,
|
||||
struct scst_session *old_sess)
|
||||
{
|
||||
struct scst_device *dev;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
TRACE_PR("Reassigning persistent states from old_sess %p to "
|
||||
TRACE_MGMT_DBG("Reassigning retained states from old_sess %p to "
|
||||
"new_sess %p", old_sess, new_sess);
|
||||
|
||||
if ((new_sess == NULL) || (old_sess == NULL)) {
|
||||
@@ -6989,6 +6977,24 @@ void scst_reassign_persistent_sess_states(struct scst_session *new_sess,
|
||||
continue;
|
||||
}
|
||||
|
||||
/** Reassign regualar reservations **/
|
||||
|
||||
if (dev->dev_reserved &&
|
||||
!test_bit(SCST_TGT_DEV_RESERVED, &old_tgt_dev->tgt_dev_flags)) {
|
||||
clear_bit(SCST_TGT_DEV_RESERVED, &new_tgt_dev->tgt_dev_flags);
|
||||
set_bit(SCST_TGT_DEV_RESERVED, &old_tgt_dev->tgt_dev_flags);
|
||||
TRACE_DBG("Reservation reassigned from old_tgt_dev %p "
|
||||
"to new_tgt_dev %p", old_tgt_dev, new_tgt_dev);
|
||||
}
|
||||
|
||||
/** Reassign PRs **/
|
||||
|
||||
if ((new_sess->transport_id == NULL) ||
|
||||
(old_sess->transport_id == NULL)) {
|
||||
TRACE_DBG("%s", "new_sess or old_sess doesn't support PRs");
|
||||
goto next;
|
||||
}
|
||||
|
||||
scst_pr_write_lock(dev);
|
||||
|
||||
if (old_tgt_dev->registrant != NULL) {
|
||||
@@ -7006,6 +7012,16 @@ void scst_reassign_persistent_sess_states(struct scst_session *new_sess,
|
||||
}
|
||||
|
||||
scst_pr_write_unlock(dev);
|
||||
next:
|
||||
/** Reassign other DH specific states **/
|
||||
|
||||
if (dev->handler->reassign_retained_states != NULL) {
|
||||
TRACE_DBG("Calling dev's %s reassign_retained_states(%p, %p)",
|
||||
dev->virt_name, new_tgt_dev, old_tgt_dev);
|
||||
dev->handler->reassign_retained_states(new_tgt_dev, old_tgt_dev);
|
||||
TRACE_DBG("Dev's %s reassign_retained_states() returned",
|
||||
dev->virt_name);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&scst_mutex);
|
||||
@@ -7014,7 +7030,7 @@ out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(scst_reassign_persistent_sess_states);
|
||||
EXPORT_SYMBOL(scst_reassign_retained_sess_states);
|
||||
|
||||
/**
|
||||
* scst_get_next_lexem() - parse and return next lexem in the string
|
||||
|
||||
Reference in New Issue
Block a user