mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	The UBIFS_DFS_DIR_LEN macro, which defines the maximum length of the UBIFS debugfs directory name, has an incorrect formula and misleading comments. The current formula is (3 + 1 + 2*2 + 1), which assumes that both UBI device number and volume ID are limited to 2 characters. However, UBI device number ranges from 0 to 31 (2 characters), and volume ID ranges from 0 to 127 (up to 3 characters). Although the current code works due to the cancellation of mathematical errors (9 + 1 = 10, which matches the correct UBIFS_DFS_DIR_LEN value), it can lead to confusion and potential issues in the future. This patch aims to improve the code clarity and maintainability by making the following changes: 1. Corrects the UBIFS_DFS_DIR_LEN macro definition to (3 + 1 + 2 + 3 + 1), accommodating the maximum lengths of both UBI device number and volume ID, plus the separators and null terminator. 2. Updates the snprintf calls to use UBIFS_DFS_DIR_LEN instead of UBIFS_DFS_DIR_LEN + 1, removing the unnecessary +1. 3. Modifies the error checks to compare against UBIFS_DFS_DIR_LEN using >= instead of >, aligning with the corrected macro definition. 4. Removes the redundant +1 in the dfs_dir_name array definitions in ubi.h and debug.h. While these changes do not affect the runtime behavior, they make the code more readable, maintainable, and less prone to future errors. v2->v3: - Removes the duplicated UBIFS_DFS_DIR_LEN and UBIFS_DFS_DIR_NAME macro definitions in ubifs.h, as they are already defined in debug.h. Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com> Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: Richard Weinberger <richard@nod.at>
		
			
				
	
	
		
			156 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
// 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,
 | 
						|
};
 | 
						|
ATTRIBUTE_GROUPS(ubifs);
 | 
						|
 | 
						|
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 const struct kobj_type ubifs_sb_ktype = {
 | 
						|
	.default_groups	= ubifs_groups,
 | 
						|
	.sysfs_ops	= &ubifs_attr_ops,
 | 
						|
	.release	= ubifs_sb_release,
 | 
						|
};
 | 
						|
 | 
						|
static const 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];
 | 
						|
 | 
						|
	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, 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);
 | 
						|
	if (ret)
 | 
						|
		kset_put(&ubifs_kset);
 | 
						|
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
void ubifs_sysfs_exit(void)
 | 
						|
{
 | 
						|
	kset_unregister(&ubifs_kset);
 | 
						|
}
 |