[bug report] iscsi-target: Implement demo_mode_discovery logic

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello SCSI heros!

The patch 2dd1d53fe004: "iscsi-target: Implement demo_mode_discovery
logic" from Oct 7, 2013, leads to the following
Smatch static checker warning:

	drivers/target/iscsi/iscsi_target.c:3397 iscsit_build_sendtargets_response()
	warn: sleeping in atomic context

drivers/target/iscsi/iscsi_target.c
    3378 	spin_lock(&tiqn_lock);
                ^^^^^^^^^^^^^^^^^^^^

    3379 	list_for_each_entry(tiqn, &g_tiqn_list, tiqn_list) {
    3380 		if ((cmd->cmd_flags & ICF_SENDTARGETS_SINGLE) &&
    3381 		     strcmp(tiqn->tiqn, text_ptr)) {
    3382 			continue;
    3383 		}
    3384 
    3385 		target_name_printed = 0;
    3386 
    3387 		spin_lock(&tiqn->tiqn_tpg_lock);
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
We're holding a couple spinlocks.

    3388 		list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) {
    3389 
    3390 			/* If demo_mode_discovery=0 and generate_node_acls=0
    3391 			 * (demo mode dislabed) do not return
    3392 			 * TargetName+TargetAddress unless a NodeACL exists.
    3393 			 */
    3394 
    3395 			if ((tpg->tpg_attrib.generate_node_acls == 0) &&
    3396 			    (tpg->tpg_attrib.demo_mode_discovery == 0) &&
--> 3397 			    (!target_tpg_has_node_acl(&tpg->tpg_se_tpg,
                                      ^^^^^^^^^^^^^^^^^^^^^^^
The target_tpg_has_node_acl() calls mutex_lock() which can sleep so this
is a sleeping in atomic bug.

    3398 				cmd->conn->sess->sess_ops->InitiatorName))) {
    3399 				continue;
    3400 			}
    3401 
    3402 			spin_lock(&tpg->tpg_state_lock);
    3403 			active = (tpg->tpg_state == TPG_STATE_ACTIVE);
    3404 			spin_unlock(&tpg->tpg_state_lock);
    3405 
    3406 			if (!active && tpg->tpg_attrib.tpg_enabled_sendtargets)
    3407 				continue;
    3408 
    3409 			spin_lock(&tpg->tpg_np_lock);
    3410 			list_for_each_entry(tpg_np, &tpg->tpg_gnp_list,
    3411 						tpg_np_list) {
    3412 				struct iscsi_np *np = tpg_np->tpg_np;
    3413 				struct sockaddr_storage *sockaddr;
    3414 
    3415 				if (np->np_network_transport != network_transport)
    3416 					continue;
    3417 
    3418 				if (!target_name_printed) {
    3419 					len = sprintf(buf, "TargetName=%s",
    3420 						      tiqn->tiqn);
    3421 					len += 1;
    3422 
    3423 					if ((len + payload_len) > buffer_len) {
    3424 						spin_unlock(&tpg->tpg_np_lock);
    3425 						spin_unlock(&tiqn->tiqn_tpg_lock);
    3426 						end_of_buf = 1;
    3427 						goto eob;
    3428 					}
    3429 
    3430 					if (skip_bytes && len <= skip_bytes) {
    3431 						skip_bytes -= len;
    3432 					} else {
    3433 						memcpy(payload + payload_len, buf, len);
    3434 						payload_len += len;
    3435 						target_name_printed = 1;
    3436 						if (len > skip_bytes)
    3437 							skip_bytes = 0;
    3438 					}
    3439 				}
    3440 
    3441 				if (inet_addr_is_any((struct sockaddr *)&np->np_sockaddr))
    3442 					sockaddr = &conn->local_sockaddr;
    3443 				else
    3444 					sockaddr = &np->np_sockaddr;
    3445 
    3446 				len = sprintf(buf, "TargetAddress="
    3447 					      "%pISpc,%hu",
    3448 					      sockaddr,
    3449 					      tpg->tpgt);
    3450 				len += 1;
    3451 
    3452 				if ((len + payload_len) > buffer_len) {
    3453 					spin_unlock(&tpg->tpg_np_lock);
    3454 					spin_unlock(&tiqn->tiqn_tpg_lock);
    3455 					end_of_buf = 1;
    3456 					goto eob;
    3457 				}
    3458 
    3459 				if (skip_bytes && len <= skip_bytes) {
    3460 					skip_bytes -= len;
    3461 				} else {
    3462 					memcpy(payload + payload_len, buf, len);
    3463 					payload_len += len;
    3464 					if (len > skip_bytes)
    3465 						skip_bytes = 0;
    3466 				}
    3467 			}
    3468 			spin_unlock(&tpg->tpg_np_lock);
    3469 		}
    3470 		spin_unlock(&tiqn->tiqn_tpg_lock);
    3471 eob:
    3472 		if (end_of_buf) {
    3473 			*completed = false;
    3474 			break;
    3475 		}
    3476 
    3477 		if (cmd->cmd_flags & ICF_SENDTARGETS_SINGLE)
    3478 			break;
    3479 	}
    3480 	spin_unlock(&tiqn_lock);
    3481 
    3482 	cmd->buf_ptr = payload;
    3483 
    3484 	return payload_len;
    3485 }

regards,
dan carpenter



[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux