Whamcloud - gitweb
LU-12734 misc: allow older bash_completion versions
[fs/lustre-release.git] / lustre / lod / lproc_lod.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  2008 Sun Microsystems, Inc. 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 <lprocfs_status.h>
35 #include <obd_class.h>
36 #include <linux/seq_file.h>
37 #include "lod_internal.h"
38 #include <uapi/linux/lustre/lustre_param.h>
39
40 /*
41  * Notice, all the functions below (except for lod_procfs_init() and
42  * lod_procfs_fini()) are not supposed to be used directly. They are
43  * called by Linux kernel's procfs.
44  */
45
46 #ifdef CONFIG_PROC_FS
47
48 /**
49  * Show DoM default stripe size.
50  */
51 static ssize_t dom_stripesize_show(struct kobject *kobj, struct attribute *attr,
52                                    char *buf)
53 {
54         struct dt_device *dt = container_of(kobj, struct dt_device,
55                                             dd_kobj);
56         struct lod_device *lod = dt2lod_dev(dt);
57
58         return snprintf(buf, PAGE_SIZE, "%u\n", lod->lod_dom_max_stripesize);
59 }
60
61 /**
62  * Set DoM default stripe size.
63  */
64 static ssize_t dom_stripesize_store(struct kobject *kobj,
65                                     struct attribute *attr, const char *buffer,
66                                     size_t count)
67 {
68         struct dt_device *dt = container_of(kobj, struct dt_device,
69                                             dd_kobj);
70         struct lod_device *lod = dt2lod_dev(dt);
71         char tbuf[22] = "";
72         s64 val;
73         int rc;
74
75         if (count > (sizeof(tbuf) - 1))
76                 return -EINVAL;
77
78         memcpy(tbuf, buffer, count);
79
80         rc = lu_str_to_s64(tbuf, count, &val, '1');
81         if (rc)
82                 return rc;
83
84         if (val < 0)
85                 return -ERANGE;
86
87         /* 1GB is the limit */
88         if (val > (1ULL << 30))
89                 return -ERANGE;
90
91         if (val > 0) {
92                 if (val < LOV_MIN_STRIPE_SIZE) {
93                         LCONSOLE_INFO("Increasing provided stripe size to "
94                                       "a minimum value %u\n",
95                                       LOV_MIN_STRIPE_SIZE);
96                         val = LOV_MIN_STRIPE_SIZE;
97                 } else if (val & (LOV_MIN_STRIPE_SIZE - 1)) {
98                         val &= ~(LOV_MIN_STRIPE_SIZE - 1);
99                         LCONSOLE_WARN("Changing provided stripe size to %llu "
100                                       "(a multiple of minimum %u)\n",
101                                       val, LOV_MIN_STRIPE_SIZE);
102                 }
103         }
104
105         lod->lod_dom_max_stripesize = val;
106
107         return count;
108 }
109
110 LUSTRE_RW_ATTR(dom_stripesize);
111
112 static ssize_t stripesize_show(struct kobject *kobj, struct attribute *attr,
113                                char *buf)
114 {
115         struct dt_device *dt = container_of(kobj, struct dt_device,
116                                             dd_kobj);
117         struct lod_device *lod = dt2lod_dev(dt);
118
119         return snprintf(buf, PAGE_SIZE, "%llu\n",
120                         lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_size);
121 }
122
123 static ssize_t stripesize_store(struct kobject *kobj, struct attribute *attr,
124                                 const char *buffer, size_t count)
125 {
126         struct dt_device *dt = container_of(kobj, struct dt_device,
127                                             dd_kobj);
128         struct lod_device *lod = dt2lod_dev(dt);
129         char tbuf[22] = "";
130         s64 val;
131         int rc;
132
133         if (count > (sizeof(tbuf) - 1))
134                 return -EINVAL;
135
136         memcpy(tbuf, buffer, count);
137
138         rc = lu_str_to_s64(tbuf, count, &val, '1');
139         if (rc)
140                 return rc;
141
142         if (val < 0)
143                 return -ERANGE;
144
145         lod_fix_desc_stripe_size(&val);
146         lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_size = val;
147
148         return count;
149 }
150
151 LUSTRE_RW_ATTR(stripesize);
152
153 /**
154  * Show default stripe offset.
155  */
156 static ssize_t stripeoffset_show(struct kobject *kobj, struct attribute *attr,
157                                  char *buf)
158 {
159         struct dt_device *dt = container_of(kobj, struct dt_device,
160                                             dd_kobj);
161         struct lod_device *lod = dt2lod_dev(dt);
162
163         return snprintf(buf, PAGE_SIZE, "%lld\n",
164                 lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_offset);
165 }
166
167 /**
168  * Set default stripe offset.
169  *
170  * Usually contains -1 allowing Lustre to balance objects among OST
171  * otherwise may cause severe OST imbalance.
172  */
173 static ssize_t stripeoffset_store(struct kobject *kobj,
174                                     struct attribute *attr,
175                                     const char *buffer, size_t count)
176 {
177         struct dt_device *dt = container_of(kobj, struct dt_device,
178                                             dd_kobj);
179         struct lod_device *lod = dt2lod_dev(dt);
180         long val;
181         int rc;
182
183         rc = kstrtol(buffer, 0, &val);
184         if (rc)
185                 return rc;
186
187         if (val < -1 || val > LOV_MAX_STRIPE_COUNT)
188                 return -ERANGE;
189
190         lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_offset = val;
191
192         return count;
193 }
194
195 LUSTRE_RW_ATTR(stripeoffset);
196
197 /**
198  * Show default striping pattern (LOV_PATTERN_*).
199  */
200 static ssize_t __stripetype_show(struct kobject *kobj, struct attribute *attr,
201                                  char *buf, bool is_mdt)
202 {
203         struct dt_device *dt = container_of(kobj, struct dt_device,
204                                             dd_kobj);
205         struct lod_device *lod = dt2lod_dev(dt);
206         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
207                                             &lod->lod_ost_descs;
208
209         return snprintf(buf, PAGE_SIZE, "%u\n", ltd->ltd_lov_desc.ld_pattern);
210 }
211
212 static ssize_t mdt_stripetype_show(struct kobject *kobj, struct attribute *attr,
213                                    char *buf)
214 {
215         return __stripetype_show(kobj, attr, buf, true);
216 }
217
218 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
219                                char *buf)
220 {
221         return __stripetype_show(kobj, attr, buf, false);
222 }
223
224 /**
225  * Set default striping pattern (a number, not a human-readable string).
226  */
227 static ssize_t __stripetype_store(struct kobject *kobj, struct attribute *attr,
228                                   const char *buffer, size_t count, bool is_mdt)
229 {
230         struct dt_device *dt = container_of(kobj, struct dt_device,
231                                             dd_kobj);
232         struct lod_device *lod = dt2lod_dev(dt);
233         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
234                                             &lod->lod_ost_descs;
235         u32 pattern;
236         int rc;
237
238         rc = kstrtouint(buffer, 0, &pattern);
239         if (rc)
240                 return rc;
241
242         if (is_mdt)
243                 lod_fix_lmv_desc_pattern(&pattern);
244         else
245                 lod_fix_desc_pattern(&pattern);
246
247         ltd->ltd_lov_desc.ld_pattern = pattern;
248
249         return count;
250 }
251
252 static ssize_t mdt_stripetype_store(struct kobject *kobj,
253                                     struct attribute *attr, const char *buffer,
254                                     size_t count)
255 {
256         return __stripetype_store(kobj, attr, buffer, count, true);
257 }
258
259 static ssize_t stripetype_store(struct kobject *kobj,
260                                     struct attribute *attr, const char *buffer,
261                                     size_t count)
262 {
263         return __stripetype_store(kobj, attr, buffer, count, false);
264 }
265
266 LUSTRE_RW_ATTR(mdt_stripetype);
267 LUSTRE_RW_ATTR(stripetype);
268
269 /**
270  * Show default number of stripes.
271  */
272 static ssize_t __stripecount_show(struct kobject *kobj, struct attribute *attr,
273                                   char *buf, bool is_mdt)
274 {
275         struct dt_device *dt = container_of(kobj, struct dt_device,
276                                             dd_kobj);
277         struct lod_device *lod = dt2lod_dev(dt);
278         struct lov_desc *desc = is_mdt ? &lod->lod_mdt_descs.ltd_lov_desc :
279                                          &lod->lod_ost_descs.ltd_lov_desc;
280
281         return snprintf(buf, PAGE_SIZE, "%d\n",
282                       (s16)(desc->ld_default_stripe_count + 1) - 1);
283 }
284
285 static ssize_t mdt_stripecount_show(struct kobject *kobj,
286                                     struct attribute *attr, char *buf)
287 {
288         return __stripecount_show(kobj, attr, buf, true);
289 }
290
291 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
292                                 char *buf)
293 {
294         return __stripecount_show(kobj, attr, buf, false);
295 }
296
297 /**
298  * Set default number of stripes.
299  */
300 static ssize_t __stripecount_store(struct kobject *kobj, struct attribute *attr,
301                                    const char *buffer, size_t count,
302                                    bool is_mdt)
303 {
304         struct dt_device *dt = container_of(kobj, struct dt_device,
305                                             dd_kobj);
306         struct lod_device *lod = dt2lod_dev(dt);
307         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
308                                             &lod->lod_ost_descs;
309         int stripe_count;
310         int rc;
311
312         rc = kstrtoint(buffer, 0, &stripe_count);
313         if (rc)
314                 return rc;
315
316         if (stripe_count < -1)
317                 return -ERANGE;
318
319         lod_fix_desc_stripe_count(&stripe_count);
320         ltd->ltd_lov_desc.ld_default_stripe_count = stripe_count;
321
322         return count;
323 }
324
325 static ssize_t mdt_stripecount_store(struct kobject *kobj,
326                                      struct attribute *attr,
327                                      const char *buffer, size_t count)
328 {
329         return __stripecount_store(kobj, attr, buffer, count, true);
330 }
331
332 static ssize_t stripecount_store(struct kobject *kobj,
333                                  struct attribute *attr,
334                                  const char *buffer, size_t count)
335 {
336         return __stripecount_store(kobj, attr, buffer, count, false);
337 }
338
339 LUSTRE_RW_ATTR(mdt_stripecount);
340 LUSTRE_RW_ATTR(stripecount);
341
342 /**
343  * Show number of targets.
344  */
345 static ssize_t __numobd_show(struct kobject *kobj, struct attribute *attr,
346                              char *buf, bool is_mdt)
347 {
348         struct dt_device *dt = container_of(kobj, struct dt_device,
349                                             dd_kobj);
350         struct lod_device *lod = dt2lod_dev(dt);
351         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
352                                             &lod->lod_ost_descs;
353
354         return snprintf(buf, PAGE_SIZE, "%u\n", ltd->ltd_lov_desc.ld_tgt_count);
355 }
356
357 static ssize_t mdt_numobd_show(struct kobject *kobj, struct attribute *attr,
358                                char *buf)
359 {
360         return __numobd_show(kobj, attr, buf, true);
361 }
362
363 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
364                            char *buf)
365 {
366         return __numobd_show(kobj, attr, buf, false);
367 }
368
369 LUSTRE_RO_ATTR(mdt_numobd);
370 LUSTRE_RO_ATTR(numobd);
371
372 /**
373  * Show number of active targets.
374  */
375 static ssize_t __activeobd_show(struct kobject *kobj, struct attribute *attr,
376                                 char *buf, bool is_mdt)
377 {
378         struct dt_device *dt = container_of(kobj, struct dt_device,
379                                             dd_kobj);
380         struct lod_device *lod = dt2lod_dev(dt);
381         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
382                                             &lod->lod_ost_descs;
383
384         return snprintf(buf, PAGE_SIZE, "%u\n",
385                         ltd->ltd_lov_desc.ld_active_tgt_count);
386 }
387
388 static ssize_t mdt_activeobd_show(struct kobject *kobj, struct attribute *attr,
389                                   char *buf)
390 {
391         return __activeobd_show(kobj, attr, buf, true);
392 }
393
394 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
395                               char *buf)
396 {
397         return __activeobd_show(kobj, attr, buf, false);
398 }
399
400 LUSTRE_RO_ATTR(mdt_activeobd);
401 LUSTRE_RO_ATTR(activeobd);
402
403 /**
404  * Show UUID of LOD device.
405  */
406 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
407                               char *buf)
408 {
409         struct dt_device *dt = container_of(kobj, struct dt_device,
410                                             dd_kobj);
411         struct lod_device *lod = dt2lod_dev(dt);
412
413         return snprintf(buf, PAGE_SIZE, "%s\n",
414                        lod->lod_ost_descs.ltd_lov_desc.ld_uuid.uuid);
415 }
416 LUSTRE_RO_ATTR(desc_uuid);
417
418 /**
419  * Show QoS priority parameter.
420  *
421  * The printed value is a percentage value (0-100%) indicating the priority
422  * of free space compared to performance. 0% means select OSTs equally
423  * regardless of their free space, 100% means select OSTs only by their free
424  * space even if it results in very imbalanced load on the OSTs.
425  */
426 static ssize_t __qos_prio_free_show(struct kobject *kobj,
427                                     struct attribute *attr, char *buf,
428                                     bool is_mdt)
429 {
430         struct dt_device *dt = container_of(kobj, struct dt_device,
431                                             dd_kobj);
432         struct lod_device *lod = dt2lod_dev(dt);
433         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
434                                             &lod->lod_ost_descs;
435
436         return snprintf(buf, PAGE_SIZE, "%d%%\n",
437                        (ltd->ltd_qos.lq_prio_free * 100 + 255) >> 8);
438 }
439
440 static ssize_t mdt_qos_prio_free_show(struct kobject *kobj,
441                                       struct attribute *attr, char *buf)
442 {
443         return __qos_prio_free_show(kobj, attr, buf, true);
444 }
445
446 static ssize_t qos_prio_free_show(struct kobject *kobj,
447                                   struct attribute *attr, char *buf)
448 {
449         return __qos_prio_free_show(kobj, attr, buf, false);
450 }
451
452 /**
453  * Set QoS free space priority parameter.
454  *
455  * Set the relative priority of free OST space compared to OST load when OSTs
456  * are space imbalanced.  See qos_priofree_show() for description of
457  * this parameter.  See qos_thresholdrr_store() and lq_threshold_rr to
458  * determine what constitutes "space imbalanced" OSTs.
459  */
460 static ssize_t __qos_prio_free_store(struct kobject *kobj,
461                                      struct attribute *attr,
462                                      const char *buffer, size_t count,
463                                      bool is_mdt)
464 {
465         struct dt_device *dt = container_of(kobj, struct dt_device,
466                                             dd_kobj);
467         struct lod_device *lod = dt2lod_dev(dt);
468         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
469                                             &lod->lod_ost_descs;
470         unsigned int val;
471         int rc;
472
473         rc = kstrtouint(buffer, 0, &val);
474         if (rc)
475                 return rc;
476
477         if (val > 100)
478                 return -EINVAL;
479         ltd->ltd_qos.lq_prio_free = (val << 8) / 100;
480         ltd->ltd_qos.lq_dirty = 1;
481         ltd->ltd_qos.lq_reset = 1;
482
483         return count;
484 }
485
486 static ssize_t mdt_qos_prio_free_store(struct kobject *kobj,
487                                        struct attribute *attr,
488                                        const char *buffer, size_t count)
489 {
490         return __qos_prio_free_store(kobj, attr, buffer, count, true);
491 }
492
493 static ssize_t qos_prio_free_store(struct kobject *kobj, struct attribute *attr,
494                                    const char *buffer, size_t count)
495 {
496         return __qos_prio_free_store(kobj, attr, buffer, count, false);
497 }
498
499 LUSTRE_RW_ATTR(mdt_qos_prio_free);
500 LUSTRE_RW_ATTR(qos_prio_free);
501
502 /**
503  * Show threshold for "same space on all OSTs" rule.
504  */
505 static ssize_t __qos_thresholdrr_show(struct kobject *kobj,
506                                     struct attribute *attr, char *buf,
507                                     bool is_mdt)
508 {
509         struct dt_device *dt = container_of(kobj, struct dt_device,
510                                             dd_kobj);
511         struct lod_device *lod = dt2lod_dev(dt);
512         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
513                                             &lod->lod_ost_descs;
514
515         return snprintf(buf, PAGE_SIZE, "%d%%\n",
516                        (ltd->ltd_qos.lq_threshold_rr * 100 + 255) >> 8);
517 }
518
519 static ssize_t mdt_qos_thresholdrr_show(struct kobject *kobj,
520                                         struct attribute *attr, char *buf)
521 {
522         return __qos_thresholdrr_show(kobj, attr, buf, true);
523 }
524
525 static ssize_t qos_thresholdrr_show(struct kobject *kobj,
526                                         struct attribute *attr, char *buf)
527 {
528         return __qos_thresholdrr_show(kobj, attr, buf, false);
529 }
530
531 /**
532  * Set threshold for "same space on all OSTs" rule.
533  *
534  * This sets the maximum percentage difference of free space between the most
535  * full and most empty OST in the currently available OSTs. If this percentage
536  * is exceeded, use the QoS allocator to select OSTs based on their available
537  * space so that more full OSTs are chosen less often, otherwise use the
538  * round-robin allocator for efficiency and performance.
539  */
540 static ssize_t __qos_thresholdrr_store(struct kobject *kobj,
541                                        struct attribute *attr,
542                                        const char *buffer, size_t count,
543                                        bool is_mdt)
544 {
545         struct dt_device *dt = container_of(kobj, struct dt_device,
546                                             dd_kobj);
547         struct lod_device *lod = dt2lod_dev(dt);
548         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
549                                             &lod->lod_ost_descs;
550         unsigned int val;
551         int rc;
552
553         rc = kstrtouint(buffer, 0, &val);
554         if (rc)
555                 return rc;
556
557         if (val > 100)
558                 return -EINVAL;
559         ltd->ltd_qos.lq_threshold_rr = (val << 8) / 100;
560         ltd->ltd_qos.lq_dirty = 1;
561
562         return count;
563 }
564
565 static ssize_t mdt_qos_thresholdrr_store(struct kobject *kobj,
566                                          struct attribute *attr,
567                                          const char *buffer, size_t count)
568 {
569         return __qos_thresholdrr_store(kobj, attr, buffer, count, true);
570 }
571
572 static ssize_t qos_thresholdrr_store(struct kobject *kobj,
573                                      struct attribute *attr,
574                                      const char *buffer, size_t count)
575 {
576         return __qos_thresholdrr_store(kobj, attr, buffer, count, false);
577 }
578
579 LUSTRE_RW_ATTR(mdt_qos_thresholdrr);
580 LUSTRE_RW_ATTR(qos_thresholdrr);
581
582 /**
583  * Show expiration period used to refresh cached statfs data, which
584  * is used to implement QoS/RR striping allocation algorithm.
585  */
586 static ssize_t __qos_maxage_show(struct kobject *kobj, struct attribute *attr,
587                                  char *buf, bool is_mdt)
588 {
589         struct dt_device *dt = container_of(kobj, struct dt_device,
590                                             dd_kobj);
591         struct lod_device *lod = dt2lod_dev(dt);
592         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
593                                             &lod->lod_ost_descs;
594
595         return snprintf(buf, PAGE_SIZE, "%u Sec\n",
596                        ltd->ltd_lov_desc.ld_qos_maxage);
597 }
598
599 static ssize_t mdt_qos_maxage_show(struct kobject *kobj, struct attribute *attr,
600                                    char *buf)
601 {
602         return __qos_maxage_show(kobj, attr, buf, true);
603 }
604
605 static ssize_t qos_maxage_show(struct kobject *kobj, struct attribute *attr,
606                                char *buf)
607 {
608         return __qos_maxage_show(kobj, attr, buf, true);
609 }
610
611 /**
612  * Set expiration period used to refresh cached statfs data.
613  */
614 static ssize_t __qos_maxage_store(struct kobject *kobj, struct attribute *attr,
615                                   const char *buffer, size_t count, bool is_mdt)
616 {
617         struct dt_device *dt = container_of(kobj, struct dt_device,
618                                             dd_kobj);
619         struct lod_device *lod = dt2lod_dev(dt);
620         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
621                                             &lod->lod_ost_descs;
622         struct lustre_cfg_bufs bufs;
623         struct lu_device *next;
624         struct lustre_cfg *lcfg;
625         char str[32];
626         struct lu_tgt_desc *tgt;
627         int rc;
628         u32 val;
629
630         rc = kstrtouint(buffer, 0, &val);
631         if (rc)
632                 return rc;
633
634         if (val <= 0)
635                 return -EINVAL;
636
637         ltd->ltd_lov_desc.ld_qos_maxage = val;
638
639         /*
640          * propogate the value down to OSPs
641          */
642         lustre_cfg_bufs_reset(&bufs, NULL);
643         snprintf(str, 32, "%smaxage=%u", PARAM_OSP, val);
644         lustre_cfg_bufs_set_string(&bufs, 1, str);
645         OBD_ALLOC(lcfg, lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen));
646         if (lcfg == NULL)
647                 return -ENOMEM;
648         lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
649
650         lod_getref(ltd);
651         ltd_foreach_tgt(ltd, tgt) {
652                 next = &tgt->ltd_tgt->dd_lu_dev;
653                 rc = next->ld_ops->ldo_process_config(NULL, next, lcfg);
654                 if (rc)
655                         CERROR("can't set maxage on #%d: %d\n",
656                                tgt->ltd_index, rc);
657         }
658         lod_putref(lod, ltd);
659         OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens));
660
661         return count;
662 }
663
664 static ssize_t mdt_qos_maxage_store(struct kobject *kobj,
665                                     struct attribute *attr,
666                                     const char *buffer, size_t count)
667 {
668         return __qos_maxage_store(kobj, attr, buffer, count, true);
669 }
670
671 static ssize_t qos_maxage_store(struct kobject *kobj, struct attribute *attr,
672                                 const char *buffer, size_t count)
673 {
674         return __qos_maxage_store(kobj, attr, buffer, count, false);
675 }
676
677 LUSTRE_RW_ATTR(mdt_qos_maxage);
678 LUSTRE_RW_ATTR(qos_maxage);
679
680 static void *lod_tgts_seq_start(struct seq_file *p, loff_t *pos, bool is_mdt)
681 {
682         struct obd_device *dev = p->private;
683         struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
684         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
685                                             &lod->lod_ost_descs;
686
687         LASSERT(dev != NULL);
688
689         lod_getref(ltd); /* released in lod_tgts_seq_stop */
690         if (*pos >= ltd->ltd_tgt_bitmap->size)
691                 return NULL;
692
693         *pos = find_next_bit(ltd->ltd_tgt_bitmap->data,
694                              ltd->ltd_tgt_bitmap->size, *pos);
695         if (*pos < ltd->ltd_tgt_bitmap->size)
696                 return LTD_TGT(ltd, *pos);
697         else
698                 return NULL;
699 }
700
701 static void *lod_mdts_seq_start(struct seq_file *p, loff_t *pos)
702 {
703         return lod_tgts_seq_start(p, pos, true);
704 }
705
706 static void *lod_osts_seq_start(struct seq_file *p, loff_t *pos)
707 {
708         return lod_tgts_seq_start(p, pos, false);
709 }
710
711 static void lod_tgts_seq_stop(struct seq_file *p, void *v, bool is_mdt)
712 {
713         struct obd_device *dev = p->private;
714         struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
715         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
716                                             &lod->lod_ost_descs;
717
718         LASSERT(dev != NULL);
719         lod_putref(lod, ltd);
720 }
721
722 static void lod_mdts_seq_stop(struct seq_file *p, void *v)
723 {
724         lod_tgts_seq_stop(p, v, true);
725 }
726
727 static void lod_osts_seq_stop(struct seq_file *p, void *v)
728 {
729         lod_tgts_seq_stop(p, v, false);
730 }
731
732 static void *lod_tgts_seq_next(struct seq_file *p, void *v, loff_t *pos,
733                                bool is_mdt)
734 {
735         struct obd_device *dev = p->private;
736         struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
737         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
738                                             &lod->lod_ost_descs;
739
740         if (*pos >= ltd->ltd_tgt_bitmap->size - 1)
741                 return NULL;
742
743         *pos = find_next_bit(ltd->ltd_tgt_bitmap->data,
744                              ltd->ltd_tgt_bitmap->size, *pos + 1);
745         if (*pos < ltd->ltd_tgt_bitmap->size)
746                 return LTD_TGT(ltd, *pos);
747         else
748                 return NULL;
749 }
750
751 static void *lod_mdts_seq_next(struct seq_file *p, void *v, loff_t *pos)
752 {
753         return lod_tgts_seq_next(p, v, pos, true);
754 }
755
756 static void *lod_osts_seq_next(struct seq_file *p, void *v, loff_t *pos)
757 {
758         return lod_tgts_seq_next(p, v, pos, false);
759 }
760
761 /**
762  * Show active/inactive status for OST found by lod_osts_seq_next().
763  *
764  * \param[in] m         seq file
765  * \param[in] v         unused for single entry
766  *
767  * \retval 0            on success
768  * \retval negative     error code if failed
769  */
770 static int lod_tgts_seq_show(struct seq_file *p, void *v)
771 {
772         struct obd_device *obd = p->private;
773         struct lu_tgt_desc *tgt = v;
774         struct dt_device *next;
775         int rc, active;
776
777         LASSERT(obd->obd_lu_dev);
778
779         next = tgt->ltd_tgt;
780         if (!next)
781                 return -EINVAL;
782
783         /* XXX: should be non-NULL env, but it's very expensive */
784         active = 1;
785         rc = dt_statfs(NULL, next, &tgt->ltd_statfs);
786         if (rc == -ENOTCONN) {
787                 active = 0;
788                 rc = 0;
789         } else if (rc)
790                 return rc;
791
792         seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
793                    obd_uuid2str(&tgt->ltd_uuid),
794                    active ? "" : "IN");
795         return 0;
796 }
797
798 static const struct seq_operations lod_mdts_sops = {
799         .start  = lod_mdts_seq_start,
800         .stop   = lod_mdts_seq_stop,
801         .next   = lod_mdts_seq_next,
802         .show   = lod_tgts_seq_show,
803 };
804
805 static const struct seq_operations lod_osts_sops = {
806         .start  = lod_osts_seq_start,
807         .stop   = lod_osts_seq_stop,
808         .next   = lod_osts_seq_next,
809         .show   = lod_tgts_seq_show,
810 };
811
812 static int lod_mdts_seq_open(struct inode *inode, struct file *file)
813 {
814         struct seq_file *seq;
815         int rc;
816
817         rc = seq_open(file, &lod_mdts_sops);
818         if (rc)
819                 return rc;
820
821         seq = file->private_data;
822         seq->private = PDE_DATA(inode);
823         return 0;
824 }
825
826 static int lod_osts_seq_open(struct inode *inode, struct file *file)
827 {
828         struct seq_file *seq;
829         int rc;
830
831         rc = seq_open(file, &lod_osts_sops);
832         if (rc)
833                 return rc;
834
835         seq = file->private_data;
836         seq->private = PDE_DATA(inode);
837         return 0;
838 }
839
840 /**
841  * Show whether special failout mode for testing is enabled or not.
842  */
843 static ssize_t lmv_failout_show(struct kobject *kobj, struct attribute *attr,
844                                 char *buf)
845 {
846         struct dt_device *dt = container_of(kobj, struct dt_device,
847                                             dd_kobj);
848         struct lod_device *lod = dt2lod_dev(dt);
849
850         return snprintf(buf, PAGE_SIZE, "%d\n", lod->lod_lmv_failout ? 1 : 0);
851 }
852
853 /**
854  * Enable/disable a special failout mode for testing.
855  *
856  * This determines whether the LMV will try to continue processing a striped
857  * directory even if it has a (partly) corrupted entry in the master directory,
858  * or if it will abort upon finding a corrupted slave directory entry.
859  */
860 static ssize_t lmv_failout_store(struct kobject *kobj, struct attribute *attr,
861                                  const char *buffer, size_t count)
862 {
863         struct dt_device *dt = container_of(kobj, struct dt_device,
864                                             dd_kobj);
865         struct lod_device *lod = dt2lod_dev(dt);
866         bool val = 0;
867         int rc;
868
869         rc = kstrtobool(buffer, &val);
870         if (rc)
871                 return rc;
872
873         lod->lod_lmv_failout = val;
874
875         return count;
876 }
877 LUSTRE_RW_ATTR(lmv_failout);
878
879 static struct lprocfs_vars lprocfs_lod_obd_vars[] = {
880         { NULL }
881 };
882
883 static const struct file_operations lod_proc_mdt_fops = {
884         .owner   = THIS_MODULE,
885         .open    = lod_mdts_seq_open,
886         .read    = seq_read,
887         .llseek  = seq_lseek,
888         .release = lprocfs_seq_release,
889 };
890
891 static const struct file_operations lod_proc_target_fops = {
892         .owner   = THIS_MODULE,
893         .open    = lod_osts_seq_open,
894         .read    = seq_read,
895         .llseek  = seq_lseek,
896         .release = lprocfs_seq_release,
897 };
898
899 static struct attribute *lod_attrs[] = {
900         &lustre_attr_dom_stripesize.attr,
901         &lustre_attr_stripesize.attr,
902         &lustre_attr_stripeoffset.attr,
903         &lustre_attr_stripecount.attr,
904         &lustre_attr_stripetype.attr,
905         &lustre_attr_activeobd.attr,
906         &lustre_attr_desc_uuid.attr,
907         &lustre_attr_lmv_failout.attr,
908         &lustre_attr_numobd.attr,
909         &lustre_attr_qos_maxage.attr,
910         &lustre_attr_qos_prio_free.attr,
911         &lustre_attr_qos_thresholdrr.attr,
912         &lustre_attr_mdt_stripecount.attr,
913         &lustre_attr_mdt_stripetype.attr,
914         &lustre_attr_mdt_activeobd.attr,
915         &lustre_attr_mdt_numobd.attr,
916         &lustre_attr_mdt_qos_maxage.attr,
917         &lustre_attr_mdt_qos_prio_free.attr,
918         &lustre_attr_mdt_qos_thresholdrr.attr,
919         NULL,
920 };
921
922 /**
923  * Initialize procfs entries for LOD.
924  *
925  * \param[in] lod       LOD device
926  *
927  * \retval 0            on success
928  * \retval negative     error code if failed
929  */
930 int lod_procfs_init(struct lod_device *lod)
931 {
932         struct lprocfs_vars ldebugfs_obd_vars[] = { { NULL } };
933         struct obd_device *obd = lod2obd(lod);
934         struct obd_type *type;
935         struct kobject *lov;
936         int rc;
937
938         lod->lod_dt_dev.dd_ktype.default_attrs = lod_attrs;
939         rc = dt_tunables_init(&lod->lod_dt_dev, obd->obd_type, obd->obd_name,
940                               ldebugfs_obd_vars);
941         if (rc) {
942                 CERROR("%s: failed to setup DT tunables: %d\n",
943                        obd->obd_name, rc);
944                 RETURN(rc);
945         }
946
947         obd->obd_vars = lprocfs_lod_obd_vars;
948         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
949                                                obd->obd_type->typ_procroot,
950                                                obd->obd_vars, obd);
951         if (IS_ERR(obd->obd_proc_entry)) {
952                 rc = PTR_ERR(obd->obd_proc_entry);
953                 CERROR("%s: error %d setting up lprocfs\n",
954                        obd->obd_name, rc);
955                 GOTO(out, rc);
956         }
957
958         rc = lprocfs_seq_create(obd->obd_proc_entry, "mdt_obd",
959                                 0444, &lod_proc_mdt_fops, obd);
960         if (rc) {
961                 CWARN("%s: Error adding the target_obd file %d\n",
962                       obd->obd_name, rc);
963                 GOTO(out, rc);
964         }
965
966         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
967                                 0444, &lod_proc_target_fops, obd);
968         if (rc) {
969                 CWARN("%s: Error adding the target_obd file %d\n",
970                       obd->obd_name, rc);
971                 GOTO(out, rc);
972         }
973
974         lod->lod_pool_proc_entry = lprocfs_register("pools",
975                                                     obd->obd_proc_entry,
976                                                     NULL, NULL);
977         if (IS_ERR(lod->lod_pool_proc_entry)) {
978                 rc = PTR_ERR(lod->lod_pool_proc_entry);
979                 lod->lod_pool_proc_entry = NULL;
980                 CWARN("%s: Failed to create pool proc file: %d\n",
981                       obd->obd_name, rc);
982                 GOTO(out, rc);
983         }
984
985         lov = kset_find_obj(lustre_kset, "lov");
986         if (!lov) {
987                 CERROR("%s: lov subsystem not found\n", obd->obd_name);
988                 GOTO(out, rc = -ENODEV);
989         }
990
991         rc = sysfs_create_link(lov, &lod->lod_dt_dev.dd_kobj,
992                                obd->obd_name);
993         if (rc)
994                 CERROR("%s: failed to create LOV sysfs symlink\n",
995                        obd->obd_name);
996         kobject_put(lov);
997
998         lod->lod_debugfs = ldebugfs_add_symlink(obd->obd_name, "lov",
999                                                 "../lod/%s", obd->obd_name);
1000         if (!lod->lod_debugfs)
1001                 CERROR("%s: failed to create LOV debugfs symlink\n",
1002                        obd->obd_name);
1003
1004         type = container_of(lov, struct obd_type, typ_kobj);
1005         if (!type->typ_procroot)
1006                 RETURN(0);
1007
1008         /* for compatibility we link old procfs's LOV entries to lod ones */
1009         lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
1010                                                type->typ_procroot,
1011                                                "../lod/%s", obd->obd_name);
1012         if (lod->lod_symlink == NULL)
1013                 CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n",
1014                        obd->obd_name);
1015         RETURN(0);
1016
1017 out:
1018         dt_tunables_fini(&lod->lod_dt_dev);
1019
1020         return rc;
1021 }
1022
1023 /**
1024  * Cleanup procfs entries registred for LOD.
1025  *
1026  * \param[in] lod       LOD device
1027  */
1028 void lod_procfs_fini(struct lod_device *lod)
1029 {
1030         struct obd_device *obd = lod2obd(lod);
1031         struct kobject *lov;
1032
1033         if (lod->lod_symlink != NULL) {
1034                 lprocfs_remove(&lod->lod_symlink);
1035                 lod->lod_symlink = NULL;
1036         }
1037
1038         lov = kset_find_obj(lustre_kset, "lov");
1039         if (lov) {
1040                 sysfs_remove_link(lov, obd->obd_name);
1041                 kobject_put(lov);
1042         }
1043
1044         if (!IS_ERR_OR_NULL(lod->lod_debugfs))
1045                 ldebugfs_remove(&lod->lod_debugfs);
1046
1047         if (obd->obd_proc_entry) {
1048                 lprocfs_remove(&obd->obd_proc_entry);
1049                 obd->obd_proc_entry = NULL;
1050         }
1051
1052         dt_tunables_fini(&lod->lod_dt_dev);
1053 }
1054
1055 #endif /* CONFIG_PROC_FS */