// 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);
}
