162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *   Copyright (C) International Business Machines Corp., 2000-2004
462306a36Sopenharmony_ci *   Portions Copyright (C) Christoph Hellwig, 2001-2002
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/fs.h>
862306a36Sopenharmony_ci#include <linux/ctype.h>
962306a36Sopenharmony_ci#include <linux/module.h>
1062306a36Sopenharmony_ci#include <linux/proc_fs.h>
1162306a36Sopenharmony_ci#include <linux/seq_file.h>
1262306a36Sopenharmony_ci#include <linux/uaccess.h>
1362306a36Sopenharmony_ci#include "jfs_incore.h"
1462306a36Sopenharmony_ci#include "jfs_filsys.h"
1562306a36Sopenharmony_ci#include "jfs_debug.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#ifdef PROC_FS_JFS /* see jfs_debug.h */
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#ifdef CONFIG_JFS_DEBUG
2062306a36Sopenharmony_cistatic int jfs_loglevel_proc_show(struct seq_file *m, void *v)
2162306a36Sopenharmony_ci{
2262306a36Sopenharmony_ci	seq_printf(m, "%d\n", jfsloglevel);
2362306a36Sopenharmony_ci	return 0;
2462306a36Sopenharmony_ci}
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistatic int jfs_loglevel_proc_open(struct inode *inode, struct file *file)
2762306a36Sopenharmony_ci{
2862306a36Sopenharmony_ci	return single_open(file, jfs_loglevel_proc_show, NULL);
2962306a36Sopenharmony_ci}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic ssize_t jfs_loglevel_proc_write(struct file *file,
3262306a36Sopenharmony_ci		const char __user *buffer, size_t count, loff_t *ppos)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	char c;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	if (get_user(c, buffer))
3762306a36Sopenharmony_ci		return -EFAULT;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	/* yes, I know this is an ASCIIism.  --hch */
4062306a36Sopenharmony_ci	if (c < '0' || c > '9')
4162306a36Sopenharmony_ci		return -EINVAL;
4262306a36Sopenharmony_ci	jfsloglevel = c - '0';
4362306a36Sopenharmony_ci	return count;
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic const struct proc_ops jfs_loglevel_proc_ops = {
4762306a36Sopenharmony_ci	.proc_open	= jfs_loglevel_proc_open,
4862306a36Sopenharmony_ci	.proc_read	= seq_read,
4962306a36Sopenharmony_ci	.proc_lseek	= seq_lseek,
5062306a36Sopenharmony_ci	.proc_release	= single_release,
5162306a36Sopenharmony_ci	.proc_write	= jfs_loglevel_proc_write,
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci#endif
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_civoid jfs_proc_init(void)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	struct proc_dir_entry *base;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	base = proc_mkdir("fs/jfs", NULL);
6062306a36Sopenharmony_ci	if (!base)
6162306a36Sopenharmony_ci		return;
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci#ifdef CONFIG_JFS_STATISTICS
6462306a36Sopenharmony_ci	proc_create_single("lmstats", 0, base, jfs_lmstats_proc_show);
6562306a36Sopenharmony_ci	proc_create_single("txstats", 0, base, jfs_txstats_proc_show);
6662306a36Sopenharmony_ci	proc_create_single("xtstat", 0, base, jfs_xtstat_proc_show);
6762306a36Sopenharmony_ci	proc_create_single("mpstat", 0, base, jfs_mpstat_proc_show);
6862306a36Sopenharmony_ci#endif
6962306a36Sopenharmony_ci#ifdef CONFIG_JFS_DEBUG
7062306a36Sopenharmony_ci	proc_create_single("TxAnchor", 0, base, jfs_txanchor_proc_show);
7162306a36Sopenharmony_ci	proc_create("loglevel", 0, base, &jfs_loglevel_proc_ops);
7262306a36Sopenharmony_ci#endif
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_civoid jfs_proc_clean(void)
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci	remove_proc_subtree("fs/jfs", NULL);
7862306a36Sopenharmony_ci}
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#endif /* PROC_FS_JFS */
81