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
22static struct ctl_table_header *xfs_table_header;
23
24#ifdef CONFIG_PROC_FS
25STATIC int
26xfs_stats_clear_proc_handler(
27	ctl_table	*ctl,
28	int		write,
29	struct file	*filp,
30	void		__user *buffer,
31	size_t		*lenp,
32	loff_t		*ppos)
33{
34	int		c, ret, *valp = ctl->data;
35	__uint32_t	vn_active;
36
37	ret = proc_dointvec_minmax(ctl, write, filp, buffer, lenp, ppos);
38
39	if (!ret && write && *valp) {
40		printk("XFS Clearing xfsstats\n");
41		for_each_possible_cpu(c) {
42			preempt_disable();
43			/* save vn_active, it's a universal truth! */
44			vn_active = per_cpu(xfsstats, c).vn_active;
45			memset(&per_cpu(xfsstats, c), 0,
46			       sizeof(struct xfsstats));
47			per_cpu(xfsstats, c).vn_active = vn_active;
48			preempt_enable();
49		}
50		xfs_stats_clear = 0;
51	}
52
53	return ret;
54}
55#endif /* CONFIG_PROC_FS */
56
57static ctl_table xfs_table[] = {
58	{
59		.ctl_name	= XFS_RESTRICT_CHOWN,
60		.procname	= "restrict_chown",
61		.data		= &xfs_params.restrict_chown.val,
62		.maxlen		= sizeof(int),
63		.mode		= 0644,
64		.proc_handler	= &proc_dointvec_minmax,
65		.strategy	= &sysctl_intvec,
66		.extra1		= &xfs_params.restrict_chown.min,
67		.extra2		= &xfs_params.restrict_chown.max
68	},
69	{
70		.ctl_name	= XFS_SGID_INHERIT,
71		.procname	= "irix_sgid_inherit",
72		.data		= &xfs_params.sgid_inherit.val,
73		.maxlen		= sizeof(int),
74		.mode		= 0644,
75		.proc_handler	= &proc_dointvec_minmax,
76		.strategy	= &sysctl_intvec,
77		.extra1		= &xfs_params.sgid_inherit.min,
78		.extra2		= &xfs_params.sgid_inherit.max
79	},
80	{
81		.ctl_name	= XFS_SYMLINK_MODE,
82		.procname	= "irix_symlink_mode",
83		.data		= &xfs_params.symlink_mode.val,
84		.maxlen		= sizeof(int),
85		.mode		= 0644,
86		.proc_handler	= &proc_dointvec_minmax,
87		.strategy	= &sysctl_intvec,
88		.extra1		= &xfs_params.symlink_mode.min,
89		.extra2		= &xfs_params.symlink_mode.max
90	},
91	{
92		.ctl_name	= XFS_PANIC_MASK,
93		.procname	= "panic_mask",
94		.data		= &xfs_params.panic_mask.val,
95		.maxlen		= sizeof(int),
96		.mode		= 0644,
97		.proc_handler	= &proc_dointvec_minmax,
98		.strategy	= &sysctl_intvec,
99		.extra1		= &xfs_params.panic_mask.min,
100		.extra2		= &xfs_params.panic_mask.max
101	},
102
103	{
104		.ctl_name	= XFS_ERRLEVEL,
105		.procname	= "error_level",
106		.data		= &xfs_params.error_level.val,
107		.maxlen		= sizeof(int),
108		.mode		= 0644,
109		.proc_handler	= &proc_dointvec_minmax,
110		.strategy	= &sysctl_intvec,
111		.extra1		= &xfs_params.error_level.min,
112		.extra2		= &xfs_params.error_level.max
113	},
114	{
115		.ctl_name	= XFS_SYNCD_TIMER,
116		.procname	= "xfssyncd_centisecs",
117		.data		= &xfs_params.syncd_timer.val,
118		.maxlen		= sizeof(int),
119		.mode		= 0644,
120		.proc_handler	= &proc_dointvec_minmax,
121		.strategy	= &sysctl_intvec,
122		.extra1		= &xfs_params.syncd_timer.min,
123		.extra2		= &xfs_params.syncd_timer.max
124	},
125	{
126		.ctl_name	= XFS_INHERIT_SYNC,
127		.procname	= "inherit_sync",
128		.data		= &xfs_params.inherit_sync.val,
129		.maxlen		= sizeof(int),
130		.mode		= 0644,
131		.proc_handler	= &proc_dointvec_minmax,
132		.strategy	= &sysctl_intvec,
133		.extra1		= &xfs_params.inherit_sync.min,
134		.extra2		= &xfs_params.inherit_sync.max
135	},
136	{
137		.ctl_name	= XFS_INHERIT_NODUMP,
138		.procname	= "inherit_nodump",
139		.data		= &xfs_params.inherit_nodump.val,
140		.maxlen		= sizeof(int),
141		.mode		= 0644,
142		.proc_handler	= &proc_dointvec_minmax,
143		.strategy	= &sysctl_intvec,
144		.extra1		= &xfs_params.inherit_nodump.min,
145		.extra2		= &xfs_params.inherit_nodump.max
146	},
147	{
148		.ctl_name	= XFS_INHERIT_NOATIME,
149		.procname	= "inherit_noatime",
150		.data		= &xfs_params.inherit_noatim.val,
151		.maxlen		= sizeof(int),
152		.mode		= 0644,
153		.proc_handler	= &proc_dointvec_minmax,
154		.strategy	= &sysctl_intvec,
155		.extra1		= &xfs_params.inherit_noatim.min,
156		.extra2		= &xfs_params.inherit_noatim.max
157	},
158	{
159		.ctl_name	= XFS_BUF_TIMER,
160		.procname	= "xfsbufd_centisecs",
161		.data		= &xfs_params.xfs_buf_timer.val,
162		.maxlen		= sizeof(int),
163		.mode		= 0644,
164		.proc_handler	= &proc_dointvec_minmax,
165		.strategy	= &sysctl_intvec,
166		.extra1		= &xfs_params.xfs_buf_timer.min,
167		.extra2		= &xfs_params.xfs_buf_timer.max
168	},
169	{
170		.ctl_name	= XFS_BUF_AGE,
171		.procname	= "age_buffer_centisecs",
172		.data		= &xfs_params.xfs_buf_age.val,
173		.maxlen		= sizeof(int),
174		.mode		= 0644,
175		.proc_handler	= &proc_dointvec_minmax,
176		.strategy	= &sysctl_intvec,
177		.extra1		= &xfs_params.xfs_buf_age.min,
178		.extra2		= &xfs_params.xfs_buf_age.max
179	},
180	{
181		.ctl_name	= XFS_INHERIT_NOSYM,
182		.procname	= "inherit_nosymlinks",
183		.data		= &xfs_params.inherit_nosym.val,
184		.maxlen		= sizeof(int),
185		.mode		= 0644,
186		.proc_handler	= &proc_dointvec_minmax,
187		.strategy	= &sysctl_intvec,
188		.extra1		= &xfs_params.inherit_nosym.min,
189		.extra2		= &xfs_params.inherit_nosym.max
190	},
191	{
192		.ctl_name	= XFS_ROTORSTEP,
193		.procname	= "rotorstep",
194		.data		= &xfs_params.rotorstep.val,
195		.maxlen		= sizeof(int),
196		.mode		= 0644,
197		.proc_handler	= &proc_dointvec_minmax,
198		.strategy	= &sysctl_intvec,
199		.extra1		= &xfs_params.rotorstep.min,
200		.extra2		= &xfs_params.rotorstep.max
201	},
202	{
203		.ctl_name	= XFS_INHERIT_NODFRG,
204		.procname	= "inherit_nodefrag",
205		.data		= &xfs_params.inherit_nodfrg.val,
206		.maxlen		= sizeof(int),
207		.mode		= 0644,
208		.proc_handler	= &proc_dointvec_minmax,
209		.strategy	= &sysctl_intvec,
210		.extra1		= &xfs_params.inherit_nodfrg.min,
211		.extra2		= &xfs_params.inherit_nodfrg.max
212	},
213	/* please keep this the last entry */
214#ifdef CONFIG_PROC_FS
215	{
216		.ctl_name	= XFS_STATS_CLEAR,
217		.procname	= "stats_clear",
218		.data		= &xfs_params.stats_clear.val,
219		.maxlen		= sizeof(int),
220		.mode		= 0644,
221		.proc_handler	= &xfs_stats_clear_proc_handler,
222		.strategy	= &sysctl_intvec,
223		.extra1		= &xfs_params.stats_clear.min,
224		.extra2		= &xfs_params.stats_clear.max
225	},
226#endif /* CONFIG_PROC_FS */
227
228	{}
229};
230
231static ctl_table xfs_dir_table[] = {
232	{
233		.ctl_name	= FS_XFS,
234		.procname	= "xfs",
235		.mode		= 0555,
236		.child		= xfs_table
237	},
238	{}
239};
240
241static ctl_table xfs_root_table[] = {
242	{
243		.ctl_name	= CTL_FS,
244		.procname	= "fs",
245		.mode		= 0555,
246		.child		= xfs_dir_table
247	},
248	{}
249};
250
251void
252xfs_sysctl_register(void)
253{
254	xfs_table_header = register_sysctl_table(xfs_root_table);
255}
256
257void
258xfs_sysctl_unregister(void)
259{
260	if (xfs_table_header)
261		unregister_sysctl_table(xfs_table_header);
262}
263