192 lines
4.5 KiB
C
192 lines
4.5 KiB
C
|
#include <linux/module.h>
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/init.h>
|
||
|
#include <linux/proc_fs.h>
|
||
|
#include <linux/highmem.h>
|
||
|
#include <linux/kdev_t.h>
|
||
|
#include <linux/sysfs.h>
|
||
|
#include <linux/kobject.h>
|
||
|
|
||
|
#include "dm-verity-debug.h"
|
||
|
|
||
|
#define ALTA_BUF_SIZE 4096
|
||
|
|
||
|
static DEFINE_SPINLOCK(alta_lock);
|
||
|
|
||
|
char* alta_buf;
|
||
|
size_t * alta_offset,alta_size;
|
||
|
|
||
|
struct kobject *kobj_ref;
|
||
|
|
||
|
|
||
|
void set_print_buf(char * buf, size_t * offset, size_t size){
|
||
|
alta_buf = buf;
|
||
|
alta_offset = offset;
|
||
|
alta_size = size;
|
||
|
|
||
|
*alta_offset = 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
void alta_print(const char *fmt, ...)
|
||
|
{
|
||
|
size_t offset = *alta_offset;
|
||
|
|
||
|
va_list aptr;
|
||
|
va_start(aptr, fmt);
|
||
|
*alta_offset += vscnprintf(alta_buf+offset,(size_t)alta_size - offset, fmt, aptr);
|
||
|
va_end(aptr);
|
||
|
}
|
||
|
|
||
|
static void show_fc_blks_list(void){
|
||
|
int i = 0;
|
||
|
|
||
|
if(empty_b_info()){
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if(get_fec_correct_blks() == 0){
|
||
|
alta_print("\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ((long long) MAX_FC_BLKS_LIST <= get_fec_correct_blks()){
|
||
|
alta_print(",\"fc_dev\":\"%s\"",b_info->dev_name[b_info->list_idx]);
|
||
|
alta_print(",\"fc_blk\":\"%llu\"",b_info->fc_blks_list[b_info->list_idx]);
|
||
|
i = (b_info->list_idx + 1) % MAX_FC_BLKS_LIST;
|
||
|
}
|
||
|
|
||
|
|
||
|
for( ; i != b_info->list_idx; i = (i + 1) % MAX_FC_BLKS_LIST){
|
||
|
alta_print(",\"fc_dev\":\"%s\"",b_info->dev_name[i]);
|
||
|
alta_print(",\"fc_blk\":\"%llu\"",b_info->fc_blks_list[i]);
|
||
|
}
|
||
|
alta_print("\n");
|
||
|
}
|
||
|
|
||
|
static void show_dmv_ctr_list(void){
|
||
|
int i = 0, ctr_cnt = get_dmv_ctr_cnt();
|
||
|
|
||
|
if(empty_b_info()){
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
alta_print(",\"dmv_dev_cnt\":\"%d\"",ctr_cnt);
|
||
|
|
||
|
for( ; i < ctr_cnt; i++)
|
||
|
alta_print(",\"dmv_dev\":\"%s\"",b_info->dmv_ctr_list[i]);
|
||
|
}
|
||
|
|
||
|
static void show_blks_cnt(void){
|
||
|
int i,foc = get_fec_off_cnt();
|
||
|
|
||
|
if(empty_b_info()){
|
||
|
return;
|
||
|
}
|
||
|
alta_print("\"total_blks\":\"%llu\"",get_total_blks());
|
||
|
alta_print(",\"skipped_blks\":\"%llu\"",get_skipped_blks());
|
||
|
alta_print(",\"corrupted_blks\":\"%llu\"",get_corrupted_blks());
|
||
|
alta_print(",\"fec_correct_blks\":\"%llu\"",get_fec_correct_blks());
|
||
|
|
||
|
if(foc > 0){
|
||
|
alta_print(",\"fec_off_cnt\":\"%d\"",foc);
|
||
|
for(i = 0 ; i < foc; i++)
|
||
|
alta_print(",\"fec_off_dev\":\"%s\"",b_info->fec_off_list[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
ssize_t alta_bigdata_read(struct file *filep, char __user *buf, size_t size, loff_t *offset){
|
||
|
ssize_t ret;
|
||
|
size_t proc_offset = 0;
|
||
|
char* proc_buf = kzalloc(ALTA_BUF_SIZE, GFP_KERNEL);
|
||
|
|
||
|
if (!proc_buf)
|
||
|
return -ENOMEM;
|
||
|
|
||
|
spin_lock(&alta_lock);
|
||
|
set_print_buf(proc_buf,&proc_offset,ALTA_BUF_SIZE);
|
||
|
|
||
|
/* Print DMV info */
|
||
|
if(empty_b_info()){
|
||
|
alta_print("\"ERROR\":\"b_info_empty\"\n");
|
||
|
}
|
||
|
else {
|
||
|
show_blks_cnt();
|
||
|
show_dmv_ctr_list();
|
||
|
show_fc_blks_list();
|
||
|
}
|
||
|
spin_unlock(&alta_lock);
|
||
|
|
||
|
ret = simple_read_from_buffer(buf, size, offset, proc_buf, proc_offset);
|
||
|
kfree(proc_buf);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static ssize_t sysfs_show(struct kobject *kobj,
|
||
|
struct kobj_attribute *attr, char *buf)
|
||
|
{
|
||
|
size_t sysfs_offset;
|
||
|
set_print_buf(buf, &sysfs_offset, PAGE_SIZE);
|
||
|
|
||
|
/* Print DMV info */
|
||
|
if(empty_b_info()){
|
||
|
alta_print("\"ERROR\":\"b_info_empty\"\n");
|
||
|
}
|
||
|
else {
|
||
|
show_blks_cnt();
|
||
|
show_dmv_ctr_list();
|
||
|
show_fc_blks_list();
|
||
|
}
|
||
|
|
||
|
return sysfs_offset;
|
||
|
}
|
||
|
|
||
|
|
||
|
static const struct file_operations alta_proc_fops = {
|
||
|
.owner = THIS_MODULE,
|
||
|
.read = alta_bigdata_read,
|
||
|
};
|
||
|
|
||
|
struct kobj_attribute alta_attr = __ATTR(dmv_info, 0444, sysfs_show, NULL);
|
||
|
|
||
|
static int __init alta_bigdata_init(void){
|
||
|
if(proc_create("alta_bigdata",0444,NULL,&alta_proc_fops) == NULL){
|
||
|
printk(KERN_ERR "alta_bigdata: Error creating proc entry");
|
||
|
goto bad_proc;
|
||
|
}
|
||
|
|
||
|
/*Creating a directory in /sys/kernel/ */
|
||
|
kobj_ref = kobject_create_and_add("alta_bigdata",kernel_kobj);
|
||
|
|
||
|
/*Creating sysfs file for dmv_info*/
|
||
|
if(sysfs_create_file(kobj_ref,&alta_attr.attr)){
|
||
|
printk(KERN_INFO"alta_bigdata: Cannot create sysfs file......\n");
|
||
|
goto bad_sysfs;
|
||
|
}
|
||
|
|
||
|
pr_info("alta_bigdata : create /proc/alta_bigdata");
|
||
|
return 0;
|
||
|
|
||
|
bad_sysfs:
|
||
|
kobject_put(kobj_ref);
|
||
|
sysfs_remove_file(kernel_kobj, &alta_attr.attr);
|
||
|
|
||
|
bad_proc:
|
||
|
free_b_info();
|
||
|
remove_proc_entry("alta_bigdata", NULL);
|
||
|
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
static void __exit alta_bigdata_exit(void){
|
||
|
kobject_put(kobj_ref);
|
||
|
sysfs_remove_file(kernel_kobj, &alta_attr.attr);
|
||
|
|
||
|
free_b_info();
|
||
|
remove_proc_entry("alta_bigdata", NULL);
|
||
|
}
|
||
|
module_init(alta_bigdata_init);
|
||
|
module_exit(alta_bigdata_exit);
|