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