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

Commit 3833aeaf authored by Sami Tolvanen's avatar Sami Tolvanen Committed by Gerrit - the friendly Code Review server
Browse files

ANDROID: dm verity fec: add sysfs attribute fec/corrected



Add a sysfs entry that allows user space to determine whether dm-verity
has come across correctable errors on the underlying block device.

Bug: 22655252
Bug: 27928374
Signed-off-by: default avatarSami Tolvanen <samitolvanen@google.com>
(cherry picked from commit 7911fad5f0a2cf5afc2215657219a21e6630e001)

Change-Id: I02d36bed1d54eaf1f1750a919fa91f66a7e9b96c
Git-commit: 9cd83628
Git-repo: https://git.linaro.org/kernel/linux-linaro-stable.git


Signed-off-by: default avatarImran Khan <kimran@codeaurora.org>
parent 1a6b1e3e
Loading
Loading
Loading
Loading
+44 −1
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@

#include "dm-verity-fec.h"
#include <linux/math64.h>
#include <linux/sysfs.h>

#define DM_MSG_PREFIX	"verity-fec"

@@ -175,9 +176,11 @@ error:
	if (r < 0 && neras)
		DMERR_LIMIT("%s: FEC %llu: failed to correct: %d",
			    v->data_dev->name, (unsigned long long)rsb, r);
	else if (r > 0)
	else if (r > 0) {
		DMWARN_LIMIT("%s: FEC %llu: corrected %d errors",
			     v->data_dev->name, (unsigned long long)rsb, r);
		atomic_add_unless(&v->fec->corrected, 1, INT_MAX);
	}

	return r;
}
@@ -548,6 +551,7 @@ unsigned verity_fec_status_table(struct dm_verity *v, unsigned sz,
void verity_fec_dtr(struct dm_verity *v)
{
	struct dm_verity_fec *f = v->fec;
	struct kobject *kobj = &f->kobj_holder.kobj;

	if (!verity_fec_is_enabled(v))
		goto out;
@@ -564,6 +568,12 @@ void verity_fec_dtr(struct dm_verity *v)

	if (f->dev)
		dm_put_device(v->ti, f->dev);

	if (kobj->state_initialized) {
		kobject_put(kobj);
		wait_for_completion(dm_get_completion_from_kobject(kobj));
	}

out:
	kfree(f);
	v->fec = NULL;
@@ -652,6 +662,27 @@ int verity_fec_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
	return 0;
}

static ssize_t corrected_show(struct kobject *kobj, struct kobj_attribute *attr,
			      char *buf)
{
	struct dm_verity_fec *f = container_of(kobj, struct dm_verity_fec,
					       kobj_holder.kobj);

	return sprintf(buf, "%d\n", atomic_read(&f->corrected));
}

static struct kobj_attribute attr_corrected = __ATTR_RO(corrected);

static struct attribute *fec_attrs[] = {
	&attr_corrected.attr,
	NULL
};

static struct kobj_type fec_ktype = {
	.sysfs_ops = &kobj_sysfs_ops,
	.default_attrs = fec_attrs
};

/*
 * Allocate dm_verity_fec for v->fec. Must be called before verity_fec_ctr.
 */
@@ -675,8 +706,10 @@ int verity_fec_ctr_alloc(struct dm_verity *v)
 */
int verity_fec_ctr(struct dm_verity *v)
{
	int r;
	struct dm_verity_fec *f = v->fec;
	struct dm_target *ti = v->ti;
	struct mapped_device *md = dm_table_get_md(ti->table);
	u64 hash_blocks;

	if (!verity_fec_is_enabled(v)) {
@@ -684,6 +717,16 @@ int verity_fec_ctr(struct dm_verity *v)
		return 0;
	}

	/* Create a kobject and sysfs attributes */
	init_completion(&f->kobj_holder.completion);

	r = kobject_init_and_add(&f->kobj_holder.kobj, &fec_ktype,
				 &disk_to_dev(dm_disk(md))->kobj, "%s", "fec");
	if (r) {
		ti->error = "Cannot create kobject";
		return r;
	}

	/*
	 * FEC is computed over data blocks, possible metadata, and
	 * hash blocks. In other words, FEC covers total of fec_blocks
+3 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#ifndef DM_VERITY_FEC_H
#define DM_VERITY_FEC_H

#include "dm.h"
#include "dm-verity.h"
#include <linux/rslib.h>

@@ -48,6 +49,8 @@ struct dm_verity_fec {
	mempool_t *extra_pool;	/* mempool for extra buffers */
	mempool_t *output_pool;	/* mempool for output */
	struct kmem_cache *cache;	/* cache for buffers */
	atomic_t corrected;		/* corrected errors */
	struct dm_kobject_holder kobj_holder;	/* for sysfs attributes */
};

/* per-bio data */