Whamcloud - gitweb
LU-9091 sysfs: use string helper like functions for sysfs
[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 static int lov_stripesize_seq_show(struct seq_file *m, void *v)
42 {
43         struct obd_device *dev = (struct obd_device *)m->private;
44         struct lov_desc *desc;
45
46         LASSERT(dev != NULL);
47         desc = &dev->u.lov.desc;
48
49         seq_printf(m, "%llu\n", desc->ld_default_stripe_size);
50         return 0;
51 }
52
53 static ssize_t lov_stripesize_seq_write(struct file *file,
54                                         const char __user *buffer,
55                                         size_t count, loff_t *off)
56 {
57         struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
58         struct lov_desc *desc;
59         char kernbuf[22] = "";
60         u64 val;
61         int rc;
62
63         LASSERT(dev != NULL);
64         desc = &dev->u.lov.desc;
65
66         if (count >= sizeof(kernbuf))
67                 return -EINVAL;
68
69         if (copy_from_user(kernbuf, buffer, count))
70                 return -EFAULT;
71         kernbuf[count] = 0;
72
73         rc = sysfs_memparse(kernbuf, count, &val, "B");
74         if (rc < 0)
75                 return rc;
76
77         lov_fix_desc_stripe_size(&val);
78         desc->ld_default_stripe_size = val;
79
80         return count;
81 }
82 LPROC_SEQ_FOPS(lov_stripesize);
83
84 static ssize_t stripeoffset_show(struct kobject *kobj, struct attribute *attr,
85                                  char *buf)
86 {
87         struct obd_device *dev = container_of(kobj, struct obd_device,
88                                               obd_kset.kobj);
89         struct lov_desc *desc = &dev->u.lov.desc;
90
91         return sprintf(buf, "%lld\n", desc->ld_default_stripe_offset);
92 }
93
94 static ssize_t stripeoffset_store(struct kobject *kobj, struct attribute *attr,
95                                   const char *buf, size_t count)
96 {
97         struct obd_device *dev = container_of(kobj, struct obd_device,
98                                               obd_kset.kobj);
99         struct lov_desc *desc = &dev->u.lov.desc;
100         long val;
101         int rc;
102
103         rc = kstrtol(buf, 0, &val);
104         if (rc)
105                 return rc;
106         if (val < -1 || val > LOV_MAX_STRIPE_COUNT)
107                 return -ERANGE;
108
109         desc->ld_default_stripe_offset = val;
110
111         return count;
112 }
113 LUSTRE_RW_ATTR(stripeoffset);
114
115 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
116                                char *buf)
117 {
118         struct obd_device *dev = container_of(kobj, struct obd_device,
119                                               obd_kset.kobj);
120         struct lov_desc *desc = &dev->u.lov.desc;
121
122         return sprintf(buf, "%u\n", desc->ld_pattern);
123 }
124
125 static ssize_t stripetype_store(struct kobject *kobj, struct attribute *attr,
126                                 const char *buffer, size_t count)
127 {
128         struct obd_device *dev = container_of(kobj, struct obd_device,
129                                               obd_kset.kobj);
130         struct lov_desc *desc = &dev->u.lov.desc;
131         u32 pattern;
132         int rc;
133
134         rc = kstrtouint(buffer, 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 LUSTRE_RW_ATTR(stripetype);
144
145 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
146                                 char *buf)
147 {
148         struct obd_device *dev = container_of(kobj, struct obd_device,
149                                               obd_kset.kobj);
150         struct lov_desc *desc = &dev->u.lov.desc;
151
152         return sprintf(buf, "%d\n",
153                        (__s16)(desc->ld_default_stripe_count + 1) - 1);
154 }
155
156 static ssize_t stripecount_store(struct kobject *kobj, struct attribute *attr,
157                                  const char *buffer, size_t count)
158 {
159         struct obd_device *dev = container_of(kobj, struct obd_device,
160                                               obd_kset.kobj);
161         struct lov_desc *desc = &dev->u.lov.desc;
162         int stripe_count;
163         int rc;
164
165         rc = kstrtoint(buffer, 0, &stripe_count);
166         if (rc)
167                 return rc;
168
169         if (stripe_count < -1)
170                 return -ERANGE;
171
172         lov_fix_desc_stripe_count(&stripe_count);
173         desc->ld_default_stripe_count = stripe_count;
174
175         return count;
176 }
177 LUSTRE_RW_ATTR(stripecount);
178
179 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
180                            char *buf)
181 {
182         struct obd_device *dev = container_of(kobj, struct obd_device,
183                                               obd_kset.kobj);
184         struct lov_desc *desc = &dev->u.lov.desc;
185
186         return sprintf(buf, "%u\n", desc->ld_tgt_count);
187 }
188 LUSTRE_RO_ATTR(numobd);
189
190 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
191                               char *buf)
192 {
193         struct obd_device *dev = container_of(kobj, struct obd_device,
194                                               obd_kset.kobj);
195         struct lov_desc *desc = &dev->u.lov.desc;
196
197         return sprintf(buf, "%u\n", desc->ld_active_tgt_count);
198 }
199 LUSTRE_RO_ATTR(activeobd);
200
201 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
202                               char *buf)
203 {
204         struct obd_device *dev = container_of(kobj, struct obd_device,
205                                               obd_kset.kobj);
206         struct lov_desc *desc = &dev->u.lov.desc;
207
208         return sprintf(buf, "%s\n", desc->ld_uuid.uuid);
209 }
210 LUSTRE_RO_ATTR(desc_uuid);
211
212 #ifdef CONFIG_PROC_FS
213 static void *lov_tgt_seq_start(struct seq_file *p, loff_t *pos)
214 {
215         struct obd_device *dev = p->private;
216         struct lov_obd *lov = &dev->u.lov;
217
218         while (*pos < lov->desc.ld_tgt_count) {
219                 if (lov->lov_tgts[*pos])
220                         return lov->lov_tgts[*pos];
221                 ++*pos;
222         }
223         return NULL;
224 }
225
226 static void lov_tgt_seq_stop(struct seq_file *p, void *v)
227 {
228 }
229
230 static void *lov_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
231 {
232         struct obd_device *dev = p->private;
233         struct lov_obd *lov = &dev->u.lov;
234
235         while (++*pos < lov->desc.ld_tgt_count) {
236                 if (lov->lov_tgts[*pos])
237                         return lov->lov_tgts[*pos];
238         }
239         return NULL;
240 }
241
242 static int lov_tgt_seq_show(struct seq_file *p, void *v)
243 {
244         struct lov_tgt_desc *tgt = v;
245
246         seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
247                    obd_uuid2str(&tgt->ltd_uuid),
248                    tgt->ltd_active ? "" : "IN");
249         return 0;
250 }
251
252 static const struct seq_operations lov_tgt_sops = {
253         .start = lov_tgt_seq_start,
254         .stop = lov_tgt_seq_stop,
255         .next = lov_tgt_seq_next,
256         .show = lov_tgt_seq_show,
257 };
258
259 static int lov_target_seq_open(struct inode *inode, struct file *file)
260 {
261         struct seq_file *seq;
262         int rc;
263
264         rc = seq_open(file, &lov_tgt_sops);
265         if (rc)
266                 return rc;
267
268         seq = file->private_data;
269         seq->private = PDE_DATA(inode);
270         return 0;
271 }
272
273 struct lprocfs_vars lprocfs_lov_obd_vars[] = {
274         { .name =       "stripesize",
275           .fops =       &lov_stripesize_fops    },
276         { NULL }
277 };
278
279 const struct file_operations lov_proc_target_fops = {
280         .owner   = THIS_MODULE,
281         .open    = lov_target_seq_open,
282         .read    = seq_read,
283         .llseek  = seq_lseek,
284         .release = lprocfs_seq_release,
285 };
286 #endif /* CONFIG_PROC_FS */
287
288 static struct attribute *lov_attrs[] = {
289         &lustre_attr_activeobd.attr,
290         &lustre_attr_numobd.attr,
291         &lustre_attr_desc_uuid.attr,
292         &lustre_attr_stripeoffset.attr,
293         &lustre_attr_stripetype.attr,
294         &lustre_attr_stripecount.attr,
295         NULL,
296 };
297
298 int lov_tunables_init(struct obd_device *obd)
299 {
300         struct lov_obd *lov = &obd->u.lov;
301         int rc;
302
303         obd->obd_vars = lprocfs_lov_obd_vars;
304         obd->obd_ktype.default_attrs = lov_attrs;
305         rc = lprocfs_obd_setup(obd, false);
306         if (rc)
307                 GOTO(out, rc);
308
309 #ifdef CONFIG_PROC_FS
310         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd", 0444,
311                                 &lov_proc_target_fops, obd);
312         if (rc)
313                 CWARN("%s: Error adding the target_obd file : rc %d\n",
314                       obd->obd_name, rc);
315
316         lov->lov_pool_proc_entry = lprocfs_register("pools",
317                                                     obd->obd_proc_entry,
318                                                     NULL, NULL);
319         if (IS_ERR(lov->lov_pool_proc_entry)) {
320                 rc = PTR_ERR(lov->lov_pool_proc_entry);
321                 CERROR("%s: error setting up debugfs for pools : rc %d\n",
322                        obd->obd_name, rc);
323                 lov->lov_pool_proc_entry = NULL;
324         }
325 #endif /* CONFIG_FS_PROC */
326 out:
327         return rc;
328 }