xref: /linux/fs/xfs/xfs_sysfs.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1 /*
2  * Copyright (c) 2014 Red Hat, 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 
19 #include "xfs.h"
20 #include "xfs_sysfs.h"
21 #include "xfs_log_format.h"
22 #include "xfs_log.h"
23 #include "xfs_log_priv.h"
24 
25 struct xfs_sysfs_attr {
26 	struct attribute attr;
27 	ssize_t (*show)(char *buf, void *data);
28 	ssize_t (*store)(const char *buf, size_t count, void *data);
29 };
30 
31 static inline struct xfs_sysfs_attr *
32 to_attr(struct attribute *attr)
33 {
34 	return container_of(attr, struct xfs_sysfs_attr, attr);
35 }
36 
37 #define XFS_SYSFS_ATTR_RW(name) \
38 	static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name)
39 #define XFS_SYSFS_ATTR_RO(name) \
40 	static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name)
41 
42 #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr
43 
44 /*
45  * xfs_mount kobject. This currently has no attributes and thus no need for show
46  * and store helpers. The mp kobject serves as the per-mount parent object that
47  * is identified by the fsname under sysfs.
48  */
49 
50 struct kobj_type xfs_mp_ktype = {
51 	.release = xfs_sysfs_release,
52 };
53 
54 #ifdef DEBUG
55 /* debug */
56 
57 STATIC ssize_t
58 log_recovery_delay_store(
59 	const char	*buf,
60 	size_t		count,
61 	void		*data)
62 {
63 	int		ret;
64 	int		val;
65 
66 	ret = kstrtoint(buf, 0, &val);
67 	if (ret)
68 		return ret;
69 
70 	if (val < 0 || val > 60)
71 		return -EINVAL;
72 
73 	xfs_globals.log_recovery_delay = val;
74 
75 	return count;
76 }
77 
78 STATIC ssize_t
79 log_recovery_delay_show(
80 	char	*buf,
81 	void	*data)
82 {
83 	return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay);
84 }
85 XFS_SYSFS_ATTR_RW(log_recovery_delay);
86 
87 static struct attribute *xfs_dbg_attrs[] = {
88 	ATTR_LIST(log_recovery_delay),
89 	NULL,
90 };
91 
92 STATIC ssize_t
93 xfs_dbg_show(
94 	struct kobject		*kobject,
95 	struct attribute	*attr,
96 	char			*buf)
97 {
98 	struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
99 
100 	return xfs_attr->show ? xfs_attr->show(buf, NULL) : 0;
101 }
102 
103 STATIC ssize_t
104 xfs_dbg_store(
105 	struct kobject		*kobject,
106 	struct attribute	*attr,
107 	const char		*buf,
108 	size_t			count)
109 {
110 	struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
111 
112 	return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0;
113 }
114 
115 static struct sysfs_ops xfs_dbg_ops = {
116 	.show = xfs_dbg_show,
117 	.store = xfs_dbg_store,
118 };
119 
120 struct kobj_type xfs_dbg_ktype = {
121 	.release = xfs_sysfs_release,
122 	.sysfs_ops = &xfs_dbg_ops,
123 	.default_attrs = xfs_dbg_attrs,
124 };
125 
126 #endif /* DEBUG */
127 
128 /* xlog */
129 
130 STATIC ssize_t
131 log_head_lsn_show(
132 	char	*buf,
133 	void	*data)
134 {
135 	struct xlog *log = data;
136 	int cycle;
137 	int block;
138 
139 	spin_lock(&log->l_icloglock);
140 	cycle = log->l_curr_cycle;
141 	block = log->l_curr_block;
142 	spin_unlock(&log->l_icloglock);
143 
144 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
145 }
146 XFS_SYSFS_ATTR_RO(log_head_lsn);
147 
148 STATIC ssize_t
149 log_tail_lsn_show(
150 	char	*buf,
151 	void	*data)
152 {
153 	struct xlog *log = data;
154 	int cycle;
155 	int block;
156 
157 	xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block);
158 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block);
159 }
160 XFS_SYSFS_ATTR_RO(log_tail_lsn);
161 
162 STATIC ssize_t
163 reserve_grant_head_show(
164 	char	*buf,
165 	void	*data)
166 {
167 	struct xlog *log = data;
168 	int cycle;
169 	int bytes;
170 
171 	xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes);
172 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
173 }
174 XFS_SYSFS_ATTR_RO(reserve_grant_head);
175 
176 STATIC ssize_t
177 write_grant_head_show(
178 	char	*buf,
179 	void	*data)
180 {
181 	struct xlog *log = data;
182 	int cycle;
183 	int bytes;
184 
185 	xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes);
186 	return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes);
187 }
188 XFS_SYSFS_ATTR_RO(write_grant_head);
189 
190 static struct attribute *xfs_log_attrs[] = {
191 	ATTR_LIST(log_head_lsn),
192 	ATTR_LIST(log_tail_lsn),
193 	ATTR_LIST(reserve_grant_head),
194 	ATTR_LIST(write_grant_head),
195 	NULL,
196 };
197 
198 static inline struct xlog *
199 to_xlog(struct kobject *kobject)
200 {
201 	struct xfs_kobj *kobj = to_kobj(kobject);
202 	return container_of(kobj, struct xlog, l_kobj);
203 }
204 
205 STATIC ssize_t
206 xfs_log_show(
207 	struct kobject		*kobject,
208 	struct attribute	*attr,
209 	char			*buf)
210 {
211 	struct xlog *log = to_xlog(kobject);
212 	struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
213 
214 	return xfs_attr->show ? xfs_attr->show(buf, log) : 0;
215 }
216 
217 STATIC ssize_t
218 xfs_log_store(
219 	struct kobject		*kobject,
220 	struct attribute	*attr,
221 	const char		*buf,
222 	size_t			count)
223 {
224 	struct xlog *log = to_xlog(kobject);
225 	struct xfs_sysfs_attr *xfs_attr = to_attr(attr);
226 
227 	return xfs_attr->store ? xfs_attr->store(buf, count, log) : 0;
228 }
229 
230 static struct sysfs_ops xfs_log_ops = {
231 	.show = xfs_log_show,
232 	.store = xfs_log_store,
233 };
234 
235 struct kobj_type xfs_log_ktype = {
236 	.release = xfs_sysfs_release,
237 	.sysfs_ops = &xfs_log_ops,
238 	.default_attrs = xfs_log_attrs,
239 };
240