diff --git a/iscsi-scst/kernel/config.c b/iscsi-scst/kernel/config.c index f48d8eac6..09de5588d 100644 --- a/iscsi-scst/kernel/config.c +++ b/iscsi-scst/kernel/config.c @@ -1004,6 +1004,7 @@ static int iscsi_register(void __user *arg) memset(®, 0, sizeof(reg)); reg.max_data_seg_len = ISCSI_CONN_IOV_MAX << PAGE_SHIFT; + reg.max_queued_cmds = scst_get_max_lun_commands(NULL, NO_SUCH_LUN); res = 0; diff --git a/iscsi-scst/kernel/conn.c b/iscsi-scst/kernel/conn.c index 9311a8b54..4f063bcab 100644 --- a/iscsi-scst/kernel/conn.c +++ b/iscsi-scst/kernel/conn.c @@ -473,7 +473,7 @@ static void conn_nop_in_delayed_work_fn(struct delayed_work *work) } if (conn->nop_in_interval > 0) { - TRACE_DBG("Reschedule NOP-In work for conn %p", conn); + TRACE_DBG("Reschedule Nop-In work for conn %p", conn); schedule_delayed_work(&conn->nop_in_delayed_work, conn->nop_in_interval + ISCSI_ADD_SCHED_TIME); } @@ -755,7 +755,7 @@ static int iscsi_conn_alloc(struct iscsi_session *session, conn->rsp_timeout = session->tgt_params.rsp_timeout * HZ; conn->nop_in_interval = session->tgt_params.nop_in_interval * HZ; if (conn->nop_in_interval > 0) { - TRACE_DBG("Schedule NOP-In work for conn %p", conn); + TRACE_DBG("Schedule Nop-In work for conn %p", conn); schedule_delayed_work(&conn->nop_in_delayed_work, conn->nop_in_interval + ISCSI_ADD_SCHED_TIME); } diff --git a/iscsi-scst/kernel/iscsi.c b/iscsi-scst/kernel/iscsi.c index eaf06b63c..90c3532c0 100644 --- a/iscsi-scst/kernel/iscsi.c +++ b/iscsi-scst/kernel/iscsi.c @@ -1558,7 +1558,7 @@ static int nop_out_start(struct iscsi_cmnd *cmnd) iscsi_extracheck_is_rd_thread(conn); if (!(req_hdr->flags & ISCSI_FLG_FINAL)) { - PRINT_ERROR("%s", "Initiator sent NOP-Out with not a single " + PRINT_ERROR("%s", "Initiator sent Nop-Out with not a single " "PDU"); err = -ISCSI_REASON_PROTOCOL_ERROR; goto out; @@ -1567,7 +1567,7 @@ static int nop_out_start(struct iscsi_cmnd *cmnd) if (cmnd_itt(cmnd) == cpu_to_be32(ISCSI_RESERVED_TAG)) { if (unlikely(!(cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE))) PRINT_ERROR("%s", "Initiator sent RESERVED tag for " - "non-immediate NOP-Out command"); + "non-immediate Nop-Out command"); } spin_lock(&conn->session->sn_lock); @@ -1588,7 +1588,7 @@ static int nop_out_start(struct iscsi_cmnd *cmnd) &cmnd->sg_cnt); if (sg == NULL) { TRACE(TRACE_OUT_OF_MEM, "Allocating buffer for" - " %d NOP-Out payload failed", size); + " %d Nop-Out payload failed", size); err = -ISCSI_REASON_OUT_OF_RESOURCES; goto out; } @@ -2509,7 +2509,7 @@ static void nop_out_exec(struct iscsi_cmnd *req) struct iscsi_cmnd *r; struct iscsi_conn *conn = req->conn; - TRACE_DBG("Receive NOP-in response (ttt 0x%08x)", + TRACE_DBG("Receive Nop-In response (ttt 0x%08x)", be32_to_cpu(cmnd_ttt(req))); spin_lock_bh(&conn->nop_req_list_lock); @@ -2526,8 +2526,8 @@ static void nop_out_exec(struct iscsi_cmnd *req) if (found) cmnd_put(r); else - TRACE_MGMT_DBG("%s", "Got NOP-out response without " - "corresponding NOP-in request"); + TRACE_MGMT_DBG("%s", "Got Nop-out response without " + "corresponding Nop-In request"); } req_cmnd_release(req); @@ -3489,13 +3489,13 @@ void iscsi_send_nop_in(struct iscsi_conn *conn) req = cmnd_alloc(conn, NULL); if (req == NULL) { - PRINT_ERROR("%s", "Unable to alloc fake NOP-IN request"); + PRINT_ERROR("%s", "Unable to alloc fake Nop-In request"); goto out_err; } rsp = iscsi_alloc_main_rsp(req); if (rsp == NULL) { - PRINT_ERROR("%s", "Unable to alloc NOP-IN rsp"); + PRINT_ERROR("%s", "Unable to alloc Nop-In rsp"); goto out_err_free_req; } @@ -3512,7 +3512,7 @@ void iscsi_send_nop_in(struct iscsi_conn *conn) /* Supposed that all other fields are zeroed */ - TRACE_DBG("Sending NOP-in request (ttt 0x%08x)", rsp_hdr->ttt); + TRACE_DBG("Sending Nop-In request (ttt 0x%08x)", rsp_hdr->ttt); spin_lock_bh(&conn->nop_req_list_lock); list_add_tail(&rsp->nop_req_list_entry, &conn->nop_req_list); spin_unlock_bh(&conn->nop_req_list_lock); diff --git a/iscsi-scst/kernel/nthread.c b/iscsi-scst/kernel/nthread.c index 5d619c88f..623f41890 100644 --- a/iscsi-scst/kernel/nthread.c +++ b/iscsi-scst/kernel/nthread.c @@ -767,7 +767,7 @@ static int iscsi_rx_check_ddigest(struct iscsi_conn *conn) cmnd_get(cmnd); } else if (cmnd_opcode(cmnd) != ISCSI_OP_SCSI_DATA_OUT) { /* - * We could get here only for NOP-Out. ISCSI RFC + * We could get here only for Nop-Out. ISCSI RFC * doesn't specify how to deal with digest errors in * this case. Is closing connection correct? */ diff --git a/iscsi-scst/kernel/param.c b/iscsi-scst/kernel/param.c index 9420f2570..cc54efa02 100644 --- a/iscsi-scst/kernel/param.c +++ b/iscsi-scst/kernel/param.c @@ -22,12 +22,17 @@ do { \ TRACE_DBG("%s: %u", #word, (iparams)[key_##word]); \ if ((iparams)[key_##word] < (min) || \ (iparams)[key_##word] > (max)) { \ - PRINT_ERROR("%s: %u is out of range (%u %u)", \ - #word, (iparams)[key_##word], (min), (max)); \ - if ((iparams)[key_##word] < (min)) \ + if ((iparams)[key_##word] < (min)) { \ (iparams)[key_##word] = (min); \ - else \ + PRINT_WARNING("%s: %u is too small, resetting " \ + "it to allowed min %u", \ + #word, (iparams)[key_##word], (min)); \ + } else { \ + PRINT_WARNING("%s: %u is too big, resetting " \ + "it to allowed max %u", \ + #word, (iparams)[key_##word], (max)); \ (iparams)[key_##word] = (max); \ + } \ } \ } \ } while (0) @@ -186,12 +191,14 @@ static void sess_params_get(struct iscsi_sess_params *params, } /* target_mutex supposed to be locked */ -static void tgt_params_check(struct iscsi_kern_params_info *info) +static void tgt_params_check(struct iscsi_session *session, + struct iscsi_kern_params_info *info) { int32_t *iparams = info->target_params; CHECK_PARAM(info, iparams, queued_cmnds, MIN_NR_QUEUED_CMNDS, - MAX_NR_QUEUED_CMNDS); + min_t(int, MAX_NR_QUEUED_CMNDS, + scst_get_max_lun_commands(session->scst_sess, NO_SUCH_LUN))); CHECK_PARAM(info, iparams, rsp_timeout, MIN_RSP_TIMEOUT, MAX_RSP_TIMEOUT); CHECK_PARAM(info, iparams, nop_in_interval, MIN_NOP_IN_INTERVAL, @@ -209,14 +216,14 @@ static int iscsi_tgt_params_set(struct iscsi_session *session, if (set) { struct iscsi_conn *conn; - tgt_params_check(info); + tgt_params_check(session, info); SET_PARAM(params, info, iparams, queued_cmnds); SET_PARAM(params, info, iparams, rsp_timeout); SET_PARAM(params, info, iparams, nop_in_interval); PRINT_INFO("Target parameters set for session %llx: " - "QueuedCommands %d, Response timeout %d, NOP-in " + "QueuedCommands %d, Response timeout %d, Nop-In " "interval %d", session->sid, params->queued_cmnds, params->rsp_timeout, params->nop_in_interval); @@ -226,7 +233,7 @@ static int iscsi_tgt_params_set(struct iscsi_session *session, conn->nop_in_interval = session->tgt_params.nop_in_interval * HZ; spin_lock_bh(&iscsi_rd_lock); if (!conn->closing && (conn->nop_in_interval > 0)) { - TRACE_DBG("Schedule NOP-In work for conn %p", conn); + TRACE_DBG("Schedule Nop-In work for conn %p", conn); schedule_delayed_work(&conn->nop_in_delayed_work, conn->nop_in_interval + ISCSI_ADD_SCHED_TIME); } diff --git a/iscsi-scst/usr/ctldev.c b/iscsi-scst/usr/ctldev.c index dd34f7238..26e36c996 100644 --- a/iscsi-scst/usr/ctldev.c +++ b/iscsi-scst/usr/ctldev.c @@ -29,7 +29,7 @@ #define CTL_DEVICE "/dev/iscsi-scst-ctl" -int kernel_open(int *max_data_seg_len) +int kernel_open(void) { FILE *f; char devname[256]; @@ -91,8 +91,10 @@ int kernel_open(int *max_data_seg_len) "kernel module?\n", strerror(errno)); goto out_close; } else { - log_debug(0, "MAX_DATA_SEG_LEN %d", err); - *max_data_seg_len = reg.max_data_seg_len; + log_debug(0, "max_data_seg_len %d, max_queued_cmds %d, ", + reg.max_data_seg_len, reg.max_queued_cmds); + iscsi_init_params.max_data_seg_len = reg.max_data_seg_len; + iscsi_init_params.max_queued_cmds = reg.max_queued_cmds; } out: diff --git a/iscsi-scst/usr/iscsi_scstd.c b/iscsi-scst/usr/iscsi_scstd.c index c7c27ab3d..e1ab45d89 100644 --- a/iscsi-scst/usr/iscsi_scstd.c +++ b/iscsi-scst/usr/iscsi_scstd.c @@ -62,6 +62,8 @@ static int incoming_cnt; int ctrl_fd, ipc_fd, nl_fd; int conn_blocked; +struct iscsi_init_params iscsi_init_params; + static char program_name[] = "iscsi-scstd"; static struct option const long_options[] = @@ -566,7 +568,7 @@ static void event_loop(void) } } -static void init_max_data_seg_len(int max_data_seg_len) +static void init_max_params(void) { if ((session_keys[key_max_recv_data_length].local_def != -1) || (session_keys[key_max_recv_data_length].max != -1) || @@ -580,21 +582,29 @@ static void init_max_data_seg_len(int max_data_seg_len) exit(-1); } + /* QueuedCommands */ + target_keys[key_queued_cmnds].local_def = min(target_keys[key_queued_cmnds].local_def, + iscsi_init_params.max_queued_cmds); + target_keys[key_queued_cmnds].max = min(target_keys[key_queued_cmnds].max, + iscsi_init_params.max_queued_cmds); + target_keys[key_queued_cmnds].min = min(target_keys[key_queued_cmnds].min, + iscsi_init_params.max_queued_cmds); + /* MaxRecvDataSegmentLength */ - session_keys[key_max_recv_data_length].local_def = max_data_seg_len; - session_keys[key_max_recv_data_length].max = max_data_seg_len; + session_keys[key_max_recv_data_length].local_def = iscsi_init_params.max_data_seg_len; + session_keys[key_max_recv_data_length].max = iscsi_init_params.max_data_seg_len; /* MaxXmitDataSegmentLength */ - session_keys[key_max_xmit_data_length].local_def = max_data_seg_len; - session_keys[key_max_xmit_data_length].max = max_data_seg_len; + session_keys[key_max_xmit_data_length].local_def = iscsi_init_params.max_data_seg_len; + session_keys[key_max_xmit_data_length].max = iscsi_init_params.max_data_seg_len; /* MaxBurstLength */ - session_keys[key_max_burst_length].local_def = max_data_seg_len; - session_keys[key_max_burst_length].max = max_data_seg_len; + session_keys[key_max_burst_length].local_def = iscsi_init_params.max_data_seg_len; + session_keys[key_max_burst_length].max = iscsi_init_params.max_data_seg_len; /* FirstBurstLength */ - session_keys[key_first_burst_length].local_def = max_data_seg_len; - session_keys[key_first_burst_length].max = max_data_seg_len; + session_keys[key_first_burst_length].local_def = iscsi_init_params.max_data_seg_len; + session_keys[key_first_burst_length].max = iscsi_init_params.max_data_seg_len; return; } @@ -605,7 +615,6 @@ int main(int argc, char **argv) char *config = NULL; uid_t uid = 0; gid_t gid = 0; - int max_data_seg_len = -1; int err; #ifdef CONFIG_SCST_PROC @@ -668,10 +677,10 @@ int main(int argc, char **argv) exit(-1); }; - if ((ctrl_fd = kernel_open(&max_data_seg_len)) < 0) + if ((ctrl_fd = kernel_open()) < 0) exit(-1); - init_max_data_seg_len(max_data_seg_len); + init_max_params(); #ifndef CONFIG_SCST_PROC err = kernel_attr_add(NULL, ISCSI_ISNS_SERVER_PARAM_NAME, diff --git a/iscsi-scst/usr/iscsid.h b/iscsi-scst/usr/iscsid.h index 227400a6d..f0ef0d27c 100644 --- a/iscsi-scst/usr/iscsid.h +++ b/iscsi-scst/usr/iscsid.h @@ -30,6 +30,11 @@ #define sBUG() assert(0) #define sBUG_ON(p) assert(!(p)) +struct iscsi_init_params { + int max_data_seg_len; + int max_queued_cmds; +}; + struct buf_segment { struct __qelem entry; @@ -199,6 +204,7 @@ extern void conn_free_rsp_buf_list(struct connection *conn); /* iscsi_scstd.c */ extern uint16_t server_port; +extern struct iscsi_init_params iscsi_init_params; extern void isns_set_fd(int isns, int scn_listen, int scn); /* iscsid.c */ @@ -253,7 +259,7 @@ extern int iscsi_adm_request_listen(void); extern int iscsi_adm_request_handle(int accept_fd); /* ctldev.c */ -extern int kernel_open(int *max_data_seg_len); +extern int kernel_open(void); extern int kernel_params_get(u32 tid, u64 sid, int type, struct iscsi_param *params); extern int kernel_params_set(u32 tid, u64 sid, int type, u32 partial, const struct iscsi_param *params); diff --git a/scst/include/scst.h b/scst/include/scst.h index 5c2bc7428..7dc48ff3e 100644 --- a/scst/include/scst.h +++ b/scst/include/scst.h @@ -3638,6 +3638,18 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd, */ int scst_obtain_device_parameters(struct scst_device *dev); +/* + * Returns maximum commands count which can be queued to this LUN in this + * session. + * + * If lun is NO_SUCH_LUN, returns minimum of maximum commands count which + * can be queued to any LUN in this session. + * + * If sess is NULL, returns minimum of maximum commands count which can be + * queued to any SCST device. + */ +int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun); + /* * Has to be put here open coded, because Linux doesn't have equivalent, which * allows exclusive wake ups of threads in LIFO order. We need it to let (yet) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 57c640b4c..ab99fd93c 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -5826,6 +5826,12 @@ out: return; } +int scst_get_max_lun_commands(struct scst_session *sess, uint64_t lun) +{ + return SCST_MAX_TGT_DEV_COMMANDS; +} +EXPORT_SYMBOL(scst_get_max_lun_commands); + char *scst_get_next_lexem(char **token_str) { char *p = *token_str;