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 Change-Id: I80547a2aa944af2fb9ffde002650482877ade31b Signed-off-by: Sami Tolvanen <samitolvanen@google.com> (cherry picked from commit 7911fad5f0a2cf5afc2215657219a21e6630e001) [AmitP: Folded following android-4.9 commit changes into this patch 3278f53e4658 ("ANDROID: dm verity fec: add missing release from fec_ktype")] Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
This commit is contained in:
parent
8e2c3ddc73
commit
8fe0ca37c8
2 changed files with 49 additions and 1 deletions
|
@ -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 @@ static int fec_decode_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio,
|
|||
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;
|
||||
}
|
||||
|
@ -545,6 +548,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;
|
||||
|
@ -561,6 +565,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;
|
||||
|
@ -649,6 +659,28 @@ 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,
|
||||
.release = dm_kobject_release
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocate dm_verity_fec for v->fec. Must be called before verity_fec_ctr.
|
||||
*/
|
||||
|
@ -672,8 +704,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;
|
||||
int ret;
|
||||
|
||||
|
@ -682,6 +716,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
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#ifndef DM_VERITY_FEC_H
|
||||
#define DM_VERITY_FEC_H
|
||||
|
||||
#include "dm.h"
|
||||
#include "dm-core.h"
|
||||
#include "dm-verity.h"
|
||||
#include <linux/rslib.h>
|
||||
|
||||
|
@ -51,6 +53,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 */
|
||||
|
|
Loading…
Reference in a new issue