@@ -46,60 +46,83 @@ static int target_xcopy_gen_naa_ieee(struct se_device *dev, unsigned char *buf)
4646 return 0 ;
4747}
4848
49- struct xcopy_dev_search_info {
50- const unsigned char * dev_wwn ;
51- struct se_device * found_dev ;
52- };
53-
49+ /**
50+ * target_xcopy_locate_se_dev_e4_iter - compare XCOPY NAA device identifiers
51+ *
52+ * @se_dev: device being considered for match
53+ * @dev_wwn: XCOPY requested NAA dev_wwn
54+ * @return: 1 on match, 0 on no-match
55+ */
5456static int target_xcopy_locate_se_dev_e4_iter (struct se_device * se_dev ,
55- void * data )
57+ const unsigned char * dev_wwn )
5658{
57- struct xcopy_dev_search_info * info = data ;
5859 unsigned char tmp_dev_wwn [XCOPY_NAA_IEEE_REGEX_LEN ];
5960 int rc ;
6061
61- if (!se_dev -> dev_attrib .emulate_3pc )
62+ if (!se_dev -> dev_attrib .emulate_3pc ) {
63+ pr_debug ("XCOPY: emulate_3pc disabled on se_dev %p\n" , se_dev );
6264 return 0 ;
65+ }
6366
6467 memset (& tmp_dev_wwn [0 ], 0 , XCOPY_NAA_IEEE_REGEX_LEN );
6568 target_xcopy_gen_naa_ieee (se_dev , & tmp_dev_wwn [0 ]);
6669
67- rc = memcmp (& tmp_dev_wwn [0 ], info -> dev_wwn , XCOPY_NAA_IEEE_REGEX_LEN );
68- if (rc != 0 )
69- return 0 ;
70-
71- info -> found_dev = se_dev ;
72- pr_debug ("XCOPY 0xe4: located se_dev: %p\n" , se_dev );
73-
74- rc = target_depend_item (& se_dev -> dev_group .cg_item );
70+ rc = memcmp (& tmp_dev_wwn [0 ], dev_wwn , XCOPY_NAA_IEEE_REGEX_LEN );
7571 if (rc != 0 ) {
76- pr_err ( "configfs_depend_item attempt failed: %d for se_dev : %p \n" ,
77- rc , se_dev );
78- return rc ;
72+ pr_debug ( "XCOPY: skip non-matching : %*ph \n" ,
73+ XCOPY_NAA_IEEE_REGEX_LEN , tmp_dev_wwn );
74+ return 0 ;
7975 }
76+ pr_debug ("XCOPY 0xe4: located se_dev: %p\n" , se_dev );
8077
81- pr_debug ("Called configfs_depend_item for se_dev: %p se_dev->se_dev_group: %p\n" ,
82- se_dev , & se_dev -> dev_group );
8378 return 1 ;
8479}
8580
86- static int target_xcopy_locate_se_dev_e4 (const unsigned char * dev_wwn ,
87- struct se_device * * found_dev )
81+ static int target_xcopy_locate_se_dev_e4 (struct se_session * sess ,
82+ const unsigned char * dev_wwn ,
83+ struct se_device * * _found_dev ,
84+ struct percpu_ref * * _found_lun_ref )
8885{
89- struct xcopy_dev_search_info info ;
90- int ret ;
91-
92- memset (& info , 0 , sizeof (info ));
93- info .dev_wwn = dev_wwn ;
94-
95- ret = target_for_each_device (target_xcopy_locate_se_dev_e4_iter , & info );
96- if (ret == 1 ) {
97- * found_dev = info .found_dev ;
98- return 0 ;
99- } else {
100- pr_debug_ratelimited ("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n" );
101- return - EINVAL ;
86+ struct se_dev_entry * deve ;
87+ struct se_node_acl * nacl ;
88+ struct se_lun * this_lun = NULL ;
89+ struct se_device * found_dev = NULL ;
90+
91+ /* cmd with NULL sess indicates no associated $FABRIC_MOD */
92+ if (!sess )
93+ goto err_out ;
94+
95+ pr_debug ("XCOPY 0xe4: searching for: %*ph\n" ,
96+ XCOPY_NAA_IEEE_REGEX_LEN , dev_wwn );
97+
98+ nacl = sess -> se_node_acl ;
99+ rcu_read_lock ();
100+ hlist_for_each_entry_rcu (deve , & nacl -> lun_entry_hlist , link ) {
101+ struct se_device * this_dev ;
102+ int rc ;
103+
104+ this_lun = rcu_dereference (deve -> se_lun );
105+ this_dev = rcu_dereference_raw (this_lun -> lun_se_dev );
106+
107+ rc = target_xcopy_locate_se_dev_e4_iter (this_dev , dev_wwn );
108+ if (rc ) {
109+ if (percpu_ref_tryget_live (& this_lun -> lun_ref ))
110+ found_dev = this_dev ;
111+ break ;
112+ }
102113 }
114+ rcu_read_unlock ();
115+ if (found_dev == NULL )
116+ goto err_out ;
117+
118+ pr_debug ("lun_ref held for se_dev: %p se_dev->se_dev_group: %p\n" ,
119+ found_dev , & found_dev -> dev_group );
120+ * _found_dev = found_dev ;
121+ * _found_lun_ref = & this_lun -> lun_ref ;
122+ return 0 ;
123+ err_out :
124+ pr_debug_ratelimited ("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n" );
125+ return - EINVAL ;
103126}
104127
105128static int target_xcopy_parse_tiddesc_e4 (struct se_cmd * se_cmd , struct xcopy_op * xop ,
@@ -246,12 +269,16 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd,
246269
247270 switch (xop -> op_origin ) {
248271 case XCOL_SOURCE_RECV_OP :
249- rc = target_xcopy_locate_se_dev_e4 (xop -> dst_tid_wwn ,
250- & xop -> dst_dev );
272+ rc = target_xcopy_locate_se_dev_e4 (se_cmd -> se_sess ,
273+ xop -> dst_tid_wwn ,
274+ & xop -> dst_dev ,
275+ & xop -> remote_lun_ref );
251276 break ;
252277 case XCOL_DEST_RECV_OP :
253- rc = target_xcopy_locate_se_dev_e4 (xop -> src_tid_wwn ,
254- & xop -> src_dev );
278+ rc = target_xcopy_locate_se_dev_e4 (se_cmd -> se_sess ,
279+ xop -> src_tid_wwn ,
280+ & xop -> src_dev ,
281+ & xop -> remote_lun_ref );
255282 break ;
256283 default :
257284 pr_err ("XCOPY CSCD descriptor IDs not found in CSCD list - "
@@ -391,18 +418,12 @@ static int xcopy_pt_get_cmd_state(struct se_cmd *se_cmd)
391418
392419static void xcopy_pt_undepend_remotedev (struct xcopy_op * xop )
393420{
394- struct se_device * remote_dev ;
395-
396421 if (xop -> op_origin == XCOL_SOURCE_RECV_OP )
397- remote_dev = xop -> dst_dev ;
422+ pr_debug ( "putting dst lun_ref for %p\n" , xop -> dst_dev ) ;
398423 else
399- remote_dev = xop -> src_dev ;
400-
401- pr_debug ("Calling configfs_undepend_item for"
402- " remote_dev: %p remote_dev->dev_group: %p\n" ,
403- remote_dev , & remote_dev -> dev_group .cg_item );
424+ pr_debug ("putting src lun_ref for %p\n" , xop -> src_dev );
404425
405- target_undepend_item ( & remote_dev -> dev_group . cg_item );
426+ percpu_ref_put ( xop -> remote_lun_ref );
406427}
407428
408429static void xcopy_pt_release_cmd (struct se_cmd * se_cmd )
0 commit comments