@@ -208,6 +208,7 @@ struct fcloop_lport {
208208 struct nvme_fc_local_port * localport ;
209209 struct list_head lport_list ;
210210 struct completion unreg_done ;
211+ refcount_t ref ;
211212};
212213
213214struct fcloop_lport_priv {
@@ -239,7 +240,7 @@ struct fcloop_nport {
239240 struct fcloop_tport * tport ;
240241 struct fcloop_lport * lport ;
241242 struct list_head nport_list ;
242- struct kref ref ;
243+ refcount_t ref ;
243244 u64 node_name ;
244245 u64 port_name ;
245246 u32 port_role ;
@@ -274,7 +275,7 @@ struct fcloop_fcpreq {
274275 u32 inistate ;
275276 bool active ;
276277 bool aborted ;
277- struct kref ref ;
278+ refcount_t ref ;
278279 struct work_struct fcp_rcv_work ;
279280 struct work_struct abort_rcv_work ;
280281 struct work_struct tio_done_work ;
@@ -478,7 +479,7 @@ fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport,
478479 if (targetport ) {
479480 tport = targetport -> private ;
480481 spin_lock (& tport -> lock );
481- list_add_tail (& tport -> ls_list , & tls_req -> ls_list );
482+ list_add_tail (& tls_req -> ls_list , & tport -> ls_list );
482483 spin_unlock (& tport -> lock );
483484 queue_work (nvmet_wq , & tport -> ls_work );
484485 }
@@ -534,24 +535,18 @@ fcloop_tgt_discovery_evt(struct nvmet_fc_target_port *tgtport)
534535}
535536
536537static void
537- fcloop_tfcp_req_free (struct kref * ref )
538+ fcloop_tfcp_req_put (struct fcloop_fcpreq * tfcp_req )
538539{
539- struct fcloop_fcpreq * tfcp_req =
540- container_of ( ref , struct fcloop_fcpreq , ref ) ;
540+ if (! refcount_dec_and_test ( & tfcp_req -> ref ))
541+ return ;
541542
542543 kfree (tfcp_req );
543544}
544545
545- static void
546- fcloop_tfcp_req_put (struct fcloop_fcpreq * tfcp_req )
547- {
548- kref_put (& tfcp_req -> ref , fcloop_tfcp_req_free );
549- }
550-
551546static int
552547fcloop_tfcp_req_get (struct fcloop_fcpreq * tfcp_req )
553548{
554- return kref_get_unless_zero (& tfcp_req -> ref );
549+ return refcount_inc_not_zero (& tfcp_req -> ref );
555550}
556551
557552static void
@@ -748,7 +743,7 @@ fcloop_fcp_req(struct nvme_fc_local_port *localport,
748743 INIT_WORK (& tfcp_req -> fcp_rcv_work , fcloop_fcp_recv_work );
749744 INIT_WORK (& tfcp_req -> abort_rcv_work , fcloop_fcp_abort_recv_work );
750745 INIT_WORK (& tfcp_req -> tio_done_work , fcloop_tgt_fcprqst_done_work );
751- kref_init (& tfcp_req -> ref );
746+ refcount_set (& tfcp_req -> ref , 1 );
752747
753748 queue_work (nvmet_wq , & tfcp_req -> fcp_rcv_work );
754749
@@ -1001,24 +996,39 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport,
1001996}
1002997
1003998static void
1004- fcloop_nport_free (struct kref * ref )
999+ fcloop_lport_put (struct fcloop_lport * lport )
10051000{
1006- struct fcloop_nport * nport =
1007- container_of (ref , struct fcloop_nport , ref );
1001+ unsigned long flags ;
10081002
1009- kfree (nport );
1003+ if (!refcount_dec_and_test (& lport -> ref ))
1004+ return ;
1005+
1006+ spin_lock_irqsave (& fcloop_lock , flags );
1007+ list_del (& lport -> lport_list );
1008+ spin_unlock_irqrestore (& fcloop_lock , flags );
1009+
1010+ kfree (lport );
1011+ }
1012+
1013+ static int
1014+ fcloop_lport_get (struct fcloop_lport * lport )
1015+ {
1016+ return refcount_inc_not_zero (& lport -> ref );
10101017}
10111018
10121019static void
10131020fcloop_nport_put (struct fcloop_nport * nport )
10141021{
1015- kref_put (& nport -> ref , fcloop_nport_free );
1022+ if (!refcount_dec_and_test (& nport -> ref ))
1023+ return ;
1024+
1025+ kfree (nport );
10161026}
10171027
10181028static int
10191029fcloop_nport_get (struct fcloop_nport * nport )
10201030{
1021- return kref_get_unless_zero (& nport -> ref );
1031+ return refcount_inc_not_zero (& nport -> ref );
10221032}
10231033
10241034static void
@@ -1029,6 +1039,8 @@ fcloop_localport_delete(struct nvme_fc_local_port *localport)
10291039
10301040 /* release any threads waiting for the unreg to complete */
10311041 complete (& lport -> unreg_done );
1042+
1043+ fcloop_lport_put (lport );
10321044}
10331045
10341046static void
@@ -1140,6 +1152,7 @@ fcloop_create_local_port(struct device *dev, struct device_attribute *attr,
11401152
11411153 lport -> localport = localport ;
11421154 INIT_LIST_HEAD (& lport -> lport_list );
1155+ refcount_set (& lport -> ref , 1 );
11431156
11441157 spin_lock_irqsave (& fcloop_lock , flags );
11451158 list_add_tail (& lport -> lport_list , & fcloop_lports );
@@ -1156,13 +1169,6 @@ fcloop_create_local_port(struct device *dev, struct device_attribute *attr,
11561169 return ret ? ret : count ;
11571170}
11581171
1159-
1160- static void
1161- __unlink_local_port (struct fcloop_lport * lport )
1162- {
1163- list_del (& lport -> lport_list );
1164- }
1165-
11661172static int
11671173__wait_localport_unreg (struct fcloop_lport * lport )
11681174{
@@ -1175,8 +1181,6 @@ __wait_localport_unreg(struct fcloop_lport *lport)
11751181 if (!ret )
11761182 wait_for_completion (& lport -> unreg_done );
11771183
1178- kfree (lport );
1179-
11801184 return ret ;
11811185}
11821186
@@ -1199,8 +1203,9 @@ fcloop_delete_local_port(struct device *dev, struct device_attribute *attr,
11991203 list_for_each_entry (tlport , & fcloop_lports , lport_list ) {
12001204 if (tlport -> localport -> node_name == nodename &&
12011205 tlport -> localport -> port_name == portname ) {
1206+ if (!fcloop_lport_get (tlport ))
1207+ break ;
12021208 lport = tlport ;
1203- __unlink_local_port (lport );
12041209 break ;
12051210 }
12061211 }
@@ -1210,6 +1215,7 @@ fcloop_delete_local_port(struct device *dev, struct device_attribute *attr,
12101215 return - ENOENT ;
12111216
12121217 ret = __wait_localport_unreg (lport );
1218+ fcloop_lport_put (lport );
12131219
12141220 return ret ? ret : count ;
12151221}
@@ -1249,7 +1255,7 @@ fcloop_alloc_nport(const char *buf, size_t count, bool remoteport)
12491255 newnport -> port_role = opts -> roles ;
12501256 if (opts -> mask & NVMF_OPT_FCADDR )
12511257 newnport -> port_id = opts -> fcaddr ;
1252- kref_init (& newnport -> ref );
1258+ refcount_set (& newnport -> ref , 1 );
12531259
12541260 spin_lock_irqsave (& fcloop_lock , flags );
12551261
@@ -1637,17 +1643,17 @@ static void __exit fcloop_exit(void)
16371643 for (;;) {
16381644 lport = list_first_entry_or_null (& fcloop_lports ,
16391645 typeof (* lport ), lport_list );
1640- if (!lport )
1646+ if (!lport || ! fcloop_lport_get ( lport ) )
16411647 break ;
16421648
1643- __unlink_local_port (lport );
1644-
16451649 spin_unlock_irqrestore (& fcloop_lock , flags );
16461650
16471651 ret = __wait_localport_unreg (lport );
16481652 if (ret )
16491653 pr_warn ("%s: Failed deleting local port\n" , __func__ );
16501654
1655+ fcloop_lport_put (lport );
1656+
16511657 spin_lock_irqsave (& fcloop_lock , flags );
16521658 }
16531659
0 commit comments