staging/lustre/obdclass: move max_dirty_mb from sysctl to sysfs
[linux-2.6-block.git] / drivers / staging / lustre / lustre / obdclass / linux / linux-sysctl.c
CommitLineData
d7e09d03
PT
1/*
2 * GPL HEADER START
3 *
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19 *
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
22 * have any questions.
23 *
24 * GPL HEADER END
25 */
26/*
27 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
29 *
30 * Copyright (c) 2011, Intel Corporation.
31 */
32/*
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
35 */
36
37#include <linux/module.h>
38#include <linux/sysctl.h>
39#include <linux/sched.h>
40#include <linux/mm.h>
d7e09d03
PT
41#include <linux/slab.h>
42#include <linux/stat.h>
43#include <linux/ctype.h>
87822e41
AS
44#include <linux/bitops.h>
45#include <linux/uaccess.h>
d7e09d03
PT
46#include <linux/utsname.h>
47
48#define DEBUG_SUBSYSTEM S_CLASS
49
610f7377
GKH
50#include "../../include/obd_support.h"
51#include "../../include/lprocfs_status.h"
d7e09d03
PT
52
53#ifdef CONFIG_SYSCTL
71b1fd9c 54static struct ctl_table_header *obd_table_header;
d7e09d03
PT
55#endif
56
e2424a12
OD
57struct static_lustre_uintvalue_attr {
58 struct {
59 struct attribute attr;
60 ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
61 char *buf);
62 ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
63 const char *buf, size_t len);
64 } u;
65 int *value;
66};
67
68static ssize_t static_uintvalue_show(struct kobject *kobj,
69 struct attribute *attr,
70 char *buf)
d7e09d03 71{
e2424a12
OD
72 struct static_lustre_uintvalue_attr *lattr = (void *)attr;
73
74 return sprintf(buf, "%d\n", *lattr->value);
75}
76
77static ssize_t static_uintvalue_store(struct kobject *kobj,
78 struct attribute *attr,
79 const char *buffer, size_t count)
80{
81 struct static_lustre_uintvalue_attr *lattr = (void *)attr;
d7e09d03 82 int rc;
e2424a12 83 unsigned int val;
d7e09d03 84
e2424a12
OD
85 rc = kstrtouint(buffer, 10, &val);
86 if (rc)
87 return rc;
88
89 *lattr->value = val;
90
91 return count;
d7e09d03
PT
92}
93
e2424a12
OD
94#define LUSTRE_STATIC_UINT_ATTR(name, value) \
95static struct static_lustre_uintvalue_attr lustre_sattr_##name = \
96 {__ATTR(name, 0644, \
97 static_uintvalue_show, \
98 static_uintvalue_store),\
99 value }
100
101LUSTRE_STATIC_UINT_ATTR(timeout, &obd_timeout);
102
df476a4d
OD
103static ssize_t max_dirty_mb_show(struct kobject *kobj, struct attribute *attr,
104 char *buf)
d7e09d03 105{
df476a4d
OD
106 return sprintf(buf, "%ul\n",
107 obd_max_dirty_pages / (1 << (20 - PAGE_CACHE_SHIFT)));
108}
109
110static ssize_t max_dirty_mb_store(struct kobject *kobj, struct attribute *attr,
111 const char *buffer, size_t count)
112{
113 int rc;
114 unsigned long val;
115
116 rc = kstrtoul(buffer, 10, &val);
117 if (rc)
118 return rc;
119
120 val *= 1 << (20 - PAGE_CACHE_SHIFT); /* convert to pages */
d7e09d03 121
df476a4d
OD
122 if (val > ((totalram_pages / 10) * 9)) {
123 /* Somebody wants to assign too much memory to dirty pages */
124 return -EINVAL;
d7e09d03 125 }
df476a4d
OD
126
127 if (val < 4 << (20 - PAGE_CACHE_SHIFT)) {
128 /* Less than 4 Mb for dirty cache is also bad */
129 return -EINVAL;
d7e09d03 130 }
df476a4d
OD
131
132 obd_max_dirty_pages = val;
133
134 return count;
d7e09d03 135}
df476a4d 136LUSTRE_RW_ATTR(max_dirty_mb);
d7e09d03 137
df476a4d 138#ifdef CONFIG_SYSCTL
691bc0eb 139static struct ctl_table obd_table[] = {
d7e09d03 140 {
d7e09d03
PT
141 .procname = "debug_peer_on_timeout",
142 .data = &obd_debug_peer_on_timeout,
143 .maxlen = sizeof(int),
144 .mode = 0644,
145 .proc_handler = &proc_dointvec
146 },
147 {
d7e09d03
PT
148 .procname = "dump_on_timeout",
149 .data = &obd_dump_on_timeout,
150 .maxlen = sizeof(int),
151 .mode = 0644,
152 .proc_handler = &proc_dointvec
153 },
154 {
d7e09d03
PT
155 .procname = "dump_on_eviction",
156 .data = &obd_dump_on_eviction,
157 .maxlen = sizeof(int),
158 .mode = 0644,
159 .proc_handler = &proc_dointvec
160 },
d7e09d03 161 {
d7e09d03
PT
162 .procname = "at_min",
163 .data = &at_min,
164 .maxlen = sizeof(int),
165 .mode = 0644,
1d3ade00 166 .proc_handler = &proc_dointvec,
d7e09d03
PT
167 },
168 {
d7e09d03
PT
169 .procname = "at_max",
170 .data = &at_max,
171 .maxlen = sizeof(int),
172 .mode = 0644,
1d3ade00 173 .proc_handler = &proc_dointvec,
d7e09d03
PT
174 },
175 {
d7e09d03
PT
176 .procname = "at_extra",
177 .data = &at_extra,
178 .maxlen = sizeof(int),
179 .mode = 0644,
1d3ade00 180 .proc_handler = &proc_dointvec,
d7e09d03
PT
181 },
182 {
d7e09d03
PT
183 .procname = "at_early_margin",
184 .data = &at_early_margin,
185 .maxlen = sizeof(int),
186 .mode = 0644,
1d3ade00 187 .proc_handler = &proc_dointvec,
d7e09d03
PT
188 },
189 {
d7e09d03
PT
190 .procname = "at_history",
191 .data = &at_history,
192 .maxlen = sizeof(int),
193 .mode = 0644,
1d3ade00 194 .proc_handler = &proc_dointvec,
e780e3de
PT
195 },
196 {}
d7e09d03
PT
197};
198
691bc0eb 199static struct ctl_table parent_table[] = {
d7e09d03 200 {
d7e09d03
PT
201 .procname = "lustre",
202 .data = NULL,
203 .maxlen = 0,
204 .mode = 0555,
205 .child = obd_table
e780e3de
PT
206 },
207 {}
d7e09d03
PT
208};
209#endif
210
e2424a12
OD
211static struct attribute *lustre_attrs[] = {
212 &lustre_sattr_timeout.u.attr,
df476a4d 213 &lustre_attr_max_dirty_mb.attr,
e2424a12
OD
214 NULL,
215};
216
217static struct attribute_group lustre_attr_group = {
218 .attrs = lustre_attrs,
219};
220
221int obd_sysctl_init(void)
d7e09d03
PT
222{
223#ifdef CONFIG_SYSCTL
e4f3771f 224 if (!obd_table_header)
a7f24447 225 obd_table_header = register_sysctl_table(parent_table);
d7e09d03 226#endif
e2424a12 227 return sysfs_create_group(lustre_kobj, &lustre_attr_group);
d7e09d03
PT
228}
229
e4f3771f 230void obd_sysctl_clean(void)
d7e09d03
PT
231{
232#ifdef CONFIG_SYSCTL
e4f3771f 233 if (obd_table_header)
d7e09d03
PT
234 unregister_sysctl_table(obd_table_header);
235 obd_table_header = NULL;
236#endif
237}