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