-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ubifs: Export filesystem error counters
Not all ubifs filesystem errors are propagated to userspace. Export bad magic, bad node and crc errors via sysfs. This allows userspace to notice filesystem errors: /sys/fs/ubifs/ubiX_Y/errors_magic /sys/fs/ubifs/ubiX_Y/errors_node /sys/fs/ubifs/ubiX_Y/errors_crc The counters are reset to 0 with a remount. Signed-off-by: Stefan Schaeckeler <sschaeck@cisco.com> Signed-off-by: Richard Weinberger <richard@nod.at>
- Loading branch information
Stefan Schaeckeler
authored and
Richard Weinberger
committed
Oct 27, 2021
1 parent
e708759
commit 9a62029
Showing
5 changed files
with
225 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* This file is part of UBIFS. | ||
* | ||
* Copyright (C) 2021 Cisco Systems | ||
* | ||
* Author: Stefan Schaeckeler | ||
*/ | ||
|
||
|
||
#include <linux/fs.h> | ||
#include "ubifs.h" | ||
|
||
enum attr_id_t { | ||
attr_errors_magic, | ||
attr_errors_node, | ||
attr_errors_crc, | ||
}; | ||
|
||
struct ubifs_attr { | ||
struct attribute attr; | ||
enum attr_id_t attr_id; | ||
}; | ||
|
||
#define UBIFS_ATTR(_name, _mode, _id) \ | ||
static struct ubifs_attr ubifs_attr_##_name = { \ | ||
.attr = {.name = __stringify(_name), .mode = _mode }, \ | ||
.attr_id = attr_##_id, \ | ||
} | ||
|
||
#define UBIFS_ATTR_FUNC(_name, _mode) UBIFS_ATTR(_name, _mode, _name) | ||
|
||
UBIFS_ATTR_FUNC(errors_magic, 0444); | ||
UBIFS_ATTR_FUNC(errors_crc, 0444); | ||
UBIFS_ATTR_FUNC(errors_node, 0444); | ||
|
||
#define ATTR_LIST(name) (&ubifs_attr_##name.attr) | ||
|
||
static struct attribute *ubifs_attrs[] = { | ||
ATTR_LIST(errors_magic), | ||
ATTR_LIST(errors_node), | ||
ATTR_LIST(errors_crc), | ||
NULL, | ||
}; | ||
|
||
static ssize_t ubifs_attr_show(struct kobject *kobj, | ||
struct attribute *attr, char *buf) | ||
{ | ||
struct ubifs_info *sbi = container_of(kobj, struct ubifs_info, | ||
kobj); | ||
|
||
struct ubifs_attr *a = container_of(attr, struct ubifs_attr, attr); | ||
|
||
switch (a->attr_id) { | ||
case attr_errors_magic: | ||
return sysfs_emit(buf, "%u\n", sbi->stats->magic_errors); | ||
case attr_errors_node: | ||
return sysfs_emit(buf, "%u\n", sbi->stats->node_errors); | ||
case attr_errors_crc: | ||
return sysfs_emit(buf, "%u\n", sbi->stats->crc_errors); | ||
} | ||
return 0; | ||
}; | ||
|
||
static void ubifs_sb_release(struct kobject *kobj) | ||
{ | ||
struct ubifs_info *c = container_of(kobj, struct ubifs_info, kobj); | ||
|
||
complete(&c->kobj_unregister); | ||
} | ||
|
||
static const struct sysfs_ops ubifs_attr_ops = { | ||
.show = ubifs_attr_show, | ||
}; | ||
|
||
static struct kobj_type ubifs_sb_ktype = { | ||
.default_attrs = ubifs_attrs, | ||
.sysfs_ops = &ubifs_attr_ops, | ||
.release = ubifs_sb_release, | ||
}; | ||
|
||
static struct kobj_type ubifs_ktype = { | ||
.sysfs_ops = &ubifs_attr_ops, | ||
}; | ||
|
||
static struct kset ubifs_kset = { | ||
.kobj = {.ktype = &ubifs_ktype}, | ||
}; | ||
|
||
int ubifs_sysfs_register(struct ubifs_info *c) | ||
{ | ||
int ret, n; | ||
char dfs_dir_name[UBIFS_DFS_DIR_LEN+1]; | ||
|
||
c->stats = kzalloc(sizeof(struct ubifs_stats_info), GFP_KERNEL); | ||
if (!c->stats) { | ||
ret = -ENOMEM; | ||
goto out_last; | ||
} | ||
n = snprintf(dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME, | ||
c->vi.ubi_num, c->vi.vol_id); | ||
|
||
if (n == UBIFS_DFS_DIR_LEN) { | ||
/* The array size is too small */ | ||
ret = -EINVAL; | ||
goto out_free; | ||
} | ||
|
||
c->kobj.kset = &ubifs_kset; | ||
init_completion(&c->kobj_unregister); | ||
|
||
ret = kobject_init_and_add(&c->kobj, &ubifs_sb_ktype, NULL, | ||
"%s", dfs_dir_name); | ||
if (ret) | ||
goto out_put; | ||
|
||
return 0; | ||
|
||
out_put: | ||
kobject_put(&c->kobj); | ||
wait_for_completion(&c->kobj_unregister); | ||
out_free: | ||
kfree(c->stats); | ||
out_last: | ||
ubifs_err(c, "cannot create sysfs entry for ubifs%d_%d, error %d\n", | ||
c->vi.ubi_num, c->vi.vol_id, ret); | ||
return ret; | ||
} | ||
|
||
void ubifs_sysfs_unregister(struct ubifs_info *c) | ||
{ | ||
kobject_del(&c->kobj); | ||
kobject_put(&c->kobj); | ||
wait_for_completion(&c->kobj_unregister); | ||
|
||
kfree(c->stats); | ||
} | ||
|
||
int __init ubifs_sysfs_init(void) | ||
{ | ||
int ret; | ||
|
||
kobject_set_name(&ubifs_kset.kobj, "ubifs"); | ||
ubifs_kset.kobj.parent = fs_kobj; | ||
ret = kset_register(&ubifs_kset); | ||
|
||
return ret; | ||
} | ||
|
||
void ubifs_sysfs_exit(void) | ||
{ | ||
kset_unregister(&ubifs_kset); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters