brintos

brintos / linux-shallow public Read only

0
0
Text · 3.2 KiB · aae3222 Raw
157 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * This file is part of UBIFS.4 *5 * Copyright (C) 2021 Cisco Systems6 *7 * Author: Stefan Schaeckeler8 */9 10 11#include <linux/fs.h>12#include "ubifs.h"13 14enum attr_id_t {15	attr_errors_magic,16	attr_errors_node,17	attr_errors_crc,18};19 20struct ubifs_attr {21	struct attribute attr;22	enum attr_id_t attr_id;23};24 25#define UBIFS_ATTR(_name, _mode, _id)					\26static struct ubifs_attr ubifs_attr_##_name = {				\27	.attr = {.name = __stringify(_name), .mode = _mode },		\28	.attr_id = attr_##_id,						\29}30 31#define UBIFS_ATTR_FUNC(_name, _mode) UBIFS_ATTR(_name, _mode, _name)32 33UBIFS_ATTR_FUNC(errors_magic, 0444);34UBIFS_ATTR_FUNC(errors_crc, 0444);35UBIFS_ATTR_FUNC(errors_node, 0444);36 37#define ATTR_LIST(name) (&ubifs_attr_##name.attr)38 39static struct attribute *ubifs_attrs[] = {40	ATTR_LIST(errors_magic),41	ATTR_LIST(errors_node),42	ATTR_LIST(errors_crc),43	NULL,44};45ATTRIBUTE_GROUPS(ubifs);46 47static ssize_t ubifs_attr_show(struct kobject *kobj,48			       struct attribute *attr, char *buf)49{50	struct ubifs_info *sbi = container_of(kobj, struct ubifs_info,51					      kobj);52 53	struct ubifs_attr *a = container_of(attr, struct ubifs_attr, attr);54 55	switch (a->attr_id) {56	case attr_errors_magic:57		return sysfs_emit(buf, "%u\n", sbi->stats->magic_errors);58	case attr_errors_node:59		return sysfs_emit(buf, "%u\n", sbi->stats->node_errors);60	case attr_errors_crc:61		return sysfs_emit(buf, "%u\n", sbi->stats->crc_errors);62	}63	return 0;64};65 66static void ubifs_sb_release(struct kobject *kobj)67{68	struct ubifs_info *c = container_of(kobj, struct ubifs_info, kobj);69 70	complete(&c->kobj_unregister);71}72 73static const struct sysfs_ops ubifs_attr_ops = {74	.show	= ubifs_attr_show,75};76 77static const struct kobj_type ubifs_sb_ktype = {78	.default_groups	= ubifs_groups,79	.sysfs_ops	= &ubifs_attr_ops,80	.release	= ubifs_sb_release,81};82 83static const struct kobj_type ubifs_ktype = {84	.sysfs_ops	= &ubifs_attr_ops,85};86 87static struct kset ubifs_kset = {88	.kobj	= {.ktype = &ubifs_ktype},89};90 91int ubifs_sysfs_register(struct ubifs_info *c)92{93	int ret, n;94	char dfs_dir_name[UBIFS_DFS_DIR_LEN];95 96	c->stats = kzalloc(sizeof(struct ubifs_stats_info), GFP_KERNEL);97	if (!c->stats) {98		ret = -ENOMEM;99		goto out_last;100	}101	n = snprintf(dfs_dir_name, UBIFS_DFS_DIR_LEN, UBIFS_DFS_DIR_NAME,102		     c->vi.ubi_num, c->vi.vol_id);103 104	if (n >= UBIFS_DFS_DIR_LEN) {105		/* The array size is too small */106		ret = -EINVAL;107		goto out_free;108	}109 110	c->kobj.kset = &ubifs_kset;111	init_completion(&c->kobj_unregister);112 113	ret = kobject_init_and_add(&c->kobj, &ubifs_sb_ktype, NULL,114				   "%s", dfs_dir_name);115	if (ret)116		goto out_put;117 118	return 0;119 120out_put:121	kobject_put(&c->kobj);122	wait_for_completion(&c->kobj_unregister);123out_free:124	kfree(c->stats);125out_last:126	ubifs_err(c, "cannot create sysfs entry for ubifs%d_%d, error %d\n",127		  c->vi.ubi_num, c->vi.vol_id, ret);128	return ret;129}130 131void ubifs_sysfs_unregister(struct ubifs_info *c)132{133	kobject_del(&c->kobj);134	kobject_put(&c->kobj);135	wait_for_completion(&c->kobj_unregister);136 137	kfree(c->stats);138}139 140int __init ubifs_sysfs_init(void)141{142	int ret;143 144	kobject_set_name(&ubifs_kset.kobj, "ubifs");145	ubifs_kset.kobj.parent = fs_kobj;146	ret = kset_register(&ubifs_kset);147	if (ret)148		kset_put(&ubifs_kset);149 150	return ret;151}152 153void ubifs_sysfs_exit(void)154{155	kset_unregister(&ubifs_kset);156}157