1/*
2 * Copyright (c) 2001-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18#include "xfs.h"
19#include <linux/sysctl.h>
20#include <linux/proc_fs.h>
21#include "xfs_error.h"
22#include "xfs_stats.h"
23
24static struct ctl_table_header *xfs_table_header;
25
26#ifdef CONFIG_PROC_FS
27STATIC int
28xfs_stats_clear_proc_handler(
29	struct ctl_table	*ctl,
30	int			write,
31	void			__user *buffer,
32	size_t			*lenp,
33	loff_t			*ppos)
34{
35	int		ret, *valp = ctl->data;
36
37	ret = proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
38
39	if (!ret && write && *valp) {
40		xfs_stats_clearall(xfsstats.xs_stats);
41		xfs_stats_clear = 0;
42	}
43
44	return ret;
45}
46
47STATIC int
48xfs_panic_mask_proc_handler(
49	struct ctl_table	*ctl,
50	int			write,
51	void			__user *buffer,
52	size_t			*lenp,
53	loff_t			*ppos)
54{
55	int		ret, *valp = ctl->data;
56
57	ret = proc_dointvec_minmax(ctl, write, buffer, lenp, ppos);
58	if (!ret && write) {
59		xfs_panic_mask = *valp;
60#ifdef DEBUG
61		xfs_panic_mask |= (XFS_PTAG_SHUTDOWN_CORRUPT | XFS_PTAG_LOGRES);
62#endif
63	}
64	return ret;
65}
66#endif /* CONFIG_PROC_FS */
67
68static struct ctl_table xfs_table[] = {
69	{
70		.procname	= "irix_sgid_inherit",
71		.data		= &xfs_params.sgid_inherit.val,
72		.maxlen		= sizeof(int),
73		.mode		= 0644,
74		.proc_handler	= proc_dointvec_minmax,
75		.extra1		= &xfs_params.sgid_inherit.min,
76		.extra2		= &xfs_params.sgid_inherit.max
77	},
78	{
79		.procname	= "irix_symlink_mode",
80		.data		= &xfs_params.symlink_mode.val,
81		.maxlen		= sizeof(int),
82		.mode		= 0644,
83		.proc_handler	= proc_dointvec_minmax,
84		.extra1		= &xfs_params.symlink_mode.min,
85		.extra2		= &xfs_params.symlink_mode.max
86	},
87	{
88		.procname	= "panic_mask",
89		.data		= &xfs_params.panic_mask.val,
90		.maxlen		= sizeof(int),
91		.mode		= 0644,
92		.proc_handler	= xfs_panic_mask_proc_handler,
93		.extra1		= &xfs_params.panic_mask.min,
94		.extra2		= &xfs_params.panic_mask.max
95	},
96
97	{
98		.procname	= "error_level",
99		.data		= &xfs_params.error_level.val,
100		.maxlen		= sizeof(int),
101		.mode		= 0644,
102		.proc_handler	= proc_dointvec_minmax,
103		.extra1		= &xfs_params.error_level.min,
104		.extra2		= &xfs_params.error_level.max
105	},
106	{
107		.procname	= "xfssyncd_centisecs",
108		.data		= &xfs_params.syncd_timer.val,
109		.maxlen		= sizeof(int),
110		.mode		= 0644,
111		.proc_handler	= proc_dointvec_minmax,
112		.extra1		= &xfs_params.syncd_timer.min,
113		.extra2		= &xfs_params.syncd_timer.max
114	},
115	{
116		.procname	= "inherit_sync",
117		.data		= &xfs_params.inherit_sync.val,
118		.maxlen		= sizeof(int),
119		.mode		= 0644,
120		.proc_handler	= proc_dointvec_minmax,
121		.extra1		= &xfs_params.inherit_sync.min,
122		.extra2		= &xfs_params.inherit_sync.max
123	},
124	{
125		.procname	= "inherit_nodump",
126		.data		= &xfs_params.inherit_nodump.val,
127		.maxlen		= sizeof(int),
128		.mode		= 0644,
129		.proc_handler	= proc_dointvec_minmax,
130		.extra1		= &xfs_params.inherit_nodump.min,
131		.extra2		= &xfs_params.inherit_nodump.max
132	},
133	{
134		.procname	= "inherit_noatime",
135		.data		= &xfs_params.inherit_noatim.val,
136		.maxlen		= sizeof(int),
137		.mode		= 0644,
138		.proc_handler	= proc_dointvec_minmax,
139		.extra1		= &xfs_params.inherit_noatim.min,
140		.extra2		= &xfs_params.inherit_noatim.max
141	},
142	{
143		.procname	= "inherit_nosymlinks",
144		.data		= &xfs_params.inherit_nosym.val,
145		.maxlen		= sizeof(int),
146		.mode		= 0644,
147		.proc_handler	= proc_dointvec_minmax,
148		.extra1		= &xfs_params.inherit_nosym.min,
149		.extra2		= &xfs_params.inherit_nosym.max
150	},
151	{
152		.procname	= "rotorstep",
153		.data		= &xfs_params.rotorstep.val,
154		.maxlen		= sizeof(int),
155		.mode		= 0644,
156		.proc_handler	= proc_dointvec_minmax,
157		.extra1		= &xfs_params.rotorstep.min,
158		.extra2		= &xfs_params.rotorstep.max
159	},
160	{
161		.procname	= "inherit_nodefrag",
162		.data		= &xfs_params.inherit_nodfrg.val,
163		.maxlen		= sizeof(int),
164		.mode		= 0644,
165		.proc_handler	= proc_dointvec_minmax,
166		.extra1		= &xfs_params.inherit_nodfrg.min,
167		.extra2		= &xfs_params.inherit_nodfrg.max
168	},
169	{
170		.procname	= "filestream_centisecs",
171		.data		= &xfs_params.fstrm_timer.val,
172		.maxlen		= sizeof(int),
173		.mode		= 0644,
174		.proc_handler	= proc_dointvec_minmax,
175		.extra1		= &xfs_params.fstrm_timer.min,
176		.extra2		= &xfs_params.fstrm_timer.max,
177	},
178	{
179		.procname	= "speculative_prealloc_lifetime",
180		.data		= &xfs_params.eofb_timer.val,
181		.maxlen		= sizeof(int),
182		.mode		= 0644,
183		.proc_handler	= proc_dointvec_minmax,
184		.extra1		= &xfs_params.eofb_timer.min,
185		.extra2		= &xfs_params.eofb_timer.max,
186	},
187	/* please keep this the last entry */
188#ifdef CONFIG_PROC_FS
189	{
190		.procname	= "stats_clear",
191		.data		= &xfs_params.stats_clear.val,
192		.maxlen		= sizeof(int),
193		.mode		= 0644,
194		.proc_handler	= xfs_stats_clear_proc_handler,
195		.extra1		= &xfs_params.stats_clear.min,
196		.extra2		= &xfs_params.stats_clear.max
197	},
198#endif /* CONFIG_PROC_FS */
199
200	{}
201};
202
203static struct ctl_table xfs_dir_table[] = {
204	{
205		.procname	= "xfs",
206		.mode		= 0555,
207		.child		= xfs_table
208	},
209	{}
210};
211
212static struct ctl_table xfs_root_table[] = {
213	{
214		.procname	= "fs",
215		.mode		= 0555,
216		.child		= xfs_dir_table
217	},
218	{}
219};
220
221int
222xfs_sysctl_register(void)
223{
224	xfs_table_header = register_sysctl_table(xfs_root_table);
225	if (!xfs_table_header)
226		return -ENOMEM;
227	return 0;
228}
229
230void
231xfs_sysctl_unregister(void)
232{
233	unregister_sysctl_table(xfs_table_header);
234}
235