4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
23 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2012, 2017, Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 #define DEBUG_SUBSYSTEM S_CLASS
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"
41 static int lov_stripesize_seq_show(struct seq_file *m, void *v)
43 struct obd_device *obd = (struct obd_device *)m->private;
44 struct lov_desc *desc;
47 desc = &obd->u.lov.desc;
49 seq_printf(m, "%llu\n", desc->ld_default_stripe_size);
53 static ssize_t lov_stripesize_seq_write(struct file *file,
54 const char __user *buffer,
55 size_t count, loff_t *off)
57 struct seq_file *m = file->private_data;
58 struct obd_device *obd = m->private;
59 struct lov_desc *desc;
60 char kernbuf[22] = "";
65 desc = &obd->u.lov.desc;
67 if (count >= sizeof(kernbuf))
70 if (copy_from_user(kernbuf, buffer, count))
74 rc = sysfs_memparse(kernbuf, count, &val, "B");
78 lov_fix_desc_stripe_size(&val);
79 desc->ld_default_stripe_size = val;
83 LPROC_SEQ_FOPS(lov_stripesize);
85 static ssize_t stripeoffset_show(struct kobject *kobj, struct attribute *attr,
88 struct obd_device *obd = container_of(kobj, struct obd_device,
90 struct lov_desc *desc = &obd->u.lov.desc;
92 return sprintf(buf, "%lld\n", desc->ld_default_stripe_offset);
95 static ssize_t stripeoffset_store(struct kobject *kobj, struct attribute *attr,
96 const char *buf, size_t count)
98 struct obd_device *obd = container_of(kobj, struct obd_device,
100 struct lov_desc *desc = &obd->u.lov.desc;
104 rc = kstrtol(buf, 0, &val);
107 if (val < -1 || val > LOV_MAX_STRIPE_COUNT)
110 desc->ld_default_stripe_offset = val;
114 LUSTRE_RW_ATTR(stripeoffset);
116 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
119 struct obd_device *obd = container_of(kobj, struct obd_device,
121 struct lov_desc *desc = &obd->u.lov.desc;
123 return sprintf(buf, "%u\n", desc->ld_pattern);
126 static ssize_t stripetype_store(struct kobject *kobj, struct attribute *attr,
127 const char *buffer, size_t count)
129 struct obd_device *obd = container_of(kobj, struct obd_device,
131 struct lov_desc *desc = &obd->u.lov.desc;
135 rc = kstrtouint(buffer, 0, &pattern);
139 lov_fix_desc_pattern(&pattern);
140 desc->ld_pattern = pattern;
144 LUSTRE_RW_ATTR(stripetype);
146 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
149 struct obd_device *obd = container_of(kobj, struct obd_device,
151 struct lov_desc *desc = &obd->u.lov.desc;
153 return sprintf(buf, "%d\n",
154 (__s16)(desc->ld_default_stripe_count + 1) - 1);
157 static ssize_t stripecount_store(struct kobject *kobj, struct attribute *attr,
158 const char *buffer, size_t count)
160 struct obd_device *obd = container_of(kobj, struct obd_device,
162 struct lov_desc *desc = &obd->u.lov.desc;
166 rc = kstrtoint(buffer, 0, &stripe_count);
170 if (stripe_count < -1)
173 lov_fix_desc_stripe_count(&stripe_count);
174 desc->ld_default_stripe_count = stripe_count;
178 LUSTRE_RW_ATTR(stripecount);
180 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
183 struct obd_device *obd = container_of(kobj, struct obd_device,
185 struct lov_desc *desc = &obd->u.lov.desc;
187 return sprintf(buf, "%u\n", desc->ld_tgt_count);
189 LUSTRE_RO_ATTR(numobd);
191 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
194 struct obd_device *obd = container_of(kobj, struct obd_device,
196 struct lov_desc *desc = &obd->u.lov.desc;
198 return sprintf(buf, "%u\n", desc->ld_active_tgt_count);
200 LUSTRE_RO_ATTR(activeobd);
202 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
205 struct obd_device *obd = container_of(kobj, struct obd_device,
207 struct lov_desc *desc = &obd->u.lov.desc;
209 return sprintf(buf, "%s\n", desc->ld_uuid.uuid);
211 LUSTRE_RO_ATTR(desc_uuid);
213 #ifdef CONFIG_PROC_FS
214 static void *lov_tgt_seq_start(struct seq_file *p, loff_t *pos)
216 struct obd_device *obd = p->private;
217 struct lov_obd *lov = &obd->u.lov;
219 while (*pos < lov->desc.ld_tgt_count) {
220 if (lov->lov_tgts[*pos])
221 return lov->lov_tgts[*pos];
227 static void lov_tgt_seq_stop(struct seq_file *p, void *v)
231 static void *lov_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
233 struct obd_device *obd = p->private;
234 struct lov_obd *lov = &obd->u.lov;
236 while (++*pos < lov->desc.ld_tgt_count) {
237 if (lov->lov_tgts[*pos])
238 return lov->lov_tgts[*pos];
243 static int lov_tgt_seq_show(struct seq_file *p, void *v)
245 struct lov_tgt_desc *tgt = v;
247 seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
248 obd_uuid2str(&tgt->ltd_uuid),
249 tgt->ltd_active ? "" : "IN");
253 static const struct seq_operations lov_tgt_sops = {
254 .start = lov_tgt_seq_start,
255 .stop = lov_tgt_seq_stop,
256 .next = lov_tgt_seq_next,
257 .show = lov_tgt_seq_show,
260 static int lov_target_seq_open(struct inode *inode, struct file *file)
262 struct seq_file *seq;
265 rc = seq_open(file, &lov_tgt_sops);
269 seq = file->private_data;
270 seq->private = PDE_DATA(inode);
274 struct lprocfs_vars lprocfs_lov_obd_vars[] = {
275 { .name = "stripesize",
276 .fops = &lov_stripesize_fops },
280 static const struct file_operations lov_proc_target_fops = {
281 .owner = THIS_MODULE,
282 .open = lov_target_seq_open,
285 .release = lprocfs_seq_release,
287 #endif /* CONFIG_PROC_FS */
289 static struct attribute *lov_attrs[] = {
290 &lustre_attr_activeobd.attr,
291 &lustre_attr_numobd.attr,
292 &lustre_attr_desc_uuid.attr,
293 &lustre_attr_stripeoffset.attr,
294 &lustre_attr_stripetype.attr,
295 &lustre_attr_stripecount.attr,
299 int lov_tunables_init(struct obd_device *obd)
301 struct lov_obd *lov = &obd->u.lov;
304 obd->obd_vars = lprocfs_lov_obd_vars;
305 obd->obd_ktype.default_attrs = lov_attrs;
306 rc = lprocfs_obd_setup(obd, false);
310 #ifdef CONFIG_PROC_FS
311 rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd", 0444,
312 &lov_proc_target_fops, obd);
314 CWARN("%s: Error adding the target_obd file : rc %d\n",
317 lov->lov_pool_proc_entry = lprocfs_register("pools",
320 if (IS_ERR(lov->lov_pool_proc_entry)) {
321 rc = PTR_ERR(lov->lov_pool_proc_entry);
322 CERROR("%s: error setting up debugfs for pools : rc %d\n",
324 lov->lov_pool_proc_entry = NULL;
326 #endif /* CONFIG_FS_PROC */