diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index 7f0b24636..f352b4973 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -1224,6 +1224,15 @@ void req_add_to_write_timeout_list(struct iscsi_cmnd *req) list_add_tail(&req->write_timeout_list_entry, &conn->write_timeout_list); } + + /* We suppose that nop_in_timeout must be <= data_rsp_timeout */ + req_tt += ISCSI_ADD_SCHED_TIME; + if (timer_pending(&conn->rsp_timer) && + time_after(conn->rsp_timer.expires, req_tt)) { + TRACE_DBG("Timer adjusted for sooner expired NOP IN " + "req %p", req); + mod_timer(&conn->rsp_timer, req_tt); + } } else list_add_tail(&req->write_timeout_list_entry, &conn->write_timeout_list); diff --git a/iscsi-scst/kernel/param.c b/iscsi-scst/kernel/param.c index 65dce7be8..e61fe928f 100644 --- a/iscsi-scst/kernel/param.c +++ b/iscsi-scst/kernel/param.c @@ -115,6 +115,11 @@ static void sess_params_check(struct iscsi_kern_params_info *info) int32_t *iparams = info->session_params; const int max_len = ISCSI_CONN_IOV_MAX * PAGE_SIZE; + /* + * This is only kernel sanity check. Actual data validity checks + * performed in the user space. + */ + CHECK_PARAM(info, iparams, initial_r2t, 0, 1); CHECK_PARAM(info, iparams, immediate_data, 0, 1); CHECK_PARAM(info, iparams, max_connections, 1, 1); @@ -196,6 +201,12 @@ static void tgt_params_check(struct iscsi_session *session, struct iscsi_kern_params_info *info) { int32_t *iparams = info->target_params; + unsigned int rsp_timeout, nop_in_timeout; + + /* + * This is only kernel sanity check. Actual data validity checks + * performed in the user space. + */ CHECK_PARAM(info, iparams, queued_cmnds, MIN_NR_QUEUED_CMNDS, min_t(int, MAX_NR_QUEUED_CMNDS, @@ -206,6 +217,24 @@ static void tgt_params_check(struct iscsi_session *session, MAX_NOP_IN_INTERVAL); CHECK_PARAM(info, iparams, nop_in_timeout, MIN_NOP_IN_TIMEOUT, MAX_NOP_IN_TIMEOUT); + + /* + * We adjust too long timeout in req_add_to_write_timeout_list() + * only for NOPs, so check and warn if this assumption isn't honored. + */ + if (!info->partial || (info->partial & 1 << key_rsp_timeout)) + rsp_timeout = iparams[key_rsp_timeout]; + else + rsp_timeout = session->tgt_params.rsp_timeout; + if (!info->partial || (info->partial & 1 << key_nop_in_timeout)) + nop_in_timeout = iparams[key_nop_in_timeout]; + else + nop_in_timeout = session->tgt_params.nop_in_timeout; + if (nop_in_timeout > rsp_timeout) + PRINT_WARNING("%s", "RspTimeout should be >= NopInTimeout, " + "otherwise data transfer failure could take up to " + "NopInTimeout long to detect"); + return; } diff --git a/iscsi-scst/usr/config.c b/iscsi-scst/usr/config.c index 95ba23558..2e7c3349d 100644 --- a/iscsi-scst/usr/config.c +++ b/iscsi-scst/usr/config.c @@ -815,7 +815,7 @@ int config_params_get(u32 tid, u64 sid, int type, struct iscsi_param *params) params[i].val = target->session_params[i]; } else { for (i = 0; i < target_key_last; i++) - params[i].val = target->target_params[i]; + params[i].val = target->target_params[i]; } out: