Decouple iSCSI connection limits from defaults.
If initiator does not negotiate some parameter, it expects one to get default value, not some unknown remote hardware limit. On the side side, if some parameter is negotiated, its default value from RFC should not be used for anything.
This commit is contained in:
parent
00ea8a5fc9
commit
59c6e3a58f
@ -1582,6 +1582,7 @@ connection_new(struct portal *portal, int fd, const char *host,
|
||||
* Default values, from RFC 3720, section 12.
|
||||
*/
|
||||
conn->conn_max_recv_data_segment_length = 8192;
|
||||
conn->conn_max_send_data_segment_length = 8192;
|
||||
conn->conn_max_burst_length = 262144;
|
||||
conn->conn_first_burst_length = 65536;
|
||||
conn->conn_immediate_data = true;
|
||||
|
@ -48,8 +48,6 @@
|
||||
#define MAX_LUNS 1024
|
||||
#define MAX_NAME_LEN 223
|
||||
#define MAX_DATA_SEGMENT_LENGTH (128 * 1024)
|
||||
#define MAX_BURST_LENGTH 16776192
|
||||
#define FIRST_BURST_LENGTH (128 * 1024)
|
||||
#define SOCKBUF_SIZE 1048576
|
||||
|
||||
struct auth {
|
||||
@ -242,6 +240,10 @@ struct connection {
|
||||
struct sockaddr_storage conn_initiator_sa;
|
||||
uint32_t conn_cmdsn;
|
||||
uint32_t conn_statsn;
|
||||
int conn_max_recv_data_segment_limit;
|
||||
int conn_max_send_data_segment_limit;
|
||||
int conn_max_burst_limit;
|
||||
int conn_first_burst_limit;
|
||||
int conn_max_recv_data_segment_length;
|
||||
int conn_max_send_data_segment_length;
|
||||
int conn_max_burst_length;
|
||||
|
@ -557,13 +557,15 @@ login_negotiate_key(struct pdu *request, const char *name,
|
||||
* our MaxRecvDataSegmentLength is not influenced by the
|
||||
* initiator in any way.
|
||||
*/
|
||||
if ((int)tmp > conn->conn_max_send_data_segment_length) {
|
||||
log_debugx("capping max_send_data_segment_length "
|
||||
if ((int)tmp > conn->conn_max_send_data_segment_limit) {
|
||||
log_debugx("capping MaxRecvDataSegmentLength "
|
||||
"from %zd to %d", tmp,
|
||||
conn->conn_max_send_data_segment_length);
|
||||
tmp = conn->conn_max_send_data_segment_length;
|
||||
conn->conn_max_send_data_segment_limit);
|
||||
tmp = conn->conn_max_send_data_segment_limit;
|
||||
}
|
||||
conn->conn_max_send_data_segment_length = tmp;
|
||||
conn->conn_max_recv_data_segment_length =
|
||||
conn->conn_max_recv_data_segment_limit;
|
||||
keys_add_int(response_keys, name,
|
||||
conn->conn_max_recv_data_segment_length);
|
||||
} else if (strcmp(name, "MaxBurstLength") == 0) {
|
||||
@ -572,10 +574,10 @@ login_negotiate_key(struct pdu *request, const char *name,
|
||||
login_send_error(request, 0x02, 0x00);
|
||||
log_errx(1, "received invalid MaxBurstLength");
|
||||
}
|
||||
if ((int)tmp > conn->conn_max_burst_length) {
|
||||
if ((int)tmp > conn->conn_max_burst_limit) {
|
||||
log_debugx("capping MaxBurstLength from %zd to %d",
|
||||
tmp, conn->conn_max_burst_length);
|
||||
tmp = conn->conn_max_burst_length;
|
||||
tmp, conn->conn_max_burst_limit);
|
||||
tmp = conn->conn_max_burst_limit;
|
||||
}
|
||||
conn->conn_max_burst_length = tmp;
|
||||
keys_add_int(response_keys, name, tmp);
|
||||
@ -585,10 +587,10 @@ login_negotiate_key(struct pdu *request, const char *name,
|
||||
login_send_error(request, 0x02, 0x00);
|
||||
log_errx(1, "received invalid FirstBurstLength");
|
||||
}
|
||||
if ((int)tmp > conn->conn_first_burst_length) {
|
||||
if ((int)tmp > conn->conn_first_burst_limit) {
|
||||
log_debugx("capping FirstBurstLength from %zd to %d",
|
||||
tmp, conn->conn_first_burst_length);
|
||||
tmp = conn->conn_first_burst_length;
|
||||
tmp, conn->conn_first_burst_limit);
|
||||
tmp = conn->conn_first_burst_limit;
|
||||
}
|
||||
conn->conn_first_burst_length = tmp;
|
||||
keys_add_int(response_keys, name, tmp);
|
||||
@ -694,25 +696,42 @@ login_negotiate(struct connection *conn, struct pdu *request)
|
||||
* offload, it depends on hardware capabilities.
|
||||
*/
|
||||
assert(conn->conn_target != NULL);
|
||||
conn->conn_max_recv_data_segment_limit = (1 << 24) - 1;
|
||||
conn->conn_max_send_data_segment_limit = (1 << 24) - 1;
|
||||
conn->conn_max_burst_limit = (1 << 24) - 1;
|
||||
conn->conn_first_burst_limit = (1 << 24) - 1;
|
||||
kernel_limits(conn->conn_portal->p_portal_group->pg_offload,
|
||||
&conn->conn_max_recv_data_segment_length,
|
||||
&conn->conn_max_send_data_segment_length,
|
||||
&conn->conn_max_burst_length,
|
||||
&conn->conn_first_burst_length);
|
||||
&conn->conn_max_recv_data_segment_limit,
|
||||
&conn->conn_max_send_data_segment_limit,
|
||||
&conn->conn_max_burst_limit,
|
||||
&conn->conn_first_burst_limit);
|
||||
|
||||
/* We expect legal, usable values at this point. */
|
||||
assert(conn->conn_max_recv_data_segment_length >= 512);
|
||||
assert(conn->conn_max_recv_data_segment_length < (1 << 24));
|
||||
assert(conn->conn_max_burst_length >= 512);
|
||||
assert(conn->conn_max_burst_length < (1 << 24));
|
||||
assert(conn->conn_first_burst_length >= 512);
|
||||
assert(conn->conn_first_burst_length < (1 << 24));
|
||||
assert(conn->conn_first_burst_length <=
|
||||
conn->conn_max_burst_length);
|
||||
assert(conn->conn_max_recv_data_segment_limit >= 512);
|
||||
assert(conn->conn_max_recv_data_segment_limit < (1 << 24));
|
||||
assert(conn->conn_max_send_data_segment_limit >= 512);
|
||||
assert(conn->conn_max_send_data_segment_limit < (1 << 24));
|
||||
assert(conn->conn_max_burst_limit >= 512);
|
||||
assert(conn->conn_max_burst_limit < (1 << 24));
|
||||
assert(conn->conn_first_burst_limit >= 512);
|
||||
assert(conn->conn_first_burst_limit < (1 << 24));
|
||||
assert(conn->conn_first_burst_limit <=
|
||||
conn->conn_max_burst_limit);
|
||||
|
||||
/*
|
||||
* Limit default send length in case it won't be negotiated.
|
||||
* We can't do it for other limits, since they may affect both
|
||||
* sender and receiver operation, and we must obey defaults.
|
||||
*/
|
||||
if (conn->conn_max_send_data_segment_limit <
|
||||
conn->conn_max_send_data_segment_length) {
|
||||
conn->conn_max_send_data_segment_limit =
|
||||
conn->conn_max_send_data_segment_length;
|
||||
}
|
||||
} else {
|
||||
conn->conn_max_recv_data_segment_length =
|
||||
conn->conn_max_recv_data_segment_limit =
|
||||
MAX_DATA_SEGMENT_LENGTH;
|
||||
conn->conn_max_send_data_segment_length =
|
||||
conn->conn_max_send_data_segment_limit =
|
||||
MAX_DATA_SEGMENT_LENGTH;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user