Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * This file is part of UBIFS.
  4 *
  5 * Copyright (C) 2021 Cisco Systems
  6 *
  7 * Author: Stefan Schaeckeler
  8 */
  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}