mirror of
				https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
				synced 2025-11-04 16:52:06 +10:00 
			
		
		
		
	scsi: target: core: De-RCU of se_lun and se_lun acl
se_lun and se_lun_acl are immutable pointers of struct se_dev_entry. Remove RCU usage for access to those pointers. Link: https://lore.kernel.org/r/20220727214125.19647-3-d.bogdanov@yadro.com Reviewed-by: Mike Christie <michael.christie@oracle.com> Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
		
							parent
							
								
									dd0a66ada0
								
							
						
					
					
						commit
						ef4f7e4bf1
					
				@ -934,8 +934,7 @@ static void core_alua_queue_state_change_ua(struct t10_alua_tg_pt_gp *tg_pt_gp)
 | 
			
		||||
 | 
			
		||||
		spin_lock(&lun->lun_deve_lock);
 | 
			
		||||
		list_for_each_entry(se_deve, &lun->lun_deve_list, lun_link) {
 | 
			
		||||
			lacl = rcu_dereference_check(se_deve->se_lun_acl,
 | 
			
		||||
					lockdep_is_held(&lun->lun_deve_lock));
 | 
			
		||||
			lacl = se_deve->se_lun_acl;
 | 
			
		||||
 | 
			
		||||
			/*
 | 
			
		||||
			 * spc4r37 p.242:
 | 
			
		||||
 | 
			
		||||
@ -75,7 +75,7 @@ transport_lookup_cmd_lun(struct se_cmd *se_cmd)
 | 
			
		||||
			return TCM_WRITE_PROTECTED;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		se_lun = rcu_dereference(deve->se_lun);
 | 
			
		||||
		se_lun = deve->se_lun;
 | 
			
		||||
 | 
			
		||||
		if (!percpu_ref_tryget_live(&se_lun->lun_ref)) {
 | 
			
		||||
			se_lun = NULL;
 | 
			
		||||
@ -152,7 +152,7 @@ int transport_lookup_tmr_lun(struct se_cmd *se_cmd)
 | 
			
		||||
	rcu_read_lock();
 | 
			
		||||
	deve = target_nacl_find_deve(nacl, se_cmd->orig_fe_lun);
 | 
			
		||||
	if (deve) {
 | 
			
		||||
		se_lun = rcu_dereference(deve->se_lun);
 | 
			
		||||
		se_lun = deve->se_lun;
 | 
			
		||||
 | 
			
		||||
		if (!percpu_ref_tryget_live(&se_lun->lun_ref)) {
 | 
			
		||||
			se_lun = NULL;
 | 
			
		||||
@ -216,7 +216,7 @@ struct se_dev_entry *core_get_se_deve_from_rtpi(
 | 
			
		||||
 | 
			
		||||
	rcu_read_lock();
 | 
			
		||||
	hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
 | 
			
		||||
		lun = rcu_dereference(deve->se_lun);
 | 
			
		||||
		lun = deve->se_lun;
 | 
			
		||||
		if (!lun) {
 | 
			
		||||
			pr_err("%s device entries device pointer is"
 | 
			
		||||
				" NULL, but Initiator has access.\n",
 | 
			
		||||
@ -243,11 +243,8 @@ void core_free_device_list_for_node(
 | 
			
		||||
	struct se_dev_entry *deve;
 | 
			
		||||
 | 
			
		||||
	mutex_lock(&nacl->lun_entry_mutex);
 | 
			
		||||
	hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
 | 
			
		||||
		struct se_lun *lun = rcu_dereference_check(deve->se_lun,
 | 
			
		||||
					lockdep_is_held(&nacl->lun_entry_mutex));
 | 
			
		||||
		core_disable_device_list_for_node(lun, deve, nacl, tpg);
 | 
			
		||||
	}
 | 
			
		||||
	hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link)
 | 
			
		||||
		core_disable_device_list_for_node(deve->se_lun, deve, nacl, tpg);
 | 
			
		||||
	mutex_unlock(&nacl->lun_entry_mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -334,8 +331,7 @@ int core_enable_device_list_for_node(
 | 
			
		||||
	mutex_lock(&nacl->lun_entry_mutex);
 | 
			
		||||
	orig = target_nacl_find_deve(nacl, mapped_lun);
 | 
			
		||||
	if (orig && orig->se_lun) {
 | 
			
		||||
		struct se_lun *orig_lun = rcu_dereference_check(orig->se_lun,
 | 
			
		||||
					lockdep_is_held(&nacl->lun_entry_mutex));
 | 
			
		||||
		struct se_lun *orig_lun = orig->se_lun;
 | 
			
		||||
 | 
			
		||||
		if (orig_lun != lun) {
 | 
			
		||||
			pr_err("Existing orig->se_lun doesn't match new lun"
 | 
			
		||||
@ -355,8 +351,8 @@ int core_enable_device_list_for_node(
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		rcu_assign_pointer(new->se_lun, lun);
 | 
			
		||||
		rcu_assign_pointer(new->se_lun_acl, lun_acl);
 | 
			
		||||
		new->se_lun = lun;
 | 
			
		||||
		new->se_lun_acl = lun_acl;
 | 
			
		||||
		hlist_del_rcu(&orig->link);
 | 
			
		||||
		hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist);
 | 
			
		||||
		mutex_unlock(&nacl->lun_entry_mutex);
 | 
			
		||||
@ -374,8 +370,8 @@ int core_enable_device_list_for_node(
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rcu_assign_pointer(new->se_lun, lun);
 | 
			
		||||
	rcu_assign_pointer(new->se_lun_acl, lun_acl);
 | 
			
		||||
	new->se_lun = lun;
 | 
			
		||||
	new->se_lun_acl = lun_acl;
 | 
			
		||||
	hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist);
 | 
			
		||||
	mutex_unlock(&nacl->lun_entry_mutex);
 | 
			
		||||
 | 
			
		||||
@ -454,10 +450,7 @@ void core_clear_lun_from_tpg(struct se_lun *lun, struct se_portal_group *tpg)
 | 
			
		||||
 | 
			
		||||
		mutex_lock(&nacl->lun_entry_mutex);
 | 
			
		||||
		hlist_for_each_entry_rcu(deve, &nacl->lun_entry_hlist, link) {
 | 
			
		||||
			struct se_lun *tmp_lun = rcu_dereference_check(deve->se_lun,
 | 
			
		||||
					lockdep_is_held(&nacl->lun_entry_mutex));
 | 
			
		||||
 | 
			
		||||
			if (lun != tmp_lun)
 | 
			
		||||
			if (lun != deve->se_lun)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			core_disable_device_list_for_node(lun, deve, nacl, tpg);
 | 
			
		||||
 | 
			
		||||
@ -739,8 +739,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
 | 
			
		||||
			if (!deve_tmp->se_lun_acl)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			lacl_tmp = rcu_dereference_check(deve_tmp->se_lun_acl,
 | 
			
		||||
						lockdep_is_held(&lun_tmp->lun_deve_lock));
 | 
			
		||||
			lacl_tmp = deve_tmp->se_lun_acl;
 | 
			
		||||
			nacl_tmp = lacl_tmp->se_lun_nacl;
 | 
			
		||||
			/*
 | 
			
		||||
			 * Skip the matching struct se_node_acl that is allocated
 | 
			
		||||
@ -784,8 +783,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
 | 
			
		||||
			 * the original *pr_reg is processed in
 | 
			
		||||
			 * __core_scsi3_add_registration()
 | 
			
		||||
			 */
 | 
			
		||||
			dest_lun = rcu_dereference_check(deve_tmp->se_lun,
 | 
			
		||||
				kref_read(&deve_tmp->pr_kref) != 0);
 | 
			
		||||
			dest_lun = deve_tmp->se_lun;
 | 
			
		||||
 | 
			
		||||
			pr_reg_atp = __core_scsi3_do_alloc_registration(dev,
 | 
			
		||||
						nacl_tmp, dest_lun, deve_tmp,
 | 
			
		||||
@ -1437,34 +1435,26 @@ static void core_scsi3_nodeacl_undepend_item(struct se_node_acl *nacl)
 | 
			
		||||
 | 
			
		||||
static int core_scsi3_lunacl_depend_item(struct se_dev_entry *se_deve)
 | 
			
		||||
{
 | 
			
		||||
	struct se_lun_acl *lun_acl;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * For nacl->dynamic_node_acl=1
 | 
			
		||||
	 */
 | 
			
		||||
	lun_acl = rcu_dereference_check(se_deve->se_lun_acl,
 | 
			
		||||
				kref_read(&se_deve->pr_kref) != 0);
 | 
			
		||||
	if (!lun_acl)
 | 
			
		||||
	if (!se_deve->se_lun_acl)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return target_depend_item(&lun_acl->se_lun_group.cg_item);
 | 
			
		||||
	return target_depend_item(&se_deve->se_lun_acl->se_lun_group.cg_item);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void core_scsi3_lunacl_undepend_item(struct se_dev_entry *se_deve)
 | 
			
		||||
{
 | 
			
		||||
	struct se_lun_acl *lun_acl;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * For nacl->dynamic_node_acl=1
 | 
			
		||||
	 */
 | 
			
		||||
	lun_acl = rcu_dereference_check(se_deve->se_lun_acl,
 | 
			
		||||
				kref_read(&se_deve->pr_kref) != 0);
 | 
			
		||||
	if (!lun_acl) {
 | 
			
		||||
	if (!se_deve->se_lun_acl) {
 | 
			
		||||
		kref_put(&se_deve->pr_kref, target_pr_kref_release);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	target_undepend_item(&lun_acl->se_lun_group.cg_item);
 | 
			
		||||
	target_undepend_item(&se_deve->se_lun_acl->se_lun_group.cg_item);
 | 
			
		||||
	kref_put(&se_deve->pr_kref, target_pr_kref_release);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1751,8 +1741,7 @@ core_scsi3_decode_spec_i_port(
 | 
			
		||||
		 * and then call __core_scsi3_add_registration() in the
 | 
			
		||||
		 * 2nd loop which will never fail.
 | 
			
		||||
		 */
 | 
			
		||||
		dest_lun = rcu_dereference_check(dest_se_deve->se_lun,
 | 
			
		||||
				kref_read(&dest_se_deve->pr_kref) != 0);
 | 
			
		||||
		dest_lun = dest_se_deve->se_lun;
 | 
			
		||||
 | 
			
		||||
		dest_pr_reg = __core_scsi3_alloc_registration(cmd->se_dev,
 | 
			
		||||
					dest_node_acl, dest_lun, dest_se_deve,
 | 
			
		||||
@ -3446,8 +3435,7 @@ after_iport_check:
 | 
			
		||||
	dest_pr_reg = __core_scsi3_locate_pr_reg(dev, dest_node_acl,
 | 
			
		||||
					iport_ptr);
 | 
			
		||||
	if (!dest_pr_reg) {
 | 
			
		||||
		struct se_lun *dest_lun = rcu_dereference_check(dest_se_deve->se_lun,
 | 
			
		||||
				kref_read(&dest_se_deve->pr_kref) != 0);
 | 
			
		||||
		struct se_lun *dest_lun = dest_se_deve->se_lun;
 | 
			
		||||
 | 
			
		||||
		spin_unlock(&dev->dev_reservation_lock);
 | 
			
		||||
		if (core_scsi3_alloc_registration(cmd->se_dev, dest_node_acl,
 | 
			
		||||
 | 
			
		||||
@ -877,7 +877,6 @@ static ssize_t target_stat_auth_dev_show(struct config_item *item,
 | 
			
		||||
	struct se_lun_acl *lacl = auth_to_lacl(item);
 | 
			
		||||
	struct se_node_acl *nacl = lacl->se_lun_nacl;
 | 
			
		||||
	struct se_dev_entry *deve;
 | 
			
		||||
	struct se_lun *lun;
 | 
			
		||||
	ssize_t ret;
 | 
			
		||||
 | 
			
		||||
	rcu_read_lock();
 | 
			
		||||
@ -886,9 +885,9 @@ static ssize_t target_stat_auth_dev_show(struct config_item *item,
 | 
			
		||||
		rcu_read_unlock();
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
	}
 | 
			
		||||
	lun = rcu_dereference(deve->se_lun);
 | 
			
		||||
 | 
			
		||||
	/* scsiDeviceIndex */
 | 
			
		||||
	ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_index);
 | 
			
		||||
	ret = snprintf(page, PAGE_SIZE, "%u\n", deve->se_lun->lun_index);
 | 
			
		||||
	rcu_read_unlock();
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
@ -1217,7 +1216,6 @@ static ssize_t target_stat_iport_dev_show(struct config_item *item,
 | 
			
		||||
	struct se_lun_acl *lacl = iport_to_lacl(item);
 | 
			
		||||
	struct se_node_acl *nacl = lacl->se_lun_nacl;
 | 
			
		||||
	struct se_dev_entry *deve;
 | 
			
		||||
	struct se_lun *lun;
 | 
			
		||||
	ssize_t ret;
 | 
			
		||||
 | 
			
		||||
	rcu_read_lock();
 | 
			
		||||
@ -1226,9 +1224,9 @@ static ssize_t target_stat_iport_dev_show(struct config_item *item,
 | 
			
		||||
		rcu_read_unlock();
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
	}
 | 
			
		||||
	lun = rcu_dereference(deve->se_lun);
 | 
			
		||||
 | 
			
		||||
	/* scsiDeviceIndex */
 | 
			
		||||
	ret = snprintf(page, PAGE_SIZE, "%u\n", lun->lun_index);
 | 
			
		||||
	ret = snprintf(page, PAGE_SIZE, "%u\n", deve->se_lun->lun_index);
 | 
			
		||||
	rcu_read_unlock();
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -88,7 +88,7 @@ static int target_xcopy_locate_se_dev_e4(struct se_session *sess,
 | 
			
		||||
		struct se_device *this_dev;
 | 
			
		||||
		int rc;
 | 
			
		||||
 | 
			
		||||
		this_lun = rcu_dereference(deve->se_lun);
 | 
			
		||||
		this_lun = deve->se_lun;
 | 
			
		||||
		this_dev = rcu_dereference_raw(this_lun->lun_se_dev);
 | 
			
		||||
 | 
			
		||||
		rc = target_xcopy_locate_se_dev_e4_iter(this_dev, dev_wwn);
 | 
			
		||||
 | 
			
		||||
@ -665,9 +665,9 @@ struct se_dev_entry {
 | 
			
		||||
	/* Used for PR SPEC_I_PT=1 and REGISTER_AND_MOVE */
 | 
			
		||||
	struct kref		pr_kref;
 | 
			
		||||
	struct completion	pr_comp;
 | 
			
		||||
	struct se_lun_acl __rcu	*se_lun_acl;
 | 
			
		||||
	struct se_lun_acl	*se_lun_acl;
 | 
			
		||||
	spinlock_t		ua_lock;
 | 
			
		||||
	struct se_lun __rcu	*se_lun;
 | 
			
		||||
	struct se_lun		*se_lun;
 | 
			
		||||
#define DEF_PR_REG_ACTIVE		1
 | 
			
		||||
	unsigned long		deve_flags;
 | 
			
		||||
	struct list_head	alua_port_list;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user