Skip to content

Commit fe506a7

Browse files
igawkeithbusch
authored andcommitted
nvmet-fc: take ref count on tgtport before delete assoc
We have to ensure that the tgtport is not going away before be have remove all the associations. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Daniel Wagner <dwagner@suse.de> Signed-off-by: Keith Busch <kbusch@kernel.org>
1 parent 710c69d commit fe506a7

File tree

1 file changed

+23
-8
lines changed
  • drivers/nvme/target

1 file changed

+23
-8
lines changed

drivers/nvme/target/fc.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,13 +1090,28 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
10901090
}
10911091

10921092
static void
1093-
nvmet_fc_delete_assoc(struct work_struct *work)
1093+
nvmet_fc_delete_assoc(struct nvmet_fc_tgt_assoc *assoc)
1094+
{
1095+
nvmet_fc_delete_target_assoc(assoc);
1096+
nvmet_fc_tgt_a_put(assoc);
1097+
}
1098+
1099+
static void
1100+
nvmet_fc_delete_assoc_work(struct work_struct *work)
10941101
{
10951102
struct nvmet_fc_tgt_assoc *assoc =
10961103
container_of(work, struct nvmet_fc_tgt_assoc, del_work);
1104+
struct nvmet_fc_tgtport *tgtport = assoc->tgtport;
10971105

1098-
nvmet_fc_delete_target_assoc(assoc);
1099-
nvmet_fc_tgt_a_put(assoc);
1106+
nvmet_fc_delete_assoc(assoc);
1107+
nvmet_fc_tgtport_put(tgtport);
1108+
}
1109+
1110+
static void
1111+
nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc)
1112+
{
1113+
nvmet_fc_tgtport_get(assoc->tgtport);
1114+
queue_work(nvmet_wq, &assoc->del_work);
11001115
}
11011116

11021117
static struct nvmet_fc_tgt_assoc *
@@ -1127,7 +1142,7 @@ nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle)
11271142
assoc->a_id = idx;
11281143
INIT_LIST_HEAD(&assoc->a_list);
11291144
kref_init(&assoc->ref);
1130-
INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc);
1145+
INIT_WORK(&assoc->del_work, nvmet_fc_delete_assoc_work);
11311146
atomic_set(&assoc->terminating, 0);
11321147

11331148
while (needrandom) {
@@ -1483,7 +1498,7 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport)
14831498
list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) {
14841499
if (!nvmet_fc_tgt_a_get(assoc))
14851500
continue;
1486-
queue_work(nvmet_wq, &assoc->del_work);
1501+
nvmet_fc_schedule_delete_assoc(assoc);
14871502
nvmet_fc_tgt_a_put(assoc);
14881503
}
14891504
rcu_read_unlock();
@@ -1536,7 +1551,7 @@ nvmet_fc_invalidate_host(struct nvmet_fc_target_port *target_port,
15361551
continue;
15371552
assoc->hostport->invalid = 1;
15381553
noassoc = false;
1539-
queue_work(nvmet_wq, &assoc->del_work);
1554+
nvmet_fc_schedule_delete_assoc(assoc);
15401555
nvmet_fc_tgt_a_put(assoc);
15411556
}
15421557
spin_unlock_irqrestore(&tgtport->lock, flags);
@@ -1581,7 +1596,7 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl)
15811596
nvmet_fc_tgtport_put(tgtport);
15821597

15831598
if (found_ctrl) {
1584-
queue_work(nvmet_wq, &assoc->del_work);
1599+
nvmet_fc_schedule_delete_assoc(assoc);
15851600
nvmet_fc_tgt_a_put(assoc);
15861601
return;
15871602
}
@@ -1888,7 +1903,7 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
18881903
nvmet_fc_xmt_ls_rsp(tgtport, oldls);
18891904
}
18901905

1891-
queue_work(nvmet_wq, &assoc->del_work);
1906+
nvmet_fc_schedule_delete_assoc(assoc);
18921907
nvmet_fc_tgt_a_put(assoc);
18931908

18941909
return false;

0 commit comments

Comments
 (0)