Skip to content

Commit 72511b1

Browse files
igawChristoph Hellwig
authored andcommitted
nvmet-fcloop: add ref counting to lport
The fcloop_lport objects live time is controlled by the user interface add_local_port and del_local_port. nport, rport and tport objects are pointing to the lport objects but here is no clear tracking. Let's introduce an explicit ref counter for the lport objects and prepare the stage for restructuring how lports are used. Signed-off-by: Daniel Wagner <wagi@kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
1 parent f22c458 commit 72511b1

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

drivers/nvme/target/fcloop.c

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

213214
struct fcloop_lport_priv {
@@ -994,6 +995,27 @@ fcloop_fcp_abort(struct nvme_fc_local_port *localport,
994995
}
995996
}
996997

998+
static void
999+
fcloop_lport_put(struct fcloop_lport *lport)
1000+
{
1001+
unsigned long flags;
1002+
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);
1017+
}
1018+
9971019
static void
9981020
fcloop_nport_put(struct fcloop_nport *nport)
9991021
{
@@ -1017,6 +1039,8 @@ fcloop_localport_delete(struct nvme_fc_local_port *localport)
10171039

10181040
/* release any threads waiting for the unreg to complete */
10191041
complete(&lport->unreg_done);
1042+
1043+
fcloop_lport_put(lport);
10201044
}
10211045

10221046
static void
@@ -1128,6 +1152,7 @@ fcloop_create_local_port(struct device *dev, struct device_attribute *attr,
11281152

11291153
lport->localport = localport;
11301154
INIT_LIST_HEAD(&lport->lport_list);
1155+
refcount_set(&lport->ref, 1);
11311156

11321157
spin_lock_irqsave(&fcloop_lock, flags);
11331158
list_add_tail(&lport->lport_list, &fcloop_lports);
@@ -1144,13 +1169,6 @@ fcloop_create_local_port(struct device *dev, struct device_attribute *attr,
11441169
return ret ? ret : count;
11451170
}
11461171

1147-
1148-
static void
1149-
__unlink_local_port(struct fcloop_lport *lport)
1150-
{
1151-
list_del(&lport->lport_list);
1152-
}
1153-
11541172
static int
11551173
__wait_localport_unreg(struct fcloop_lport *lport)
11561174
{
@@ -1163,8 +1181,6 @@ __wait_localport_unreg(struct fcloop_lport *lport)
11631181
if (!ret)
11641182
wait_for_completion(&lport->unreg_done);
11651183

1166-
kfree(lport);
1167-
11681184
return ret;
11691185
}
11701186

@@ -1187,8 +1203,9 @@ fcloop_delete_local_port(struct device *dev, struct device_attribute *attr,
11871203
list_for_each_entry(tlport, &fcloop_lports, lport_list) {
11881204
if (tlport->localport->node_name == nodename &&
11891205
tlport->localport->port_name == portname) {
1206+
if (!fcloop_lport_get(tlport))
1207+
break;
11901208
lport = tlport;
1191-
__unlink_local_port(lport);
11921209
break;
11931210
}
11941211
}
@@ -1198,6 +1215,7 @@ fcloop_delete_local_port(struct device *dev, struct device_attribute *attr,
11981215
return -ENOENT;
11991216

12001217
ret = __wait_localport_unreg(lport);
1218+
fcloop_lport_put(lport);
12011219

12021220
return ret ? ret : count;
12031221
}
@@ -1625,17 +1643,17 @@ static void __exit fcloop_exit(void)
16251643
for (;;) {
16261644
lport = list_first_entry_or_null(&fcloop_lports,
16271645
typeof(*lport), lport_list);
1628-
if (!lport)
1646+
if (!lport || !fcloop_lport_get(lport))
16291647
break;
16301648

1631-
__unlink_local_port(lport);
1632-
16331649
spin_unlock_irqrestore(&fcloop_lock, flags);
16341650

16351651
ret = __wait_localport_unreg(lport);
16361652
if (ret)
16371653
pr_warn("%s: Failed deleting local port\n", __func__);
16381654

1655+
fcloop_lport_put(lport);
1656+
16391657
spin_lock_irqsave(&fcloop_lock, flags);
16401658
}
16411659

0 commit comments

Comments
 (0)