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