Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ddcf807f authored by Dan Williams's avatar Dan Williams Committed by Greg Kroah-Hartman
Browse files

libnvdimm/region: Fix label activation vs errors



commit d9cee9f85b22fab88d2b76d2e92b18e3d0e6aa8c upstream.

There are a few scenarios where init_active_labels() can return without
registering deactivate_labels() to run when the region is disabled. In
particular label error injection creates scenarios where a DIMM is
disabled, but labels on other DIMMs in the region become activated.

Arrange for init_active_labels() to always register deactivate_labels().

Reported-by: default avatarKrzysztof Kensicki <krzysztof.kensicki@intel.com>
Cc: <stable@vger.kernel.org>
Fixes: bf9bccc1 ("libnvdimm: pmem label sets and namespace instantiation.")
Reviewed-by: default avatarJeff Moyer <jmoyer@redhat.com>
Link: https://lore.kernel.org/r/162766356450.3223041.1183118139023841447.stgit@dwillia2-desk3.amr.corp.intel.com


Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bc97fde4
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -2486,7 +2486,7 @@ static void deactivate_labels(void *region)

static int init_active_labels(struct nd_region *nd_region)
{
	int i;
	int i, rc = 0;

	for (i = 0; i < nd_region->ndr_mappings; i++) {
		struct nd_mapping *nd_mapping = &nd_region->mapping[i];
@@ -2505,13 +2505,14 @@ static int init_active_labels(struct nd_region *nd_region)
			else if (test_bit(NDD_ALIASING, &nvdimm->flags))
				/* fail, labels needed to disambiguate dpa */;
			else
				return 0;
				continue;

			dev_err(&nd_region->dev, "%s: is %s, failing probe\n",
					dev_name(&nd_mapping->nvdimm->dev),
					test_bit(NDD_LOCKED, &nvdimm->flags)
					? "locked" : "disabled");
			return -ENXIO;
			rc = -ENXIO;
			goto out;
		}
		nd_mapping->ndd = ndd;
		atomic_inc(&nvdimm->busy);
@@ -2545,9 +2546,13 @@ static int init_active_labels(struct nd_region *nd_region)
			break;
	}

	if (i < nd_region->ndr_mappings) {
	if (i < nd_region->ndr_mappings)
		rc = -ENOMEM;

out:
	if (rc) {
		deactivate_labels(nd_region);
		return -ENOMEM;
		return rc;
	}

	return devm_add_action_or_reset(&nd_region->dev, deactivate_labels,