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/
31 #define DEBUG_SUBSYSTEM S_CLASS
33 #include <linux/version.h>
34 #include <asm/statfs.h>
35 #include <lprocfs_status.h>
36 #include <obd_class.h>
37 #include <uapi/linux/lustre/lustre_param.h>
38 #include "lov_internal.h"
40 static ssize_t stripesize_show(struct kobject *kobj, struct attribute *attr,
43 struct obd_device *obd = container_of(kobj, struct obd_device,
45 struct lov_desc *desc = &obd->u.lov.desc;
47 return scnprintf(buf, PAGE_SIZE, "%llu\n", desc->ld_default_stripe_size);
50 static ssize_t stripesize_store(struct kobject *kobj, struct attribute *attr,
51 const char *buf, size_t count)
53 struct obd_device *obd = container_of(kobj, struct obd_device,
55 struct lov_desc *desc = &obd->u.lov.desc;
59 rc = sysfs_memparse(buf, count, &val, "B");
63 lov_fix_desc_stripe_size(&val);
64 desc->ld_default_stripe_size = val;
68 LUSTRE_RW_ATTR(stripesize);
70 static ssize_t stripeoffset_show(struct kobject *kobj, struct attribute *attr,
73 struct obd_device *obd = container_of(kobj, struct obd_device,
75 struct lov_desc *desc = &obd->u.lov.desc;
77 return sprintf(buf, "%lld\n", desc->ld_default_stripe_offset);
80 static ssize_t stripeoffset_store(struct kobject *kobj, struct attribute *attr,
81 const char *buf, size_t count)
83 struct obd_device *obd = container_of(kobj, struct obd_device,
85 struct lov_desc *desc = &obd->u.lov.desc;
89 rc = kstrtol(buf, 0, &val);
92 if (val < -1 || val > LOV_MAX_STRIPE_COUNT)
95 desc->ld_default_stripe_offset = val;
99 LUSTRE_RW_ATTR(stripeoffset);
101 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
104 struct obd_device *obd = container_of(kobj, struct obd_device,
106 struct lov_desc *desc = &obd->u.lov.desc;
108 return sprintf(buf, "%u\n", desc->ld_pattern);
111 static ssize_t stripetype_store(struct kobject *kobj, struct attribute *attr,
112 const char *buffer, size_t count)
114 struct obd_device *obd = container_of(kobj, struct obd_device,
116 struct lov_desc *desc = &obd->u.lov.desc;
120 rc = kstrtouint(buffer, 0, &pattern);
124 lov_fix_desc_pattern(&pattern);
125 desc->ld_pattern = pattern;
129 LUSTRE_RW_ATTR(stripetype);
131 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
134 struct obd_device *obd = container_of(kobj, struct obd_device,
136 struct lov_desc *desc = &obd->u.lov.desc;
138 return sprintf(buf, "%d\n",
139 (__s16)(desc->ld_default_stripe_count + 1) - 1);
142 static ssize_t stripecount_store(struct kobject *kobj, struct attribute *attr,
143 const char *buffer, size_t count)
145 struct obd_device *obd = container_of(kobj, struct obd_device,
147 struct lov_desc *desc = &obd->u.lov.desc;
151 rc = kstrtoint(buffer, 0, &stripe_count);
155 if (stripe_count < -1)
158 lov_fix_desc_stripe_count(&stripe_count);
159 desc->ld_default_stripe_count = stripe_count;
163 LUSTRE_RW_ATTR(stripecount);
165 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
168 struct obd_device *obd = container_of(kobj, struct obd_device,
170 struct lov_desc *desc = &obd->u.lov.desc;
172 return sprintf(buf, "%u\n", desc->ld_tgt_count);
174 LUSTRE_RO_ATTR(numobd);
176 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
179 struct obd_device *obd = container_of(kobj, struct obd_device,
181 struct lov_desc *desc = &obd->u.lov.desc;
183 return sprintf(buf, "%u\n", desc->ld_active_tgt_count);
185 LUSTRE_RO_ATTR(activeobd);
187 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
190 struct obd_device *obd = container_of(kobj, struct obd_device,
192 struct lov_desc *desc = &obd->u.lov.desc;
194 return sprintf(buf, "%s\n", desc->ld_uuid.uuid);
196 LUSTRE_RO_ATTR(desc_uuid);
198 #ifdef CONFIG_PROC_FS
199 static void *lov_tgt_seq_start(struct seq_file *p, loff_t *pos)
201 struct obd_device *obd = p->private;
202 struct lov_obd *lov = &obd->u.lov;
204 while (*pos < lov->desc.ld_tgt_count) {
205 if (lov->lov_tgts[*pos])
206 return lov->lov_tgts[*pos];
212 static void lov_tgt_seq_stop(struct seq_file *p, void *v)
216 static void *lov_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
218 struct obd_device *obd = p->private;
219 struct lov_obd *lov = &obd->u.lov;
221 while (++*pos < lov->desc.ld_tgt_count) {
222 if (lov->lov_tgts[*pos])
223 return lov->lov_tgts[*pos];
228 static int lov_tgt_seq_show(struct seq_file *p, void *v)
230 struct lov_tgt_desc *tgt = v;
232 seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
233 obd_uuid2str(&tgt->ltd_uuid),
234 tgt->ltd_active ? "" : "IN");
238 static const struct seq_operations lov_tgt_sops = {
239 .start = lov_tgt_seq_start,
240 .stop = lov_tgt_seq_stop,
241 .next = lov_tgt_seq_next,
242 .show = lov_tgt_seq_show,
245 static int lov_target_seq_open(struct inode *inode, struct file *file)
247 struct seq_file *seq;
250 rc = seq_open(file, &lov_tgt_sops);
254 seq = file->private_data;
255 seq->private = pde_data(inode);
259 static const struct proc_ops lov_proc_target_fops = {
260 PROC_OWNER(THIS_MODULE)
261 .proc_open = lov_target_seq_open,
262 .proc_read = seq_read,
263 .proc_lseek = seq_lseek,
264 .proc_release = lprocfs_seq_release,
266 #endif /* CONFIG_PROC_FS */
268 static struct attribute *lov_attrs[] = {
269 &lustre_attr_activeobd.attr,
270 &lustre_attr_numobd.attr,
271 &lustre_attr_desc_uuid.attr,
272 &lustre_attr_stripesize.attr,
273 &lustre_attr_stripeoffset.attr,
274 &lustre_attr_stripetype.attr,
275 &lustre_attr_stripecount.attr,
279 KOBJ_ATTRIBUTE_GROUPS(lov); /* creates lov_groups */
281 int lov_tunables_init(struct obd_device *obd)
283 struct lov_obd *lov = &obd->u.lov;
286 obd->obd_ktype.default_groups = KOBJ_ATTR_GROUPS(lov);
287 rc = lprocfs_obd_setup(obd, false);
291 #ifdef CONFIG_PROC_FS
292 rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd", 0444,
293 &lov_proc_target_fops, obd);
295 CWARN("%s: Error adding the target_obd file : rc %d\n",
298 lov->lov_pool_proc_entry = lprocfs_register("pools",
301 if (IS_ERR(lov->lov_pool_proc_entry)) {
302 rc = PTR_ERR(lov->lov_pool_proc_entry);
303 CERROR("%s: error setting up debugfs for pools : rc %d\n",
305 lov->lov_pool_proc_entry = NULL;
307 #endif /* CONFIG_FS_PROC */