In preparation to limit the scope of the list iterator to the list traversal loop, use a dedicated pointer pointing to the found element [1].
If no break is hit or the list is empty, 'label_ent' will be a bogus pointer computed based on the head of the list. In such a case &label_ent->list == &nd_mapping->labels, which will break the list properties when passed to list_move(). Therefore list_move() is only called if it is actually guaranteed that an element was found within the list iteration. Link: https://lore.kernel.org/all/yhdfeiwi4edth...@kroah.com/ Signed-off-by: Jakob Koschel <jakobkosc...@gmail.com> --- drivers/nvdimm/namespace_devs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index b57a2d36c517..b2841e723bc3 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1894,15 +1894,17 @@ static int select_pmem_id(struct nd_region *nd_region, const uuid_t *pmem_id) struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); struct nd_namespace_label *nd_label = NULL; u64 hw_start, hw_end, pmem_start, pmem_end; - struct nd_label_ent *label_ent; + struct nd_label_ent *label_ent = NULL, *iter; lockdep_assert_held(&nd_mapping->lock); - list_for_each_entry(label_ent, &nd_mapping->labels, list) { - nd_label = label_ent->label; + list_for_each_entry(iter, &nd_mapping->labels, list) { + nd_label = iter->label; if (!nd_label) continue; - if (nsl_uuid_equal(ndd, nd_label, pmem_id)) + if (nsl_uuid_equal(ndd, nd_label, pmem_id)) { + label_ent = iter; break; + } nd_label = NULL; } @@ -1930,7 +1932,8 @@ static int select_pmem_id(struct nd_region *nd_region, const uuid_t *pmem_id) } /* move recently validated label to the front of the list */ - list_move(&label_ent->list, &nd_mapping->labels); + if (label_ent) + list_move(&label_ent->list, &nd_mapping->labels); } return 0; } base-commit: 34e047aa16c0123bbae8e2f6df33e5ecc1f56601 -- 2.25.1