1 // SPDX-License-Identifier: GPL-2.0-only
3 * This file is part of UBIFS.
5 * Copyright (C) 2021 Cisco Systems
7 * Author: Stefan Schaeckeler
21 struct attribute attr
;
22 enum attr_id_t attr_id
;
25 #define UBIFS_ATTR(_name, _mode, _id) \
26 static struct ubifs_attr ubifs_attr_##_name = { \
27 .attr = {.name = __stringify(_name), .mode = _mode }, \
28 .attr_id = attr_##_id, \
31 #define UBIFS_ATTR_FUNC(_name, _mode) UBIFS_ATTR(_name, _mode, _name)
33 UBIFS_ATTR_FUNC(errors_magic
, 0444);
34 UBIFS_ATTR_FUNC(errors_crc
, 0444);
35 UBIFS_ATTR_FUNC(errors_node
, 0444);
37 #define ATTR_LIST(name) (&ubifs_attr_##name.attr)
39 static struct attribute
*ubifs_attrs
[] = {
40 ATTR_LIST(errors_magic
),
41 ATTR_LIST(errors_node
),
42 ATTR_LIST(errors_crc
),
45 ATTRIBUTE_GROUPS(ubifs
);
47 static ssize_t
ubifs_attr_show(struct kobject
*kobj
,
48 struct attribute
*attr
, char *buf
)
50 struct ubifs_info
*sbi
= container_of(kobj
, struct ubifs_info
,
53 struct ubifs_attr
*a
= container_of(attr
, struct ubifs_attr
, attr
);
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
);
61 return sysfs_emit(buf
, "%u\n", sbi
->stats
->crc_errors
);
66 static void ubifs_sb_release(struct kobject
*kobj
)
68 struct ubifs_info
*c
= container_of(kobj
, struct ubifs_info
, kobj
);
70 complete(&c
->kobj_unregister
);
73 static const struct sysfs_ops ubifs_attr_ops
= {
74 .show
= ubifs_attr_show
,
77 static const struct kobj_type ubifs_sb_ktype
= {
78 .default_groups
= ubifs_groups
,
79 .sysfs_ops
= &ubifs_attr_ops
,
80 .release
= ubifs_sb_release
,
83 static const struct kobj_type ubifs_ktype
= {
84 .sysfs_ops
= &ubifs_attr_ops
,
87 static struct kset ubifs_kset
= {
88 .kobj
= {.ktype
= &ubifs_ktype
},
91 int ubifs_sysfs_register(struct ubifs_info
*c
)
94 char dfs_dir_name
[UBIFS_DFS_DIR_LEN
];
96 c
->stats
= kzalloc(sizeof(struct ubifs_stats_info
), GFP_KERNEL
);
101 n
= snprintf(dfs_dir_name
, UBIFS_DFS_DIR_LEN
, UBIFS_DFS_DIR_NAME
,
102 c
->vi
.ubi_num
, c
->vi
.vol_id
);
104 if (n
>= UBIFS_DFS_DIR_LEN
) {
105 /* The array size is too small */
110 c
->kobj
.kset
= &ubifs_kset
;
111 init_completion(&c
->kobj_unregister
);
113 ret
= kobject_init_and_add(&c
->kobj
, &ubifs_sb_ktype
, NULL
,
121 kobject_put(&c
->kobj
);
122 wait_for_completion(&c
->kobj_unregister
);
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
);
131 void ubifs_sysfs_unregister(struct ubifs_info
*c
)
133 kobject_del(&c
->kobj
);
134 kobject_put(&c
->kobj
);
135 wait_for_completion(&c
->kobj_unregister
);
140 int __init
ubifs_sysfs_init(void)
144 kobject_set_name(&ubifs_kset
.kobj
, "ubifs");
145 ubifs_kset
.kobj
.parent
= fs_kobj
;
146 ret
= kset_register(&ubifs_kset
);
148 kset_put(&ubifs_kset
);
153 void ubifs_sysfs_exit(void)
155 kset_unregister(&ubifs_kset
);