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