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 ssize_t stripesize_show(struct kobject *kobj, struct attribute *attr,
44 struct obd_device *obd = container_of(kobj, struct obd_device,
46 struct lov_desc *desc = &obd->u.lov.desc;
48 return scnprintf(buf, PAGE_SIZE, "%llu\n", desc->ld_default_stripe_size);
51 static ssize_t stripesize_store(struct kobject *kobj, struct attribute *attr,
52 const char *buf, size_t count)
54 struct obd_device *obd = container_of(kobj, struct obd_device,
56 struct lov_desc *desc = &obd->u.lov.desc;
60 rc = sysfs_memparse(buf, count, &val, "B");
64 lov_fix_desc_stripe_size(&val);
65 desc->ld_default_stripe_size = val;
69 LUSTRE_RW_ATTR(stripesize);
71 static ssize_t stripeoffset_show(struct kobject *kobj, struct attribute *attr,
74 struct obd_device *obd = container_of(kobj, struct obd_device,
76 struct lov_desc *desc = &obd->u.lov.desc;
78 return sprintf(buf, "%lld\n", desc->ld_default_stripe_offset);
81 static ssize_t stripeoffset_store(struct kobject *kobj, struct attribute *attr,
82 const char *buf, size_t count)
84 struct obd_device *obd = container_of(kobj, struct obd_device,
86 struct lov_desc *desc = &obd->u.lov.desc;
90 rc = kstrtol(buf, 0, &val);
93 if (val < -1 || val > LOV_MAX_STRIPE_COUNT)
96 desc->ld_default_stripe_offset = val;
100 LUSTRE_RW_ATTR(stripeoffset);
102 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
105 struct obd_device *obd = container_of(kobj, struct obd_device,
107 struct lov_desc *desc = &obd->u.lov.desc;
109 return sprintf(buf, "%u\n", desc->ld_pattern);
112 static ssize_t stripetype_store(struct kobject *kobj, struct attribute *attr,
113 const char *buffer, size_t count)
115 struct obd_device *obd = container_of(kobj, struct obd_device,
117 struct lov_desc *desc = &obd->u.lov.desc;
121 rc = kstrtouint(buffer, 0, &pattern);
125 lov_fix_desc_pattern(&pattern);
126 desc->ld_pattern = pattern;
130 LUSTRE_RW_ATTR(stripetype);
132 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
135 struct obd_device *obd = container_of(kobj, struct obd_device,
137 struct lov_desc *desc = &obd->u.lov.desc;
139 return sprintf(buf, "%d\n",
140 (__s16)(desc->ld_default_stripe_count + 1) - 1);
143 static ssize_t stripecount_store(struct kobject *kobj, struct attribute *attr,
144 const char *buffer, size_t count)
146 struct obd_device *obd = container_of(kobj, struct obd_device,
148 struct lov_desc *desc = &obd->u.lov.desc;
152 rc = kstrtoint(buffer, 0, &stripe_count);
156 if (stripe_count < -1)
159 lov_fix_desc_stripe_count(&stripe_count);
160 desc->ld_default_stripe_count = stripe_count;
164 LUSTRE_RW_ATTR(stripecount);
166 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
169 struct obd_device *obd = container_of(kobj, struct obd_device,
171 struct lov_desc *desc = &obd->u.lov.desc;
173 return sprintf(buf, "%u\n", desc->ld_tgt_count);
175 LUSTRE_RO_ATTR(numobd);
177 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
180 struct obd_device *obd = container_of(kobj, struct obd_device,
182 struct lov_desc *desc = &obd->u.lov.desc;
184 return sprintf(buf, "%u\n", desc->ld_active_tgt_count);
186 LUSTRE_RO_ATTR(activeobd);
188 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
191 struct obd_device *obd = container_of(kobj, struct obd_device,
193 struct lov_desc *desc = &obd->u.lov.desc;
195 return sprintf(buf, "%s\n", desc->ld_uuid.uuid);
197 LUSTRE_RO_ATTR(desc_uuid);
199 #ifdef CONFIG_PROC_FS
200 static void *lov_tgt_seq_start(struct seq_file *p, loff_t *pos)
202 struct obd_device *obd = p->private;
203 struct lov_obd *lov = &obd->u.lov;
205 while (*pos < lov->desc.ld_tgt_count) {
206 if (lov->lov_tgts[*pos])
207 return lov->lov_tgts[*pos];
213 static void lov_tgt_seq_stop(struct seq_file *p, void *v)
217 static void *lov_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
219 struct obd_device *obd = p->private;
220 struct lov_obd *lov = &obd->u.lov;
222 while (++*pos < lov->desc.ld_tgt_count) {
223 if (lov->lov_tgts[*pos])
224 return lov->lov_tgts[*pos];
229 static int lov_tgt_seq_show(struct seq_file *p, void *v)
231 struct lov_tgt_desc *tgt = v;
233 seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
234 obd_uuid2str(&tgt->ltd_uuid),
235 tgt->ltd_active ? "" : "IN");
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,
246 static int lov_target_seq_open(struct inode *inode, struct file *file)
248 struct seq_file *seq;
251 rc = seq_open(file, &lov_tgt_sops);
255 seq = file->private_data;
256 seq->private = PDE_DATA(inode);
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,
267 #endif /* CONFIG_PROC_FS */
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,
280 int lov_tunables_init(struct obd_device *obd)
282 struct lov_obd *lov = &obd->u.lov;
285 obd->obd_ktype.default_attrs = lov_attrs;
286 rc = lprocfs_obd_setup(obd, false);
290 #ifdef CONFIG_PROC_FS
291 rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd", 0444,
292 &lov_proc_target_fops, obd);
294 CWARN("%s: Error adding the target_obd file : rc %d\n",
297 lov->lov_pool_proc_entry = lprocfs_register("pools",
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",
304 lov->lov_pool_proc_entry = NULL;
306 #endif /* CONFIG_FS_PROC */