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) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, 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 #define DEBUG_SUBSYSTEM S_CLASS
37 
38 #include <linux/statfs.h>
39 #include "../include/lprocfs_status.h"
40 #include "../include/obd_class.h"
41 #include <linux/seq_file.h>
42 #include "lov_internal.h"
43 
lov_stripesize_seq_show(struct seq_file * m,void * v)44 static int lov_stripesize_seq_show(struct seq_file *m, void *v)
45 {
46 	struct obd_device *dev = (struct obd_device *)m->private;
47 	struct lov_desc *desc;
48 
49 	LASSERT(dev != NULL);
50 	desc = &dev->u.lov.desc;
51 	seq_printf(m, "%llu\n", desc->ld_default_stripe_size);
52 	return 0;
53 }
54 
lov_stripesize_seq_write(struct file * file,const char __user * buffer,size_t count,loff_t * off)55 static ssize_t lov_stripesize_seq_write(struct file *file,
56 				const char __user *buffer,
57 				size_t count, loff_t *off)
58 {
59 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
60 	struct lov_desc *desc;
61 	__u64 val;
62 	int rc;
63 
64 	LASSERT(dev != NULL);
65 	desc = &dev->u.lov.desc;
66 	rc = lprocfs_write_u64_helper(buffer, count, &val);
67 	if (rc)
68 		return rc;
69 
70 	lov_fix_desc_stripe_size(&val);
71 	desc->ld_default_stripe_size = val;
72 	return count;
73 }
74 LPROC_SEQ_FOPS(lov_stripesize);
75 
lov_stripeoffset_seq_show(struct seq_file * m,void * v)76 static int lov_stripeoffset_seq_show(struct seq_file *m, void *v)
77 {
78 	struct obd_device *dev = (struct obd_device *)m->private;
79 	struct lov_desc *desc;
80 
81 	LASSERT(dev != NULL);
82 	desc = &dev->u.lov.desc;
83 	seq_printf(m, "%llu\n", desc->ld_default_stripe_offset);
84 	return 0;
85 }
86 
lov_stripeoffset_seq_write(struct file * file,const char __user * buffer,size_t count,loff_t * off)87 static ssize_t lov_stripeoffset_seq_write(struct file *file,
88 				const char __user *buffer,
89 				size_t count, loff_t *off)
90 {
91 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
92 	struct lov_desc *desc;
93 	__u64 val;
94 	int rc;
95 
96 	LASSERT(dev != NULL);
97 	desc = &dev->u.lov.desc;
98 	rc = lprocfs_write_u64_helper(buffer, count, &val);
99 	if (rc)
100 		return rc;
101 
102 	desc->ld_default_stripe_offset = val;
103 	return count;
104 }
105 LPROC_SEQ_FOPS(lov_stripeoffset);
106 
lov_stripetype_seq_show(struct seq_file * m,void * v)107 static int lov_stripetype_seq_show(struct seq_file *m, void *v)
108 {
109 	struct obd_device *dev = (struct obd_device *)m->private;
110 	struct lov_desc *desc;
111 
112 	LASSERT(dev != NULL);
113 	desc = &dev->u.lov.desc;
114 	seq_printf(m, "%u\n", desc->ld_pattern);
115 	return 0;
116 }
117 
lov_stripetype_seq_write(struct file * file,const char __user * buffer,size_t count,loff_t * off)118 static ssize_t lov_stripetype_seq_write(struct file *file,
119 				const char __user *buffer,
120 				size_t count, loff_t *off)
121 {
122 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
123 	struct lov_desc *desc;
124 	int val, rc;
125 
126 	LASSERT(dev != NULL);
127 	desc = &dev->u.lov.desc;
128 	rc = lprocfs_write_helper(buffer, count, &val);
129 	if (rc)
130 		return rc;
131 
132 	lov_fix_desc_pattern(&val);
133 	desc->ld_pattern = val;
134 	return count;
135 }
136 LPROC_SEQ_FOPS(lov_stripetype);
137 
lov_stripecount_seq_show(struct seq_file * m,void * v)138 static int lov_stripecount_seq_show(struct seq_file *m, void *v)
139 {
140 	struct obd_device *dev = (struct obd_device *)m->private;
141 	struct lov_desc *desc;
142 
143 	LASSERT(dev != NULL);
144 	desc = &dev->u.lov.desc;
145 	seq_printf(m, "%d\n", (__s16)(desc->ld_default_stripe_count + 1) - 1);
146 	return 0;
147 }
148 
lov_stripecount_seq_write(struct file * file,const char __user * buffer,size_t count,loff_t * off)149 static ssize_t lov_stripecount_seq_write(struct file *file,
150 				const char __user *buffer,
151 				size_t count, loff_t *off)
152 {
153 	struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
154 	struct lov_desc *desc;
155 	int val, rc;
156 
157 	LASSERT(dev != NULL);
158 	desc = &dev->u.lov.desc;
159 	rc = lprocfs_write_helper(buffer, count, &val);
160 	if (rc)
161 		return rc;
162 
163 	lov_fix_desc_stripe_count(&val);
164 	desc->ld_default_stripe_count = val;
165 	return count;
166 }
167 LPROC_SEQ_FOPS(lov_stripecount);
168 
lov_numobd_seq_show(struct seq_file * m,void * v)169 static int lov_numobd_seq_show(struct seq_file *m, void *v)
170 {
171 	struct obd_device *dev = (struct obd_device *)m->private;
172 	struct lov_desc *desc;
173 
174 	LASSERT(dev != NULL);
175 	desc = &dev->u.lov.desc;
176 	seq_printf(m, "%u\n", desc->ld_tgt_count);
177 	return 0;
178 }
179 LPROC_SEQ_FOPS_RO(lov_numobd);
180 
lov_activeobd_seq_show(struct seq_file * m,void * v)181 static int lov_activeobd_seq_show(struct seq_file *m, void *v)
182 {
183 	struct obd_device *dev = (struct obd_device *)m->private;
184 	struct lov_desc *desc;
185 
186 	LASSERT(dev != NULL);
187 	desc = &dev->u.lov.desc;
188 	seq_printf(m, "%u\n", desc->ld_active_tgt_count);
189 	return 0;
190 }
191 LPROC_SEQ_FOPS_RO(lov_activeobd);
192 
lov_desc_uuid_seq_show(struct seq_file * m,void * v)193 static int lov_desc_uuid_seq_show(struct seq_file *m, void *v)
194 {
195 	struct obd_device *dev = (struct obd_device *)m->private;
196 	struct lov_obd *lov;
197 
198 	LASSERT(dev != NULL);
199 	lov = &dev->u.lov;
200 	seq_printf(m, "%s\n", lov->desc.ld_uuid.uuid);
201 	return 0;
202 }
203 LPROC_SEQ_FOPS_RO(lov_desc_uuid);
204 
lov_tgt_seq_start(struct seq_file * p,loff_t * pos)205 static void *lov_tgt_seq_start(struct seq_file *p, loff_t *pos)
206 {
207 	struct obd_device *dev = p->private;
208 	struct lov_obd *lov = &dev->u.lov;
209 
210 	while (*pos < lov->desc.ld_tgt_count) {
211 		if (lov->lov_tgts[*pos])
212 			return lov->lov_tgts[*pos];
213 		++*pos;
214 	}
215 	return NULL;
216 }
217 
lov_tgt_seq_stop(struct seq_file * p,void * v)218 static void lov_tgt_seq_stop(struct seq_file *p, void *v)
219 {
220 }
221 
lov_tgt_seq_next(struct seq_file * p,void * v,loff_t * pos)222 static void *lov_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
223 {
224 	struct obd_device *dev = p->private;
225 	struct lov_obd *lov = &dev->u.lov;
226 
227 	while (++*pos < lov->desc.ld_tgt_count) {
228 		if (lov->lov_tgts[*pos])
229 			return lov->lov_tgts[*pos];
230 	}
231 	return NULL;
232 }
233 
lov_tgt_seq_show(struct seq_file * p,void * v)234 static int lov_tgt_seq_show(struct seq_file *p, void *v)
235 {
236 	struct lov_tgt_desc *tgt = v;
237 
238 	seq_printf(p, "%d: %s %sACTIVE\n",
239 		   tgt->ltd_index, obd_uuid2str(&tgt->ltd_uuid),
240 		   tgt->ltd_active ? "" : "IN");
241 	return 0;
242 }
243 
244 static const struct seq_operations lov_tgt_sops = {
245 	.start = lov_tgt_seq_start,
246 	.stop = lov_tgt_seq_stop,
247 	.next = lov_tgt_seq_next,
248 	.show = lov_tgt_seq_show,
249 };
250 
lov_target_seq_open(struct inode * inode,struct file * file)251 static int lov_target_seq_open(struct inode *inode, struct file *file)
252 {
253 	struct seq_file *seq;
254 	int rc;
255 
256 	rc = seq_open(file, &lov_tgt_sops);
257 	if (rc)
258 		return rc;
259 
260 	seq = file->private_data;
261 	seq->private = PDE_DATA(inode);
262 	return 0;
263 }
264 
265 LPROC_SEQ_FOPS_RO_TYPE(lov, uuid);
266 LPROC_SEQ_FOPS_RO_TYPE(lov, filestotal);
267 LPROC_SEQ_FOPS_RO_TYPE(lov, filesfree);
268 LPROC_SEQ_FOPS_RO_TYPE(lov, blksize);
269 LPROC_SEQ_FOPS_RO_TYPE(lov, kbytestotal);
270 LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesfree);
271 LPROC_SEQ_FOPS_RO_TYPE(lov, kbytesavail);
272 
273 static struct lprocfs_vars lprocfs_lov_obd_vars[] = {
274 	{ "uuid",	  &lov_uuid_fops,	  NULL, 0 },
275 	{ "stripesize",   &lov_stripesize_fops,   NULL },
276 	{ "stripeoffset", &lov_stripeoffset_fops, NULL },
277 	{ "stripecount",  &lov_stripecount_fops,  NULL },
278 	{ "stripetype",   &lov_stripetype_fops,   NULL },
279 	{ "numobd",       &lov_numobd_fops,	  NULL, 0 },
280 	{ "activeobd",    &lov_activeobd_fops,	  NULL, 0 },
281 	{ "filestotal",   &lov_filestotal_fops,   NULL, 0 },
282 	{ "filesfree",    &lov_filesfree_fops,    NULL, 0 },
283 	/*{ "filegroups", lprocfs_rd_filegroups,  NULL, 0 },*/
284 	{ "blocksize",    &lov_blksize_fops,      NULL, 0 },
285 	{ "kbytestotal",  &lov_kbytestotal_fops,  NULL, 0 },
286 	{ "kbytesfree",   &lov_kbytesfree_fops,   NULL, 0 },
287 	{ "kbytesavail",  &lov_kbytesavail_fops,  NULL, 0 },
288 	{ "desc_uuid",    &lov_desc_uuid_fops,    NULL, 0 },
289 	{ NULL }
290 };
291 
292 LPROC_SEQ_FOPS_RO_TYPE(lov, numrefs);
293 
294 static struct lprocfs_vars lprocfs_lov_module_vars[] = {
295 	{ "num_refs",     &lov_numrefs_fops,     NULL, 0 },
296 	{ NULL }
297 };
298 
lprocfs_lov_init_vars(struct lprocfs_static_vars * lvars)299 void lprocfs_lov_init_vars(struct lprocfs_static_vars *lvars)
300 {
301     lvars->module_vars  = lprocfs_lov_module_vars;
302     lvars->obd_vars     = lprocfs_lov_obd_vars;
303 }
304 
305 const struct file_operations lov_proc_target_fops = {
306 	.owner   = THIS_MODULE,
307 	.open    = lov_target_seq_open,
308 	.read    = seq_read,
309 	.llseek  = seq_lseek,
310 	.release = lprocfs_seq_release,
311 };
312