Commit 3c006c7d authored by Mike Christie's avatar Mike Christie Committed by Martin K. Petersen
Browse files

scsi: target: Fix xcopy sess release leak

transport_init_session can allocate memory via percpu_ref_init, and
target_xcopy_release_pt never frees it. This adds a
transport_uninit_session function to handle cleanup of resources allocated
in the init function.

Link: https://lore.kernel.org/r/1593654203-12442-3-git-send-email-michael.christie@oracle.com


Signed-off-by: default avatarMike Christie <michael.christie@oracle.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 63c9ffe4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ int init_se_kmem_caches(void);
void	release_se_kmem_caches(void);
u32	scsi_get_new_index(scsi_index_t);
void	transport_subsystem_check_init(void);
void	transport_uninit_session(struct se_session *);
unsigned char *transport_dump_cmd_direction(struct se_cmd *);
void	transport_dump_dev_state(struct se_device *, char *, int *);
void	transport_dump_dev_info(struct se_device *, struct se_lun *,
+6 −1
Original line number Diff line number Diff line
@@ -236,6 +236,11 @@ int transport_init_session(struct se_session *se_sess)
}
EXPORT_SYMBOL(transport_init_session);

void transport_uninit_session(struct se_session *se_sess)
{
	percpu_ref_exit(&se_sess->cmd_count);
}

/**
 * transport_alloc_session - allocate a session object and initialize it
 * @sup_prot_ops: bitmask that defines which T10-PI modes are supported.
@@ -579,7 +584,7 @@ void transport_free_session(struct se_session *se_sess)
		sbitmap_queue_free(&se_sess->sess_tag_pool);
		kvfree(se_sess->sess_cmd_map);
	}
	percpu_ref_exit(&se_sess->cmd_count);
	transport_uninit_session(se_sess);
	kmem_cache_free(se_sess_cache, se_sess);
}
EXPORT_SYMBOL(transport_free_session);
+9 −2
Original line number Diff line number Diff line
@@ -474,7 +474,7 @@ int target_xcopy_setup_pt(void)
	memset(&xcopy_pt_sess, 0, sizeof(struct se_session));
	ret = transport_init_session(&xcopy_pt_sess);
	if (ret < 0)
		return ret;
		goto destroy_wq;

	xcopy_pt_nacl.se_tpg = &xcopy_pt_tpg;
	xcopy_pt_nacl.nacl_sess = &xcopy_pt_sess;
@@ -483,12 +483,19 @@ int target_xcopy_setup_pt(void)
	xcopy_pt_sess.se_node_acl = &xcopy_pt_nacl;

	return 0;

destroy_wq:
	destroy_workqueue(xcopy_wq);
	xcopy_wq = NULL;
	return ret;
}

void target_xcopy_release_pt(void)
{
	if (xcopy_wq)
	if (xcopy_wq) {
		destroy_workqueue(xcopy_wq);
		transport_uninit_session(&xcopy_pt_sess);
	}
}

/*