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

Commit ab45e763 authored by Vishal Verma's avatar Vishal Verma Committed by Dan Williams
Browse files

libnvdimm, btt: consolidate arena validation



Use arena_is_valid as a common routine for checking the validity of an
info block from both discover_arenas, and nd_btt_probe.

As a result, don't check for validity of the BTT's UUID, and lbasize.
The checksum in the BTT info block guarantees self-consistency, and when
we're called from nd_btt_probe, we don't have a valid uuid or lbasize
available to check against.

Also cleanup to return a bool instead of an int.

Signed-off-by: default avatarVishal Verma <vishal.l.verma@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent fbde1414
Loading
Loading
Loading
Loading
+1 −27
Original line number Diff line number Diff line
@@ -582,32 +582,6 @@ static void free_arenas(struct btt *btt)
	}
}

/*
 * This function checks if the metadata layout is valid and error free
 */
static int arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super)
{
	u64 checksum;

	if (memcmp(super->uuid, nd_btt->uuid, 16))
		return 0;

	checksum = le64_to_cpu(super->checksum);
	super->checksum = 0;
	if (checksum != nd_btt_sb_checksum(super))
		return 0;
	super->checksum = cpu_to_le64(checksum);

	if (nd_btt->lbasize != le32_to_cpu(super->external_lbasize))
		return 0;

	/* TODO: figure out action for this */
	if ((le32_to_cpu(super->flags) & IB_FLAG_ERROR_MASK) != 0)
		dev_info(&nd_btt->dev, "Found arena with an error flag\n");

	return 1;
}

/*
 * This function reads an existing valid btt superblock and
 * populates the corresponding arena_info struct
@@ -665,7 +639,7 @@ static int discover_arenas(struct btt *btt)
		if (ret)
			goto out;

		if (!arena_is_valid(btt->nd_btt, super)) {
		if (!nd_btt_arena_is_valid(btt->nd_btt, super)) {
			if (remaining == btt->rawsize) {
				btt->init_state = INIT_NOTFOUND;
				dev_info(to_dev(arena), "No existing arenas\n");
+3 −0
Original line number Diff line number Diff line
@@ -182,4 +182,7 @@ struct btt {
	int init_state;
	int num_arenas;
};

bool nd_btt_arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super);

#endif
+33 −9
Original line number Diff line number Diff line
@@ -342,6 +342,38 @@ struct device *nd_btt_create(struct nd_region *nd_region)
	return dev;
}

/**
 * nd_btt_arena_is_valid - check if the metadata layout is valid
 * @nd_btt:	device with BTT geometry and backing device info
 * @super:	pointer to the arena's info block being tested
 *
 * Check consistency of the btt info block with itself by validating
 * the checksum.
 *
 * Returns:
 * false for an invalid info block, true for a valid one
 */
bool nd_btt_arena_is_valid(struct nd_btt *nd_btt, struct btt_sb *super)
{
	u64 checksum;

	if (memcmp(super->signature, BTT_SIG, BTT_SIG_LEN) != 0)
		return false;

	checksum = le64_to_cpu(super->checksum);
	super->checksum = 0;
	if (checksum != nd_btt_sb_checksum(super))
		return false;
	super->checksum = cpu_to_le64(checksum);

	/* TODO: figure out action for this */
	if ((le32_to_cpu(super->flags) & IB_FLAG_ERROR_MASK) != 0)
		dev_info(&nd_btt->dev, "Found arena with an error flag\n");

	return true;
}
EXPORT_SYMBOL(nd_btt_arena_is_valid);

/*
 * nd_btt_sb_checksum: compute checksum for btt info block
 *
@@ -364,8 +396,6 @@ EXPORT_SYMBOL(nd_btt_sb_checksum);
static int __nd_btt_probe(struct nd_btt *nd_btt,
		struct nd_namespace_common *ndns, struct btt_sb *btt_sb)
{
	u64 checksum;

	if (!btt_sb || !ndns || !nd_btt)
		return -ENODEV;

@@ -375,14 +405,8 @@ static int __nd_btt_probe(struct nd_btt *nd_btt,
	if (nvdimm_namespace_capacity(ndns) < SZ_16M)
		return -ENXIO;

	if (memcmp(btt_sb->signature, BTT_SIG, BTT_SIG_LEN) != 0)
		return -ENODEV;

	checksum = le64_to_cpu(btt_sb->checksum);
	btt_sb->checksum = 0;
	if (checksum != nd_btt_sb_checksum(btt_sb))
	if (!nd_btt_arena_is_valid(nd_btt, btt_sb))
		return -ENODEV;
	btt_sb->checksum = cpu_to_le64(checksum);

	nd_btt->lbasize = le32_to_cpu(btt_sb->external_lbasize);
	nd_btt->uuid = kmemdup(btt_sb->uuid, 16, GFP_KERNEL);