diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-07 18:01:39 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-07 18:01:39 -0400 |
| commit | 052e5c7e28cc22017f9ad3f67026f911fdfc2edc (patch) | |
| tree | 131cfb59cf9a0ff822b129bb7139062f5d4ec119 | |
| parent | 813895f8dcb31bc6b0e9f5fc35e8c687a467f3dd (diff) | |
| parent | f1453773514bb8b0bba0716301e8c8f17f8d39c7 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target fixes from Nicholas Bellinger:
"Here are the remaining fixes for v3.15.
This series includes:
- iser-target fix for ImmediateData exception reference count bug
(Sagi + nab)
- iscsi-target fix for MC/S login + potential iser-target MRDSL
buffer overrun (Santosh + Roland)
- iser-target fix for v3.15-rc multi network portal shutdown
regression (nab)
- target fix for allowing READ_CAPCITY during ALUA Standby access
state (Chris + nab)
- target fix for NULL pointer dereference of alua_access_state for
un-configured devices (Chris + nab)"
* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
target: Fix alua_access_state attribute OOPs for un-configured devices
target: Allow READ_CAPACITY opcode in ALUA Standby access state
iser-target: Fix multi network portal shutdown regression
iscsi-target: Fix wrong buffer / buffer overrun in iscsi_change_param_value()
iser-target: Add missing target_put_sess_cmd for ImmedateData failure
| -rw-r--r-- | drivers/infiniband/ulp/isert/ib_isert.c | 2 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 1 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 70 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_tpg.c | 3 | ||||
| -rw-r--r-- | drivers/target/target_core_alua.c | 9 | ||||
| -rw-r--r-- | drivers/target/target_core_configfs.c | 5 |
6 files changed, 50 insertions, 40 deletions
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index a1710465faaf..b9d647468b99 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c | |||
| @@ -1210,6 +1210,8 @@ sequence_cmd: | |||
| 1210 | 1210 | ||
| 1211 | if (!rc && dump_payload == false && unsol_data) | 1211 | if (!rc && dump_payload == false && unsol_data) |
| 1212 | iscsit_set_unsoliticed_dataout(cmd); | 1212 | iscsit_set_unsoliticed_dataout(cmd); |
| 1213 | else if (dump_payload && imm_data) | ||
| 1214 | target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd); | ||
| 1213 | 1215 | ||
| 1214 | return 0; | 1216 | return 0; |
| 1215 | } | 1217 | } |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 46588c85d39b..9189bc0a87ae 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -460,6 +460,7 @@ int iscsit_del_np(struct iscsi_np *np) | |||
| 460 | spin_lock_bh(&np->np_thread_lock); | 460 | spin_lock_bh(&np->np_thread_lock); |
| 461 | np->np_exports--; | 461 | np->np_exports--; |
| 462 | if (np->np_exports) { | 462 | if (np->np_exports) { |
| 463 | np->enabled = true; | ||
| 463 | spin_unlock_bh(&np->np_thread_lock); | 464 | spin_unlock_bh(&np->np_thread_lock); |
| 464 | return 0; | 465 | return 0; |
| 465 | } | 466 | } |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index ca31fa1b8a4b..d9b1d88e1ad3 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
| @@ -249,6 +249,28 @@ static void iscsi_login_set_conn_values( | |||
| 249 | mutex_unlock(&auth_id_lock); | 249 | mutex_unlock(&auth_id_lock); |
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | static __printf(2, 3) int iscsi_change_param_sprintf( | ||
| 253 | struct iscsi_conn *conn, | ||
| 254 | const char *fmt, ...) | ||
| 255 | { | ||
| 256 | va_list args; | ||
| 257 | unsigned char buf[64]; | ||
| 258 | |||
| 259 | memset(buf, 0, sizeof buf); | ||
| 260 | |||
| 261 | va_start(args, fmt); | ||
| 262 | vsnprintf(buf, sizeof buf, fmt, args); | ||
| 263 | va_end(args); | ||
| 264 | |||
| 265 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
| 266 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
| 267 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
| 268 | return -1; | ||
| 269 | } | ||
| 270 | |||
| 271 | return 0; | ||
| 272 | } | ||
| 273 | |||
| 252 | /* | 274 | /* |
| 253 | * This is the leading connection of a new session, | 275 | * This is the leading connection of a new session, |
| 254 | * or session reinstatement. | 276 | * or session reinstatement. |
| @@ -339,7 +361,6 @@ static int iscsi_login_zero_tsih_s2( | |||
| 339 | { | 361 | { |
| 340 | struct iscsi_node_attrib *na; | 362 | struct iscsi_node_attrib *na; |
| 341 | struct iscsi_session *sess = conn->sess; | 363 | struct iscsi_session *sess = conn->sess; |
| 342 | unsigned char buf[32]; | ||
| 343 | bool iser = false; | 364 | bool iser = false; |
| 344 | 365 | ||
| 345 | sess->tpg = conn->tpg; | 366 | sess->tpg = conn->tpg; |
| @@ -380,26 +401,16 @@ static int iscsi_login_zero_tsih_s2( | |||
| 380 | * | 401 | * |
| 381 | * In our case, we have already located the struct iscsi_tiqn at this point. | 402 | * In our case, we have already located the struct iscsi_tiqn at this point. |
| 382 | */ | 403 | */ |
| 383 | memset(buf, 0, 32); | 404 | if (iscsi_change_param_sprintf(conn, "TargetPortalGroupTag=%hu", sess->tpg->tpgt)) |
| 384 | sprintf(buf, "TargetPortalGroupTag=%hu", sess->tpg->tpgt); | ||
| 385 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
| 386 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
| 387 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
| 388 | return -1; | 405 | return -1; |
| 389 | } | ||
| 390 | 406 | ||
| 391 | /* | 407 | /* |
| 392 | * Workaround for Initiators that have broken connection recovery logic. | 408 | * Workaround for Initiators that have broken connection recovery logic. |
| 393 | * | 409 | * |
| 394 | * "We would really like to get rid of this." Linux-iSCSI.org team | 410 | * "We would really like to get rid of this." Linux-iSCSI.org team |
| 395 | */ | 411 | */ |
| 396 | memset(buf, 0, 32); | 412 | if (iscsi_change_param_sprintf(conn, "ErrorRecoveryLevel=%d", na->default_erl)) |
| 397 | sprintf(buf, "ErrorRecoveryLevel=%d", na->default_erl); | ||
| 398 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
| 399 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
| 400 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
| 401 | return -1; | 413 | return -1; |
| 402 | } | ||
| 403 | 414 | ||
| 404 | if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0) | 415 | if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0) |
| 405 | return -1; | 416 | return -1; |
| @@ -411,12 +422,9 @@ static int iscsi_login_zero_tsih_s2( | |||
| 411 | unsigned long mrdsl, off; | 422 | unsigned long mrdsl, off; |
| 412 | int rc; | 423 | int rc; |
| 413 | 424 | ||
| 414 | sprintf(buf, "RDMAExtensions=Yes"); | 425 | if (iscsi_change_param_sprintf(conn, "RDMAExtensions=Yes")) |
| 415 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
| 416 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
| 417 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
| 418 | return -1; | 426 | return -1; |
| 419 | } | 427 | |
| 420 | /* | 428 | /* |
| 421 | * Make MaxRecvDataSegmentLength PAGE_SIZE aligned for | 429 | * Make MaxRecvDataSegmentLength PAGE_SIZE aligned for |
| 422 | * Immediate Data + Unsolicitied Data-OUT if necessary.. | 430 | * Immediate Data + Unsolicitied Data-OUT if necessary.. |
| @@ -446,12 +454,8 @@ static int iscsi_login_zero_tsih_s2( | |||
| 446 | pr_warn("Aligning ISER MaxRecvDataSegmentLength: %lu down" | 454 | pr_warn("Aligning ISER MaxRecvDataSegmentLength: %lu down" |
| 447 | " to PAGE_SIZE\n", mrdsl); | 455 | " to PAGE_SIZE\n", mrdsl); |
| 448 | 456 | ||
| 449 | sprintf(buf, "MaxRecvDataSegmentLength=%lu\n", mrdsl); | 457 | if (iscsi_change_param_sprintf(conn, "MaxRecvDataSegmentLength=%lu\n", mrdsl)) |
| 450 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
| 451 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
| 452 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
| 453 | return -1; | 458 | return -1; |
| 454 | } | ||
| 455 | /* | 459 | /* |
| 456 | * ISER currently requires that ImmediateData + Unsolicited | 460 | * ISER currently requires that ImmediateData + Unsolicited |
| 457 | * Data be disabled when protection / signature MRs are enabled. | 461 | * Data be disabled when protection / signature MRs are enabled. |
| @@ -461,19 +465,12 @@ check_prot: | |||
| 461 | (TARGET_PROT_DOUT_STRIP | TARGET_PROT_DOUT_PASS | | 465 | (TARGET_PROT_DOUT_STRIP | TARGET_PROT_DOUT_PASS | |
| 462 | TARGET_PROT_DOUT_INSERT)) { | 466 | TARGET_PROT_DOUT_INSERT)) { |
| 463 | 467 | ||
| 464 | sprintf(buf, "ImmediateData=No"); | 468 | if (iscsi_change_param_sprintf(conn, "ImmediateData=No")) |
| 465 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
| 466 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
| 467 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
| 468 | return -1; | 469 | return -1; |
| 469 | } | ||
| 470 | 470 | ||
| 471 | sprintf(buf, "InitialR2T=Yes"); | 471 | if (iscsi_change_param_sprintf(conn, "InitialR2T=Yes")) |
| 472 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
| 473 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
| 474 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
| 475 | return -1; | 472 | return -1; |
| 476 | } | 473 | |
| 477 | pr_debug("Forcing ImmediateData=No + InitialR2T=Yes for" | 474 | pr_debug("Forcing ImmediateData=No + InitialR2T=Yes for" |
| 478 | " T10-PI enabled ISER session\n"); | 475 | " T10-PI enabled ISER session\n"); |
| 479 | } | 476 | } |
| @@ -618,13 +615,8 @@ static int iscsi_login_non_zero_tsih_s2( | |||
| 618 | * | 615 | * |
| 619 | * In our case, we have already located the struct iscsi_tiqn at this point. | 616 | * In our case, we have already located the struct iscsi_tiqn at this point. |
| 620 | */ | 617 | */ |
| 621 | memset(buf, 0, 32); | 618 | if (iscsi_change_param_sprintf(conn, "TargetPortalGroupTag=%hu", sess->tpg->tpgt)) |
| 622 | sprintf(buf, "TargetPortalGroupTag=%hu", sess->tpg->tpgt); | ||
| 623 | if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) { | ||
| 624 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
| 625 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
| 626 | return -1; | 619 | return -1; |
| 627 | } | ||
| 628 | 620 | ||
| 629 | return iscsi_login_disable_FIM_keys(conn->param_list, conn); | 621 | return iscsi_login_disable_FIM_keys(conn->param_list, conn); |
| 630 | } | 622 | } |
diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index ca1811858afd..1431e8400d28 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c | |||
| @@ -184,7 +184,8 @@ static void iscsit_clear_tpg_np_login_thread( | |||
| 184 | return; | 184 | return; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | tpg_np->tpg_np->enabled = false; | 187 | if (shutdown) |
| 188 | tpg_np->tpg_np->enabled = false; | ||
| 188 | iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown); | 189 | iscsit_reset_np_thread(tpg_np->tpg_np, tpg_np, tpg, shutdown); |
| 189 | } | 190 | } |
| 190 | 191 | ||
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index fcbe6125b73e..63512cc01a1f 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
| @@ -576,7 +576,16 @@ static inline int core_alua_state_standby( | |||
| 576 | case REPORT_LUNS: | 576 | case REPORT_LUNS: |
| 577 | case RECEIVE_DIAGNOSTIC: | 577 | case RECEIVE_DIAGNOSTIC: |
| 578 | case SEND_DIAGNOSTIC: | 578 | case SEND_DIAGNOSTIC: |
| 579 | case READ_CAPACITY: | ||
| 579 | return 0; | 580 | return 0; |
| 581 | case SERVICE_ACTION_IN: | ||
| 582 | switch (cdb[1] & 0x1f) { | ||
| 583 | case SAI_READ_CAPACITY_16: | ||
| 584 | return 0; | ||
| 585 | default: | ||
| 586 | set_ascq(cmd, ASCQ_04H_ALUA_TG_PT_STANDBY); | ||
| 587 | return 1; | ||
| 588 | } | ||
| 580 | case MAINTENANCE_IN: | 589 | case MAINTENANCE_IN: |
| 581 | switch (cdb[1] & 0x1f) { | 590 | switch (cdb[1] & 0x1f) { |
| 582 | case MI_REPORT_TARGET_PGS: | 591 | case MI_REPORT_TARGET_PGS: |
diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 60a9ae6df763..bf55c5a04cfa 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c | |||
| @@ -2227,6 +2227,11 @@ static ssize_t target_core_alua_tg_pt_gp_store_attr_alua_access_state( | |||
| 2227 | " tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id); | 2227 | " tg_pt_gp ID: %hu\n", tg_pt_gp->tg_pt_gp_valid_id); |
| 2228 | return -EINVAL; | 2228 | return -EINVAL; |
| 2229 | } | 2229 | } |
| 2230 | if (!(dev->dev_flags & DF_CONFIGURED)) { | ||
| 2231 | pr_err("Unable to set alua_access_state while device is" | ||
| 2232 | " not configured\n"); | ||
| 2233 | return -ENODEV; | ||
| 2234 | } | ||
| 2230 | 2235 | ||
| 2231 | ret = kstrtoul(page, 0, &tmp); | 2236 | ret = kstrtoul(page, 0, &tmp); |
| 2232 | if (ret < 0) { | 2237 | if (ret < 0) { |
