diff options
Diffstat (limited to 'drivers/target')
| -rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 4 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 1 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 1 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_util.c | 22 | ||||
| -rw-r--r-- | drivers/target/iscsi/iscsi_target_util.h | 1 | ||||
| -rw-r--r-- | drivers/target/target_core_configfs.c | 3 | ||||
| -rw-r--r-- | drivers/target/target_core_device.c | 18 | ||||
| -rw-r--r-- | drivers/target/target_core_sbc.c | 18 | ||||
| -rw-r--r-- | drivers/target/target_core_spc.c | 2 | ||||
| -rw-r--r-- | drivers/target/target_core_tmr.c | 6 | ||||
| -rw-r--r-- | drivers/target/target_core_transport.c | 1 | 
11 files changed, 60 insertions, 17 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index d6ce2182e67..035c2c76253 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3719,7 +3719,9 @@ restart:  		 */  		iscsit_thread_check_cpumask(conn, current, 1); -		schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT); +		wait_event_interruptible(conn->queues_wq, +					 !iscsit_conn_all_queues_empty(conn) || +					 ts->status == ISCSI_THREAD_SET_RESET);  		if ((ts->status == ISCSI_THREAD_SET_RESET) ||  		     signal_pending(current)) diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 2ba9f9b9435..21048dbf7d1 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -486,6 +486,7 @@ struct iscsi_tmr_req {  };  struct iscsi_conn { +	wait_queue_head_t	queues_wq;  	/* Authentication Successful for this connection */  	u8			auth_complete;  	/* State connection is currently in */ diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index cdc8a10939c..f8dbec05d5e 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -41,6 +41,7 @@  static int iscsi_login_init_conn(struct iscsi_conn *conn)  { +	init_waitqueue_head(&conn->queues_wq);  	INIT_LIST_HEAD(&conn->conn_list);  	INIT_LIST_HEAD(&conn->conn_cmd_list);  	INIT_LIST_HEAD(&conn->immed_queue_list); diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index afd98ccd40a..1a91195ab61 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -488,7 +488,7 @@ void iscsit_add_cmd_to_immediate_queue(  	atomic_set(&conn->check_immediate_queue, 1);  	spin_unlock_bh(&conn->immed_queue_lock); -	wake_up_process(conn->thread_set->tx_thread); +	wake_up(&conn->queues_wq);  }  struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_conn *conn) @@ -562,7 +562,7 @@ void iscsit_add_cmd_to_response_queue(  	atomic_inc(&cmd->response_queue_count);  	spin_unlock_bh(&conn->response_queue_lock); -	wake_up_process(conn->thread_set->tx_thread); +	wake_up(&conn->queues_wq);  }  struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *conn) @@ -616,6 +616,24 @@ static void iscsit_remove_cmd_from_response_queue(  	}  } +bool iscsit_conn_all_queues_empty(struct iscsi_conn *conn) +{ +	bool empty; + +	spin_lock_bh(&conn->immed_queue_lock); +	empty = list_empty(&conn->immed_queue_list); +	spin_unlock_bh(&conn->immed_queue_lock); + +	if (!empty) +		return empty; + +	spin_lock_bh(&conn->response_queue_lock); +	empty = list_empty(&conn->response_queue_list); +	spin_unlock_bh(&conn->response_queue_lock); + +	return empty; +} +  void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *conn)  {  	struct iscsi_queue_req *qr, *qr_tmp; diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h index 44054bd3543..894d0f83792 100644 --- a/drivers/target/iscsi/iscsi_target_util.h +++ b/drivers/target/iscsi/iscsi_target_util.h @@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_  extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);  extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *);  extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *); +extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *);  extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *);  extern void iscsit_release_cmd(struct iscsi_cmd *);  extern void iscsit_free_cmd(struct iscsi_cmd *); diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index 015f5be27bf..c123327499a 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -3206,7 +3206,8 @@ static int __init target_core_init_configfs(void)  	if (ret < 0)  		goto out; -	if (core_dev_setup_virtual_lun0() < 0) +	ret = core_dev_setup_virtual_lun0(); +	if (ret < 0)  		goto out;  	return 0; diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 8d774da1632..9abef9f8eb7 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -850,20 +850,20 @@ int se_dev_check_shutdown(struct se_device *dev)  static u32 se_dev_align_max_sectors(u32 max_sectors, u32 block_size)  { -	u32 tmp, aligned_max_sectors; +	u32 aligned_max_sectors; +	u32 alignment;  	/*  	 * Limit max_sectors to a PAGE_SIZE aligned value for modern  	 * transport_allocate_data_tasks() operation.  	 */ -	tmp = rounddown((max_sectors * block_size), PAGE_SIZE); -	aligned_max_sectors = (tmp / block_size); -	if (max_sectors != aligned_max_sectors) { -		printk(KERN_INFO "Rounding down aligned max_sectors from %u" -				" to %u\n", max_sectors, aligned_max_sectors); -		return aligned_max_sectors; -	} +	alignment = max(1ul, PAGE_SIZE / block_size); +	aligned_max_sectors = rounddown(max_sectors, alignment); + +	if (max_sectors != aligned_max_sectors) +		pr_info("Rounding down aligned max_sectors from %u to %u\n", +			max_sectors, aligned_max_sectors); -	return max_sectors; +	return aligned_max_sectors;  }  void se_dev_set_default_attribs( diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 868f8aa04f1..a6e27d967c7 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -135,6 +135,12 @@ static int sbc_emulate_verify(struct se_cmd *cmd)  	return 0;  } +static int sbc_emulate_noop(struct se_cmd *cmd) +{ +	target_complete_cmd(cmd, GOOD); +	return 0; +} +  static inline u32 sbc_get_size(struct se_cmd *cmd, u32 sectors)  {  	return cmd->se_dev->se_sub_dev->se_dev_attrib.block_size * sectors; @@ -531,6 +537,18 @@ int sbc_parse_cdb(struct se_cmd *cmd, struct spc_ops *ops)  		size = 0;  		cmd->execute_cmd = sbc_emulate_verify;  		break; +	case REZERO_UNIT: +	case SEEK_6: +	case SEEK_10: +		/* +		 * There are still clients out there which use these old SCSI-2 +		 * commands. This mainly happens when running VMs with legacy +		 * guest systems, connected via SCSI command pass-through to +		 * iSCSI targets. Make them happy and return status GOOD. +		 */ +		size = 0; +		cmd->execute_cmd = sbc_emulate_noop; +		break;  	default:  		ret = spc_parse_cdb(cmd, &size);  		if (ret) diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 9229bd9ad61..6fd434d3d7e 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -605,6 +605,8 @@ static int spc_emulate_inquiry(struct se_cmd *cmd)  	unsigned char buf[SE_INQUIRY_BUF];  	int p, ret; +	memset(buf, 0, SE_INQUIRY_BUF); +  	if (dev == tpg->tpg_virt_lun0.lun_se_dev)  		buf[0] = 0x3f; /* Not connected */  	else diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 1c59a3c23b2..be75c4331a9 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -140,15 +140,15 @@ void core_tmr_abort_task(  		printk("ABORT_TASK: Found referenced %s task_tag: %u\n",  			se_cmd->se_tfo->get_fabric_name(), ref_tag); -		spin_lock_irq(&se_cmd->t_state_lock); +		spin_lock(&se_cmd->t_state_lock);  		if (se_cmd->transport_state & CMD_T_COMPLETE) {  			printk("ABORT_TASK: ref_tag: %u already complete, skipping\n", ref_tag); -			spin_unlock_irq(&se_cmd->t_state_lock); +			spin_unlock(&se_cmd->t_state_lock);  			spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);  			goto out;  		}  		se_cmd->transport_state |= CMD_T_ABORTED; -		spin_unlock_irq(&se_cmd->t_state_lock); +		spin_unlock(&se_cmd->t_state_lock);  		list_del_init(&se_cmd->se_cmd_list);  		kref_get(&se_cmd->cmd_kref); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index c33baff86aa..9097155e9eb 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -1616,7 +1616,6 @@ static void target_complete_tmr_failure(struct work_struct *work)  	se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;  	se_cmd->se_tfo->queue_tm_rsp(se_cmd); -	transport_generic_free_cmd(se_cmd, 0);  }  /**  |