Whamcloud - gitweb
LU-8915 lnet: migrate LNet selftest session handling to Netlink
[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  */
31 #define DEBUG_SUBSYSTEM S_CLASS
32
33 #include <lprocfs_status.h>
34 #include <obd_class.h>
35 #include <linux/seq_file.h>
36 #include "lod_internal.h"
37 #include <uapi/linux/lustre/lustre_param.h>
38
39 /*
40  * Notice, all the functions below (except for lod_procfs_init() and
41  * lod_procfs_fini()) are not supposed to be used directly. They are
42  * called by Linux kernel's procfs.
43  */
44
45 #ifdef CONFIG_PROC_FS
46
47 static ssize_t dom_stripesize_show(struct kobject *kobj,
48                                    struct attribute *attr,
49                                    char *buf)
50 {
51         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
52         struct lod_device *lod = dt2lod_dev(dt);
53
54         return scnprintf(buf, PAGE_SIZE, "%u\n",
55                          lod->lod_dom_stripesize_max_kb << 10);
56 }
57
58 static inline int dom_stripesize_max_kb_update(struct lod_device *lod,
59                                                __u64 val)
60 {
61         /* 1GB is the limit */
62         if (val > (1ULL << 20))
63                 return -ERANGE;
64
65         if (val > 0) {
66                 if (val < LOD_DOM_MIN_SIZE_KB) {
67                         LCONSOLE_INFO("Increasing provided stripe size to a minimum value %u\n",
68                                       LOD_DOM_MIN_SIZE_KB);
69                         val = LOD_DOM_MIN_SIZE_KB;
70                 } else if (val & (LOD_DOM_MIN_SIZE_KB - 1)) {
71                         val &= ~(LOD_DOM_MIN_SIZE_KB - 1);
72                         LCONSOLE_WARN("Changing provided stripe size to %llu (a multiple of minimum %u)\n",
73                                       val, LOD_DOM_MIN_SIZE_KB);
74                 }
75         }
76         spin_lock(&lod->lod_lsfs_lock);
77         lod->lod_dom_stripesize_max_kb = val;
78         lod_dom_stripesize_recalc(lod);
79         spin_unlock(&lod->lod_lsfs_lock);
80         return 0;
81 }
82
83 static ssize_t dom_stripesize_store(struct kobject *kobj,
84                                     struct attribute *attr,
85                                     const char *buffer, size_t count)
86 {
87         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
88         struct lod_device *lod = dt2lod_dev(dt);
89         u64 val;
90         int rc;
91
92         rc = sysfs_memparse(buffer, count, &val, "B");
93         if (rc < 0)
94                 return rc;
95
96         rc = dom_stripesize_max_kb_update(lod, val >> 10);
97         if (rc)
98                 return rc;
99         return count;
100 }
101
102 /* Old attribute name is still supported */
103 LUSTRE_RW_ATTR(dom_stripesize);
104
105 /**
106  * Show DoM maximum allowed stripe size.
107  */
108 static ssize_t dom_stripesize_max_kb_show(struct kobject *kobj,
109                                           struct attribute *attr,
110                                           char *buf)
111 {
112         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
113         struct lod_device *lod = dt2lod_dev(dt);
114
115         return scnprintf(buf, PAGE_SIZE, "%u\n",
116                          lod->lod_dom_stripesize_max_kb);
117 }
118
119 /**
120  * Set DoM maximum allowed stripe size.
121  */
122 static ssize_t dom_stripesize_max_kb_store(struct kobject *kobj,
123                                            struct attribute *attr,
124                                            const char *buffer, size_t count)
125 {
126         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
127         struct lod_device *lod = dt2lod_dev(dt);
128         u64 val;
129         int rc;
130
131         rc = sysfs_memparse(buffer, count, &val, "KiB");
132         if (rc < 0)
133                 return rc;
134
135         rc = dom_stripesize_max_kb_update(lod, val >> 10);
136         if (rc)
137                 return rc;
138         return count;
139 }
140 LUSTRE_RW_ATTR(dom_stripesize_max_kb);
141
142 /**
143  * Show DoM default stripe size.
144  */
145 static ssize_t dom_stripesize_cur_kb_show(struct kobject *kobj,
146                                           struct attribute *attr,
147                                           char *buf)
148 {
149         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
150         struct lod_device *lod = dt2lod_dev(dt);
151
152         return scnprintf(buf, PAGE_SIZE, "%u\n",
153                          lod->lod_dom_stripesize_cur_kb);
154 }
155
156 LUSTRE_RO_ATTR(dom_stripesize_cur_kb);
157
158 /**
159  * Show DoM threshold.
160  */
161 static ssize_t dom_threshold_free_mb_show(struct kobject *kobj,
162                                           struct attribute *attr, char *buf)
163 {
164         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
165         struct lod_device *lod = dt2lod_dev(dt);
166
167         return scnprintf(buf, PAGE_SIZE, "%llu\n",
168                          lod->lod_dom_threshold_free_mb);
169 }
170
171 /**
172  * Set DoM default stripe size.
173  */
174 static ssize_t dom_threshold_free_mb_store(struct kobject *kobj,
175                                            struct attribute *attr,
176                                            const char *buffer, size_t count)
177 {
178         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
179         struct lod_device *lod = dt2lod_dev(dt);
180         u64 val;
181         int rc;
182         char *pct;
183
184         pct = strnchr(buffer, count, '%');
185         if (pct) {
186                 rc = string_to_size(&val, buffer, pct - buffer);
187                 if (rc < 0)
188                         return rc;
189                 val = mult_frac(lod->lod_lsfs_total_mb,
190                                 min_t(unsigned int, val, 100), 100);
191         } else {
192                 rc = sysfs_memparse(buffer, count, &val, "MiB");
193                 if (rc < 0)
194                         return rc;
195                 val >>= 20;
196         }
197
198         spin_lock(&lod->lod_lsfs_lock);
199         lod->lod_dom_threshold_free_mb = val;
200         lod_dom_stripesize_recalc(lod);
201         spin_unlock(&lod->lod_lsfs_lock);
202
203         return count;
204 }
205
206 LUSTRE_RW_ATTR(dom_threshold_free_mb);
207
208 static ssize_t stripesize_show(struct kobject *kobj, struct attribute *attr,
209                                char *buf)
210 {
211         struct dt_device *dt = container_of(kobj, struct dt_device,
212                                             dd_kobj);
213         struct lod_device *lod = dt2lod_dev(dt);
214
215         return scnprintf(buf, PAGE_SIZE, "%llu\n",
216                          lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_size);
217 }
218
219 static ssize_t stripesize_store(struct kobject *kobj, struct attribute *attr,
220                                 const char *buffer, size_t count)
221 {
222         struct dt_device *dt = container_of(kobj, struct dt_device,
223                                             dd_kobj);
224         struct lod_device *lod = dt2lod_dev(dt);
225         u64 val;
226         int rc;
227
228         rc = sysfs_memparse(buffer, count, &val, "B");
229         if (rc < 0)
230                 return rc;
231
232         lod_fix_desc_stripe_size(&val);
233         lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_size = val;
234
235         return count;
236 }
237
238 LUSTRE_RW_ATTR(stripesize);
239
240 /**
241  * Show default stripe offset.
242  */
243 static ssize_t stripeoffset_show(struct kobject *kobj, struct attribute *attr,
244                                  char *buf)
245 {
246         struct dt_device *dt = container_of(kobj, struct dt_device,
247                                             dd_kobj);
248         struct lod_device *lod = dt2lod_dev(dt);
249
250         return scnprintf(buf, PAGE_SIZE, "%lld\n",
251                 lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_offset);
252 }
253
254 /**
255  * Set default stripe offset.
256  *
257  * Usually contains -1 allowing Lustre to balance objects among OST
258  * otherwise may cause severe OST imbalance.
259  */
260 static ssize_t stripeoffset_store(struct kobject *kobj,
261                                     struct attribute *attr,
262                                     const char *buffer, size_t count)
263 {
264         struct dt_device *dt = container_of(kobj, struct dt_device,
265                                             dd_kobj);
266         struct lod_device *lod = dt2lod_dev(dt);
267         long val;
268         int rc;
269
270         rc = kstrtol(buffer, 0, &val);
271         if (rc)
272                 return rc;
273
274         if (val < -1 || val > LOV_MAX_STRIPE_COUNT)
275                 return -ERANGE;
276
277         lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_offset = val;
278
279         return count;
280 }
281
282 LUSTRE_RW_ATTR(stripeoffset);
283
284 static ssize_t max_stripecount_show(struct kobject *kobj,
285                                     struct attribute *attr, char *buf)
286 {
287         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
288         struct lod_device *lod = dt2lod_dev(dt);
289
290         return scnprintf(buf, PAGE_SIZE, "%u\n", lod->lod_max_stripecount);
291 }
292
293 static ssize_t max_stripecount_store(struct kobject *kobj,
294                                      struct attribute *attr,
295                                      const char *buffer, size_t count)
296 {
297         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
298         struct lod_device *lod = dt2lod_dev(dt);
299         long val;
300         int rc;
301
302         rc = kstrtol(buffer, 0, &val);
303         if (rc)
304                 return rc;
305
306         if (val < 0 || val > LOV_MAX_STRIPE_COUNT)
307                 return -ERANGE;
308
309         lod->lod_max_stripecount = val;
310
311         return count;
312 }
313
314 LUSTRE_RW_ATTR(max_stripecount);
315
316 static ssize_t max_mdt_stripecount_show(struct kobject *kobj,
317                                     struct attribute *attr, char *buf)
318 {
319         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
320         struct lod_device *lod = dt2lod_dev(dt);
321
322         return scnprintf(buf, PAGE_SIZE, "%u\n", lod->lod_max_mdt_stripecount);
323 }
324
325 static ssize_t max_mdt_stripecount_store(struct kobject *kobj,
326                                      struct attribute *attr,
327                                      const char *buffer, size_t count)
328 {
329         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
330         struct lod_device *lod = dt2lod_dev(dt);
331         long val;
332         int rc;
333
334         rc = kstrtol(buffer, 0, &val);
335         if (rc)
336                 return rc;
337
338         if (val < 0 || val > LMV_MAX_STRIPE_COUNT) /* any limitation? */
339                 return -ERANGE;
340
341         lod->lod_max_mdt_stripecount = val;
342
343         return count;
344 }
345
346 LUSTRE_RW_ATTR(max_mdt_stripecount);
347
348
349 /**
350  * Show default striping pattern (LOV_PATTERN_*).
351  */
352 static ssize_t __stripetype_show(struct kobject *kobj, struct attribute *attr,
353                                  char *buf, bool is_mdt)
354 {
355         struct dt_device *dt = container_of(kobj, struct dt_device,
356                                             dd_kobj);
357         struct lod_device *lod = dt2lod_dev(dt);
358         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
359                                             &lod->lod_ost_descs;
360
361         return scnprintf(buf, PAGE_SIZE, "%u\n", ltd->ltd_lov_desc.ld_pattern);
362 }
363
364 static ssize_t mdt_stripetype_show(struct kobject *kobj, struct attribute *attr,
365                                    char *buf)
366 {
367         return __stripetype_show(kobj, attr, buf, true);
368 }
369
370 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
371                                char *buf)
372 {
373         return __stripetype_show(kobj, attr, buf, false);
374 }
375
376 /**
377  * Set default striping pattern (a number, not a human-readable string).
378  */
379 static ssize_t __stripetype_store(struct kobject *kobj, struct attribute *attr,
380                                   const char *buffer, size_t count, bool is_mdt)
381 {
382         struct dt_device *dt = container_of(kobj, struct dt_device,
383                                             dd_kobj);
384         struct lod_device *lod = dt2lod_dev(dt);
385         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
386                                             &lod->lod_ost_descs;
387         u32 pattern;
388         int rc;
389
390         rc = kstrtouint(buffer, 0, &pattern);
391         if (rc)
392                 return rc;
393
394         if (is_mdt)
395                 lod_fix_lmv_desc_pattern(&pattern);
396         else
397                 lod_fix_desc_pattern(&pattern);
398
399         ltd->ltd_lov_desc.ld_pattern = pattern;
400
401         return count;
402 }
403
404 static ssize_t mdt_stripetype_store(struct kobject *kobj,
405                                     struct attribute *attr, const char *buffer,
406                                     size_t count)
407 {
408         return __stripetype_store(kobj, attr, buffer, count, true);
409 }
410
411 static ssize_t stripetype_store(struct kobject *kobj,
412                                     struct attribute *attr, const char *buffer,
413                                     size_t count)
414 {
415         return __stripetype_store(kobj, attr, buffer, count, false);
416 }
417
418 LUSTRE_RW_ATTR(mdt_stripetype);
419 LUSTRE_RW_ATTR(stripetype);
420
421 /**
422  * Show default number of stripes.
423  */
424 static ssize_t __stripecount_show(struct kobject *kobj, struct attribute *attr,
425                                   char *buf, bool is_mdt)
426 {
427         struct dt_device *dt = container_of(kobj, struct dt_device,
428                                             dd_kobj);
429         struct lod_device *lod = dt2lod_dev(dt);
430         struct lov_desc *desc = is_mdt ? &lod->lod_mdt_descs.ltd_lov_desc :
431                                          &lod->lod_ost_descs.ltd_lov_desc;
432
433         return scnprintf(buf, PAGE_SIZE, "%d\n",
434                          (s16)(desc->ld_default_stripe_count + 1) - 1);
435 }
436
437 static ssize_t mdt_stripecount_show(struct kobject *kobj,
438                                     struct attribute *attr, char *buf)
439 {
440         return __stripecount_show(kobj, attr, buf, true);
441 }
442
443 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
444                                 char *buf)
445 {
446         return __stripecount_show(kobj, attr, buf, false);
447 }
448
449 /**
450  * Set default number of stripes.
451  */
452 static ssize_t __stripecount_store(struct kobject *kobj, struct attribute *attr,
453                                    const char *buffer, size_t count,
454                                    bool is_mdt)
455 {
456         struct dt_device *dt = container_of(kobj, struct dt_device,
457                                             dd_kobj);
458         struct lod_device *lod = dt2lod_dev(dt);
459         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
460                                             &lod->lod_ost_descs;
461         int stripe_count;
462         int rc;
463
464         rc = kstrtoint(buffer, 0, &stripe_count);
465         if (rc)
466                 return rc;
467
468         if (stripe_count < -1)
469                 return -ERANGE;
470
471         lod_fix_desc_stripe_count(&stripe_count);
472         ltd->ltd_lov_desc.ld_default_stripe_count = stripe_count;
473
474         return count;
475 }
476
477 static ssize_t mdt_stripecount_store(struct kobject *kobj,
478                                      struct attribute *attr,
479                                      const char *buffer, size_t count)
480 {
481         return __stripecount_store(kobj, attr, buffer, count, true);
482 }
483
484 static ssize_t stripecount_store(struct kobject *kobj,
485                                  struct attribute *attr,
486                                  const char *buffer, size_t count)
487 {
488         return __stripecount_store(kobj, attr, buffer, count, false);
489 }
490
491 LUSTRE_RW_ATTR(mdt_stripecount);
492 LUSTRE_RW_ATTR(stripecount);
493
494 /**
495  * Show number of targets.
496  */
497 static ssize_t __numobd_show(struct kobject *kobj, struct attribute *attr,
498                              char *buf, bool is_mdt)
499 {
500         struct dt_device *dt = container_of(kobj, struct dt_device,
501                                             dd_kobj);
502         struct lod_device *lod = dt2lod_dev(dt);
503         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
504                                             &lod->lod_ost_descs;
505
506         return scnprintf(buf, PAGE_SIZE, "%u\n",
507                          ltd->ltd_lov_desc.ld_tgt_count);
508 }
509
510 static ssize_t mdt_numobd_show(struct kobject *kobj, struct attribute *attr,
511                                char *buf)
512 {
513         return __numobd_show(kobj, attr, buf, true);
514 }
515
516 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
517                            char *buf)
518 {
519         return __numobd_show(kobj, attr, buf, false);
520 }
521
522 LUSTRE_RO_ATTR(mdt_numobd);
523 LUSTRE_RO_ATTR(numobd);
524
525 /**
526  * Show number of active targets.
527  */
528 static ssize_t __activeobd_show(struct kobject *kobj, struct attribute *attr,
529                                 char *buf, bool is_mdt)
530 {
531         struct dt_device *dt = container_of(kobj, struct dt_device,
532                                             dd_kobj);
533         struct lod_device *lod = dt2lod_dev(dt);
534         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
535                                             &lod->lod_ost_descs;
536
537         return scnprintf(buf, PAGE_SIZE, "%u\n",
538                          ltd->ltd_lov_desc.ld_active_tgt_count);
539 }
540
541 static ssize_t mdt_activeobd_show(struct kobject *kobj, struct attribute *attr,
542                                   char *buf)
543 {
544         return __activeobd_show(kobj, attr, buf, true);
545 }
546
547 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
548                               char *buf)
549 {
550         return __activeobd_show(kobj, attr, buf, false);
551 }
552
553 LUSTRE_RO_ATTR(mdt_activeobd);
554 LUSTRE_RO_ATTR(activeobd);
555
556 /**
557  * Show UUID of LOD device.
558  */
559 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
560                               char *buf)
561 {
562         struct dt_device *dt = container_of(kobj, struct dt_device,
563                                             dd_kobj);
564         struct lod_device *lod = dt2lod_dev(dt);
565
566         return scnprintf(buf, PAGE_SIZE, "%s\n",
567                          lod->lod_ost_descs.ltd_lov_desc.ld_uuid.uuid);
568 }
569 LUSTRE_RO_ATTR(desc_uuid);
570
571 /**
572  * Show QoS priority parameter.
573  *
574  * The printed value is a percentage value (0-100%) indicating the priority
575  * of free space compared to performance. 0% means select OSTs equally
576  * regardless of their free space, 100% means select OSTs only by their free
577  * space even if it results in very imbalanced load on the OSTs.
578  */
579 static ssize_t __qos_prio_free_show(struct kobject *kobj,
580                                     struct attribute *attr, char *buf,
581                                     bool is_mdt)
582 {
583         struct dt_device *dt = container_of(kobj, struct dt_device,
584                                             dd_kobj);
585         struct lod_device *lod = dt2lod_dev(dt);
586         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
587                                             &lod->lod_ost_descs;
588
589         return scnprintf(buf, PAGE_SIZE, "%d%%\n",
590                          (ltd->ltd_qos.lq_prio_free * 100 + 255) >> 8);
591 }
592
593 static ssize_t mdt_qos_prio_free_show(struct kobject *kobj,
594                                       struct attribute *attr, char *buf)
595 {
596         return __qos_prio_free_show(kobj, attr, buf, true);
597 }
598
599 static ssize_t qos_prio_free_show(struct kobject *kobj,
600                                   struct attribute *attr, char *buf)
601 {
602         return __qos_prio_free_show(kobj, attr, buf, false);
603 }
604
605 /**
606  * Set QoS free space priority parameter.
607  *
608  * Set the relative priority of free OST space compared to OST load when OSTs
609  * are space imbalanced.  See qos_priofree_show() for description of
610  * this parameter.  See qos_threshold_rr_store() and lq_threshold_rr to
611  * determine what constitutes "space imbalanced" OSTs.
612  */
613 static ssize_t __qos_prio_free_store(struct kobject *kobj,
614                                      struct attribute *attr,
615                                      const char *buffer, size_t count,
616                                      bool is_mdt)
617 {
618         struct dt_device *dt = container_of(kobj, struct dt_device,
619                                             dd_kobj);
620         struct lod_device *lod = dt2lod_dev(dt);
621         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
622                                             &lod->lod_ost_descs;
623         char buf[6], *tmp;
624         unsigned int val;
625         int rc;
626
627         /* "100%\n\0" should be largest string */
628         if (count >= sizeof(buf))
629                 return -ERANGE;
630
631         strncpy(buf, buffer, sizeof(buf));
632         buf[sizeof(buf) - 1] = '\0';
633         tmp = strchr(buf, '%');
634         if (tmp)
635                 *tmp = '\0';
636
637         rc = kstrtouint(buf, 0, &val);
638         if (rc)
639                 return rc;
640
641         if (val > 100)
642                 return -EINVAL;
643
644         ltd->ltd_qos.lq_prio_free = (val << 8) / 100;
645         set_bit(LQ_DIRTY, &ltd->ltd_qos.lq_flags);
646         set_bit(LQ_RESET, &ltd->ltd_qos.lq_flags);
647
648         return count;
649 }
650
651 static ssize_t mdt_qos_prio_free_store(struct kobject *kobj,
652                                        struct attribute *attr,
653                                        const char *buffer, size_t count)
654 {
655         return __qos_prio_free_store(kobj, attr, buffer, count, true);
656 }
657
658 static ssize_t qos_prio_free_store(struct kobject *kobj, struct attribute *attr,
659                                    const char *buffer, size_t count)
660 {
661         return __qos_prio_free_store(kobj, attr, buffer, count, false);
662 }
663
664 LUSTRE_RW_ATTR(mdt_qos_prio_free);
665 LUSTRE_RW_ATTR(qos_prio_free);
666
667 /**
668  * Show threshold for "same space on all OSTs" rule.
669  */
670 static ssize_t __qos_threshold_rr_show(struct kobject *kobj,
671                                        struct attribute *attr, char *buf,
672                                        bool is_mdt)
673 {
674         struct dt_device *dt = container_of(kobj, struct dt_device,
675                                             dd_kobj);
676         struct lod_device *lod = dt2lod_dev(dt);
677         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
678                                             &lod->lod_ost_descs;
679
680         return scnprintf(buf, PAGE_SIZE, "%d%%\n",
681                          (ltd->ltd_qos.lq_threshold_rr * 100 +
682                           (QOS_THRESHOLD_MAX - 1)) / QOS_THRESHOLD_MAX);
683 }
684
685 static ssize_t mdt_qos_threshold_rr_show(struct kobject *kobj,
686                                          struct attribute *attr, char *buf)
687 {
688         return __qos_threshold_rr_show(kobj, attr, buf, true);
689 }
690
691 static ssize_t qos_threshold_rr_show(struct kobject *kobj,
692                                      struct attribute *attr, char *buf)
693 {
694         return __qos_threshold_rr_show(kobj, attr, buf, false);
695 }
696
697 /**
698  * Set threshold for "same space on all OSTs" rule.
699  *
700  * This sets the maximum percentage difference of free space between the most
701  * full and most empty OST in the currently available OSTs. If this percentage
702  * is exceeded, use the QoS allocator to select OSTs based on their available
703  * space so that more full OSTs are chosen less often, otherwise use the
704  * round-robin allocator for efficiency and performance.
705  */
706 static ssize_t __qos_threshold_rr_store(struct kobject *kobj,
707                                         struct attribute *attr,
708                                         const char *buffer, size_t count,
709                                         bool is_mdt)
710 {
711         struct dt_device *dt = container_of(kobj, struct dt_device,
712                                             dd_kobj);
713         struct lod_device *lod = dt2lod_dev(dt);
714         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
715                                             &lod->lod_ost_descs;
716         char buf[6], *tmp;
717         unsigned int val;
718         int rc;
719
720         /* "100%\n\0" should be largest string */
721         if (count >= sizeof(buf))
722                 return -ERANGE;
723
724         strncpy(buf, buffer, sizeof(buf));
725         buf[sizeof(buf) - 1] = '\0';
726         tmp = strchr(buf, '%');
727         if (tmp)
728                 *tmp = '\0';
729
730         rc = kstrtouint(buf, 0, &val);
731         if (rc)
732                 return rc;
733
734         if (val > 100)
735                 return -EINVAL;
736         ltd->ltd_qos.lq_threshold_rr = (val * QOS_THRESHOLD_MAX) / 100;
737         set_bit(LQ_DIRTY, &ltd->ltd_qos.lq_flags);
738
739         return count;
740 }
741
742 static ssize_t mdt_qos_threshold_rr_store(struct kobject *kobj,
743                                           struct attribute *attr,
744                                           const char *buffer, size_t count)
745 {
746         return __qos_threshold_rr_store(kobj, attr, buffer, count, true);
747 }
748
749 static ssize_t qos_threshold_rr_store(struct kobject *kobj,
750                                       struct attribute *attr,
751                                       const char *buffer, size_t count)
752 {
753         return __qos_threshold_rr_store(kobj, attr, buffer, count, false);
754 }
755
756 LUSTRE_RW_ATTR(mdt_qos_threshold_rr);
757 LUSTRE_RW_ATTR(qos_threshold_rr);
758
759 /**
760  * Show expiration period used to refresh cached statfs data, which
761  * is used to implement QoS/RR striping allocation algorithm.
762  */
763 static ssize_t __qos_maxage_show(struct kobject *kobj, struct attribute *attr,
764                                  char *buf, bool is_mdt)
765 {
766         struct dt_device *dt = container_of(kobj, struct dt_device,
767                                             dd_kobj);
768         struct lod_device *lod = dt2lod_dev(dt);
769         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
770                                             &lod->lod_ost_descs;
771
772         return scnprintf(buf, PAGE_SIZE, "%u\n",
773                          ltd->ltd_lov_desc.ld_qos_maxage);
774 }
775
776 static ssize_t mdt_qos_maxage_show(struct kobject *kobj, struct attribute *attr,
777                                    char *buf)
778 {
779         return __qos_maxage_show(kobj, attr, buf, true);
780 }
781
782 static ssize_t qos_maxage_show(struct kobject *kobj, struct attribute *attr,
783                                char *buf)
784 {
785         return __qos_maxage_show(kobj, attr, buf, true);
786 }
787
788 /**
789  * Set expiration period used to refresh cached statfs data.
790  */
791 static ssize_t __qos_maxage_store(struct kobject *kobj, struct attribute *attr,
792                                   const char *buffer, size_t count, bool is_mdt)
793 {
794         struct dt_device *dt = container_of(kobj, struct dt_device,
795                                             dd_kobj);
796         struct lod_device *lod = dt2lod_dev(dt);
797         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
798                                             &lod->lod_ost_descs;
799         struct lustre_cfg_bufs bufs;
800         struct lu_device *next;
801         struct lustre_cfg *lcfg;
802         char str[32];
803         struct lu_tgt_desc *tgt;
804         int rc;
805         u32 val;
806
807         rc = kstrtouint(buffer, 0, &val);
808         if (rc)
809                 return rc;
810
811         if (val <= 0)
812                 return -EINVAL;
813
814         ltd->ltd_lov_desc.ld_qos_maxage = val;
815
816         /*
817          * propogate the value down to OSPs
818          */
819         lustre_cfg_bufs_reset(&bufs, NULL);
820         snprintf(str, 32, "%smaxage=%u", PARAM_OSP, val);
821         lustre_cfg_bufs_set_string(&bufs, 1, str);
822         OBD_ALLOC(lcfg, lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen));
823         if (lcfg == NULL)
824                 return -ENOMEM;
825         lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
826
827         lod_getref(ltd);
828         ltd_foreach_tgt(ltd, tgt) {
829                 next = &tgt->ltd_tgt->dd_lu_dev;
830                 rc = next->ld_ops->ldo_process_config(NULL, next, lcfg);
831                 if (rc)
832                         CERROR("can't set maxage on #%d: %d\n",
833                                tgt->ltd_index, rc);
834         }
835         lod_putref(lod, ltd);
836         OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens));
837
838         return count;
839 }
840
841 static ssize_t mdt_qos_maxage_store(struct kobject *kobj,
842                                     struct attribute *attr,
843                                     const char *buffer, size_t count)
844 {
845         return __qos_maxage_store(kobj, attr, buffer, count, true);
846 }
847
848 static ssize_t qos_maxage_store(struct kobject *kobj, struct attribute *attr,
849                                 const char *buffer, size_t count)
850 {
851         return __qos_maxage_store(kobj, attr, buffer, count, false);
852 }
853
854 LUSTRE_RW_ATTR(mdt_qos_maxage);
855 LUSTRE_RW_ATTR(qos_maxage);
856
857 static void *lod_tgts_seq_start(struct seq_file *p, loff_t *pos, bool is_mdt)
858 {
859         struct obd_device *obd = p->private;
860         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
861         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
862                                             &lod->lod_ost_descs;
863
864         LASSERT(obd != NULL);
865
866         lod_getref(ltd); /* released in lod_tgts_seq_stop */
867         if (*pos >= ltd->ltd_tgts_size)
868                 return NULL;
869
870         *pos = find_next_bit(ltd->ltd_tgt_bitmap,
871                              ltd->ltd_tgts_size, *pos);
872         if (*pos < ltd->ltd_tgts_size)
873                 return LTD_TGT(ltd, *pos);
874         else
875                 return NULL;
876 }
877
878 static void *lod_mdts_seq_start(struct seq_file *p, loff_t *pos)
879 {
880         return lod_tgts_seq_start(p, pos, true);
881 }
882
883 static void *lod_osts_seq_start(struct seq_file *p, loff_t *pos)
884 {
885         return lod_tgts_seq_start(p, pos, false);
886 }
887
888 static void lod_tgts_seq_stop(struct seq_file *p, void *v, bool is_mdt)
889 {
890         struct obd_device *obd = p->private;
891         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
892         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
893                                             &lod->lod_ost_descs;
894
895         LASSERT(obd != NULL);
896         lod_putref(lod, ltd);
897 }
898
899 static void lod_mdts_seq_stop(struct seq_file *p, void *v)
900 {
901         lod_tgts_seq_stop(p, v, true);
902 }
903
904 static void lod_osts_seq_stop(struct seq_file *p, void *v)
905 {
906         lod_tgts_seq_stop(p, v, false);
907 }
908
909 static void *lod_tgts_seq_next(struct seq_file *p, void *v, loff_t *pos,
910                                bool is_mdt)
911 {
912         struct obd_device *obd = p->private;
913         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
914         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
915                                             &lod->lod_ost_descs;
916
917         (*pos)++;
918         if (*pos > ltd->ltd_tgts_size - 1)
919                 return NULL;
920
921         *pos = find_next_bit(ltd->ltd_tgt_bitmap,
922                              ltd->ltd_tgts_size, *pos);
923         if (*pos < ltd->ltd_tgts_size)
924                 return LTD_TGT(ltd, *pos);
925         else
926                 return NULL;
927 }
928
929 static void *lod_mdts_seq_next(struct seq_file *p, void *v, loff_t *pos)
930 {
931         return lod_tgts_seq_next(p, v, pos, true);
932 }
933
934 static void *lod_osts_seq_next(struct seq_file *p, void *v, loff_t *pos)
935 {
936         return lod_tgts_seq_next(p, v, pos, false);
937 }
938
939 /**
940  * Show active/inactive status for OST found by lod_osts_seq_next().
941  *
942  * \param[in] m         seq file
943  * \param[in] v         unused for single entry
944  *
945  * \retval 0            on success
946  * \retval negative     error code if failed
947  */
948 static int lod_tgts_seq_show(struct seq_file *p, void *v)
949 {
950         struct obd_device *obd = p->private;
951         struct lu_tgt_desc *tgt = v;
952         struct dt_device *next;
953         int rc, active;
954
955         LASSERT(obd->obd_lu_dev);
956
957         next = tgt->ltd_tgt;
958         if (!next)
959                 return -EINVAL;
960
961         /* XXX: should be non-NULL env, but it's very expensive */
962         active = 1;
963         rc = dt_statfs(NULL, next, &tgt->ltd_statfs);
964         if (rc == -ENOTCONN) {
965                 active = 0;
966                 rc = 0;
967         } else if (rc)
968                 return rc;
969
970         seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
971                    obd_uuid2str(&tgt->ltd_uuid),
972                    active ? "" : "IN");
973         return 0;
974 }
975
976 static const struct seq_operations lod_mdts_sops = {
977         .start  = lod_mdts_seq_start,
978         .stop   = lod_mdts_seq_stop,
979         .next   = lod_mdts_seq_next,
980         .show   = lod_tgts_seq_show,
981 };
982
983 static const struct seq_operations lod_osts_sops = {
984         .start  = lod_osts_seq_start,
985         .stop   = lod_osts_seq_stop,
986         .next   = lod_osts_seq_next,
987         .show   = lod_tgts_seq_show,
988 };
989
990 static int lod_mdts_seq_open(struct inode *inode, struct file *file)
991 {
992         struct seq_file *seq;
993         int rc;
994
995         rc = seq_open(file, &lod_mdts_sops);
996         if (rc)
997                 return rc;
998
999         seq = file->private_data;
1000         seq->private = PDE_DATA(inode);
1001         return 0;
1002 }
1003
1004 static int lod_osts_seq_open(struct inode *inode, struct file *file)
1005 {
1006         struct seq_file *seq;
1007         int rc;
1008
1009         rc = seq_open(file, &lod_osts_sops);
1010         if (rc)
1011                 return rc;
1012
1013         seq = file->private_data;
1014         seq->private = PDE_DATA(inode);
1015         return 0;
1016 }
1017
1018 /**
1019  * Show whether special failout mode for testing is enabled or not.
1020  */
1021 static ssize_t lmv_failout_show(struct kobject *kobj, struct attribute *attr,
1022                                 char *buf)
1023 {
1024         struct dt_device *dt = container_of(kobj, struct dt_device,
1025                                             dd_kobj);
1026         struct lod_device *lod = dt2lod_dev(dt);
1027
1028         return scnprintf(buf, PAGE_SIZE, "%d\n", lod->lod_lmv_failout ? 1 : 0);
1029 }
1030
1031 /**
1032  * Enable/disable a special failout mode for testing.
1033  *
1034  * This determines whether the LMV will try to continue processing a striped
1035  * directory even if it has a (partly) corrupted entry in the master directory,
1036  * or if it will abort upon finding a corrupted slave directory entry.
1037  */
1038 static ssize_t lmv_failout_store(struct kobject *kobj, struct attribute *attr,
1039                                  const char *buffer, size_t count)
1040 {
1041         struct dt_device *dt = container_of(kobj, struct dt_device,
1042                                             dd_kobj);
1043         struct lod_device *lod = dt2lod_dev(dt);
1044         bool val = 0;
1045         int rc;
1046
1047         rc = kstrtobool(buffer, &val);
1048         if (rc)
1049                 return rc;
1050
1051         lod->lod_lmv_failout = val;
1052
1053         return count;
1054 }
1055 LUSTRE_RW_ATTR(lmv_failout);
1056
1057 static ssize_t mdt_hash_show(struct kobject *kobj, struct attribute *attr,
1058                              char *buf)
1059 {
1060         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
1061         struct lod_device *lod = dt2lod_dev(dt);
1062
1063         return scnprintf(buf, PAGE_SIZE, "%s\n",
1064                 mdt_hash_name[lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern]);
1065 }
1066
1067 static ssize_t mdt_hash_store(struct kobject *kobj, struct attribute *attr,
1068                               const char *buffer, size_t count)
1069 {
1070         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
1071         struct lod_device *lod = dt2lod_dev(dt);
1072         char *hash;
1073         int len;
1074         int rc = -EINVAL;
1075         int i;
1076
1077         hash = kstrndup(buffer, count, GFP_KERNEL);
1078         if (!hash)
1079                 return -ENOMEM;
1080
1081         if (kstrtoint(hash, 10, &i) == 0 && lmv_is_known_hash_type(i)) {
1082                 lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern = i;
1083                 GOTO(out, rc = count);
1084         }
1085
1086         len = strcspn(hash, "\n ");
1087         hash[len] = '\0';
1088         for (i = LMV_HASH_TYPE_ALL_CHARS; i < ARRAY_SIZE(mdt_hash_name); i++) {
1089                 if (strcmp(hash, mdt_hash_name[i]) == 0) {
1090                         lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern = i;
1091                         GOTO(out, rc = count);
1092                 }
1093         }
1094 out:
1095         kfree(hash);
1096
1097         return rc;
1098 }
1099 LUSTRE_RW_ATTR(mdt_hash);
1100
1101 static ssize_t dist_txn_check_space_show(struct kobject *kobj,
1102                                          struct attribute *attr,
1103                                          char *buf)
1104 {
1105         struct dt_device *dt = container_of(kobj, struct dt_device,
1106                                             dd_kobj);
1107         struct lod_device *lod = dt2lod_dev(dt);
1108
1109         return scnprintf(buf, PAGE_SIZE, "%d\n", lod->lod_dist_txn_check_space);
1110 }
1111
1112 static ssize_t dist_txn_check_space_store(struct kobject *kobj,
1113                                           struct attribute *attr,
1114                                           const char *buffer, size_t count)
1115 {
1116         struct dt_device *dt = container_of(kobj, struct dt_device,
1117                                             dd_kobj);
1118         struct lod_device *lod = dt2lod_dev(dt);
1119         bool val = 0;
1120         int rc;
1121
1122         rc = kstrtobool(buffer, &val);
1123         if (rc)
1124                 return rc;
1125
1126         lod->lod_dist_txn_check_space = val;
1127
1128         return count;
1129 }
1130 LUSTRE_RW_ATTR(dist_txn_check_space);
1131
1132 static const struct proc_ops lod_proc_mdt_fops = {
1133         PROC_OWNER(THIS_MODULE)
1134         .proc_open      = lod_mdts_seq_open,
1135         .proc_read      = seq_read,
1136         .proc_lseek     = seq_lseek,
1137         .proc_release   = lprocfs_seq_release,
1138 };
1139
1140 static int lod_spill_threshold_pct_seq_show(struct seq_file *m, void *v)
1141 {
1142         struct pool_desc *pool = m->private;
1143
1144         LASSERT(pool != NULL);
1145         seq_printf(m, "%d\n", pool->pool_spill_threshold_pct);
1146
1147         return 0;
1148 }
1149
1150 static ssize_t
1151 lod_spill_threshold_pct_seq_write(struct file *file, const char __user *buffer,
1152                                   size_t count, loff_t *off)
1153 {
1154         struct seq_file *m = file->private_data;
1155         struct pool_desc *pool = m->private;
1156         int rc;
1157         int val;
1158
1159         LASSERT(pool != NULL);
1160
1161         rc = kstrtoint_from_user(buffer, count, 0, &val);
1162         if (rc)
1163                 return rc;
1164
1165         if (val > 100 || val < 0)
1166                 return -EINVAL;
1167
1168         pool->pool_spill_threshold_pct = val;
1169         pool->pool_spill_expire = 0;
1170         if (pool->pool_spill_threshold_pct == 0) {
1171                 pool->pool_spill_is_active = false;
1172                 pool->pool_spill_target[0] = '\0';
1173         }
1174
1175         return count;
1176 }
1177 LPROC_SEQ_FOPS(lod_spill_threshold_pct);
1178
1179 static int lod_spill_target_seq_show(struct seq_file *m, void *v)
1180 {
1181         struct pool_desc *pool = m->private;
1182
1183         LASSERT(pool != NULL);
1184         seq_printf(m, "%s\n", pool->pool_spill_target);
1185
1186         return 0;
1187 }
1188
1189 static DEFINE_MUTEX(lod_spill_loop_mutex);
1190
1191 static int lod_spill_check_loop(struct lod_device *lod,
1192                                 const char *pool,
1193                                 const char *destarg)
1194 {
1195         char dest[LOV_MAXPOOLNAME + 1];
1196         struct pool_desc *tgt;
1197         int rc = 0;
1198
1199         strncpy(dest, destarg, sizeof(dest));
1200
1201         /*
1202          * pool1 -> pool2 -> pool3 ++> pool1
1203          * pool1 -> pool2 ++>pool3 -> pool1
1204          */
1205         while (1) {
1206                 tgt = lod_pool_find(lod, dest);
1207                 if (!tgt) {
1208                         /* no more steps, we're fine */
1209                         break;
1210                 }
1211
1212                 strncpy(dest, tgt->pool_spill_target, sizeof(dest));
1213                 lod_pool_putref(tgt);
1214
1215                 if (strcmp(dest, pool) == 0) {
1216                         rc = -ELOOP;
1217                         break;
1218                 }
1219         }
1220         return rc;
1221 }
1222
1223 static ssize_t
1224 lod_spill_target_seq_write(struct file *file, const char __user *buffer,
1225                            size_t count, loff_t *off)
1226 {
1227         struct seq_file *m = file->private_data;
1228         struct pool_desc *pool = m->private;
1229         struct lod_device *lod;
1230         char tgt_name[LOV_MAXPOOLNAME + 1];
1231         int rc;
1232
1233
1234         LASSERT(pool != NULL);
1235         lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
1236
1237         if (count == 0) {
1238                 pool->pool_spill_target[0] = '\0';
1239                 pool->pool_spill_is_active = false;
1240                 return count;
1241         }
1242
1243         if (count > sizeof(tgt_name) - 1)
1244                 return -E2BIG;
1245         if (copy_from_user(tgt_name, buffer, count))
1246                 return -EFAULT;
1247         tgt_name[count] = '\0';
1248
1249         if (strcmp(pool->pool_name, tgt_name) == 0)
1250                 return -ELOOP;
1251         if (!lod_pool_exists(lod, tgt_name)) {
1252                 pool->pool_spill_target[0] = '\0';
1253                 pool->pool_spill_expire = 0;
1254                 return -ENODEV;
1255         }
1256
1257         /* serialize all checks to protect against racing settings */
1258         mutex_lock(&lod_spill_loop_mutex);
1259
1260         rc = lod_spill_check_loop(lod, pool->pool_name, tgt_name);
1261         if (rc == 0) {
1262                 strncpy(pool->pool_spill_target, tgt_name,
1263                         sizeof(pool->pool_spill_target));
1264                 rc = count;
1265         }
1266
1267         mutex_unlock(&lod_spill_loop_mutex);
1268
1269         return rc;
1270 }
1271 LPROC_SEQ_FOPS(lod_spill_target);
1272
1273 static int lod_spill_is_active_seq_show(struct seq_file *m, void *v)
1274 {
1275         struct pool_desc *pool = m->private;
1276         struct lod_device *lod;
1277         struct lu_env env;
1278         int rc;
1279
1280         if (!pool)
1281                 return -ENODEV;
1282
1283         rc = lu_env_init(&env, LCT_LOCAL);
1284         if (rc)
1285                 return rc;
1286
1287         lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
1288         lod_spill_target_refresh(&env, lod, pool);
1289         lu_env_fini(&env);
1290
1291         seq_printf(m, "%d\n", pool->pool_spill_is_active ? 1 : 0);
1292
1293         return 0;
1294 }
1295 LPROC_SEQ_FOPS_RO(lod_spill_is_active);
1296
1297 static int lod_spill_hit_seq_show(struct seq_file *m, void *v)
1298 {
1299         struct pool_desc  *pool = m->private;
1300
1301         LASSERT(pool != NULL);
1302         seq_printf(m, "%d\n", atomic_read(&pool->pool_spill_hit));
1303         return 0;
1304 }
1305 LPROC_SEQ_FOPS_RO(lod_spill_hit);
1306
1307 struct lprocfs_vars lprocfs_lod_spill_vars[] = {
1308         { .name =       "spill_threshold_pct",
1309           .fops =       &lod_spill_threshold_pct_fops },
1310         { .name =       "spill_target",
1311           .fops =       &lod_spill_target_fops },
1312         { .name =       "spill_is_active",
1313           .fops =       &lod_spill_is_active_fops },
1314         { .name =       "spill_hit",
1315           .fops =       &lod_spill_hit_fops },
1316         { NULL }
1317 };
1318
1319 static struct proc_ops lod_proc_target_fops = {
1320         PROC_OWNER(THIS_MODULE)
1321         .proc_open      = lod_osts_seq_open,
1322         .proc_read      = seq_read,
1323         .proc_lseek     = seq_lseek,
1324         .proc_release   = lprocfs_seq_release,
1325 };
1326
1327 static struct attribute *lod_attrs[] = {
1328         &lustre_attr_dom_stripesize.attr,
1329         &lustre_attr_dom_stripesize_max_kb.attr,
1330         &lustre_attr_dom_stripesize_cur_kb.attr,
1331         &lustre_attr_dom_threshold_free_mb.attr,
1332         &lustre_attr_stripesize.attr,
1333         &lustre_attr_stripeoffset.attr,
1334         &lustre_attr_stripecount.attr,
1335         &lustre_attr_max_stripecount.attr,
1336         &lustre_attr_max_mdt_stripecount.attr,
1337         &lustre_attr_stripetype.attr,
1338         &lustre_attr_activeobd.attr,
1339         &lustre_attr_desc_uuid.attr,
1340         &lustre_attr_lmv_failout.attr,
1341         &lustre_attr_numobd.attr,
1342         &lustre_attr_qos_maxage.attr,
1343         &lustre_attr_qos_prio_free.attr,
1344         &lustre_attr_qos_threshold_rr.attr,
1345         &lustre_attr_mdt_stripecount.attr,
1346         &lustre_attr_mdt_stripetype.attr,
1347         &lustre_attr_mdt_activeobd.attr,
1348         &lustre_attr_mdt_numobd.attr,
1349         &lustre_attr_mdt_qos_maxage.attr,
1350         &lustre_attr_mdt_qos_prio_free.attr,
1351         &lustre_attr_mdt_qos_threshold_rr.attr,
1352         &lustre_attr_mdt_hash.attr,
1353         &lustre_attr_dist_txn_check_space.attr,
1354         NULL,
1355 };
1356
1357 /**
1358  * Initialize procfs entries for LOD.
1359  *
1360  * \param[in] lod       LOD device
1361  *
1362  * \retval 0            on success
1363  * \retval negative     error code if failed
1364  */
1365 int lod_procfs_init(struct lod_device *lod)
1366 {
1367         struct obd_device *obd = lod2obd(lod);
1368         struct obd_type *type;
1369         struct kobject *lov;
1370         int rc;
1371
1372         lod->lod_dt_dev.dd_ktype.default_attrs = lod_attrs;
1373         rc = dt_tunables_init(&lod->lod_dt_dev, obd->obd_type, obd->obd_name,
1374                               NULL);
1375         if (rc) {
1376                 CERROR("%s: failed to setup DT tunables: %d\n",
1377                        obd->obd_name, rc);
1378                 RETURN(rc);
1379         }
1380
1381         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1382                                                obd->obd_type->typ_procroot,
1383                                                NULL, obd);
1384         if (IS_ERR(obd->obd_proc_entry)) {
1385                 rc = PTR_ERR(obd->obd_proc_entry);
1386                 CERROR("%s: error %d setting up lprocfs\n",
1387                        obd->obd_name, rc);
1388                 GOTO(out, rc);
1389         }
1390
1391         rc = lprocfs_seq_create(obd->obd_proc_entry, "mdt_obd",
1392                                 0444, &lod_proc_mdt_fops, obd);
1393         if (rc) {
1394                 CWARN("%s: Error adding the target_obd file %d\n",
1395                       obd->obd_name, rc);
1396                 GOTO(out, rc);
1397         }
1398
1399         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
1400                                 0444, &lod_proc_target_fops, obd);
1401         if (rc) {
1402                 CWARN("%s: Error adding the target_obd file %d\n",
1403                       obd->obd_name, rc);
1404                 GOTO(out, rc);
1405         }
1406
1407         lod->lod_pool_proc_entry = lprocfs_register("pools",
1408                                                     obd->obd_proc_entry,
1409                                                     NULL, NULL);
1410         if (IS_ERR(lod->lod_pool_proc_entry)) {
1411                 rc = PTR_ERR(lod->lod_pool_proc_entry);
1412                 lod->lod_pool_proc_entry = NULL;
1413                 CWARN("%s: Failed to create pools proc file: %d\n",
1414                       obd->obd_name, rc);
1415                 GOTO(out, rc);
1416         }
1417
1418         lod->lod_spill_proc_entry = lprocfs_register("pool",
1419                                                     obd->obd_proc_entry,
1420                                                     NULL, NULL);
1421         if (IS_ERR(lod->lod_spill_proc_entry)) {
1422                 rc = PTR_ERR(lod->lod_spill_proc_entry);
1423                 lod->lod_spill_proc_entry = NULL;
1424                 CWARN("%s: Failed to create pool proc file: %d\n",
1425                       obd->obd_name, rc);
1426                 GOTO(out, rc);
1427         }
1428
1429         lov = kset_find_obj(lustre_kset, "lov");
1430         if (!lov) {
1431                 CERROR("%s: lov subsystem not found\n", obd->obd_name);
1432                 GOTO(out, rc = -ENODEV);
1433         }
1434
1435         rc = sysfs_create_link(lov, &lod->lod_dt_dev.dd_kobj,
1436                                obd->obd_name);
1437         if (rc)
1438                 CERROR("%s: failed to create LOV sysfs symlink\n",
1439                        obd->obd_name);
1440         kobject_put(lov);
1441
1442         obd->obd_debugfs_entry = debugfs_create_dir(obd->obd_name,
1443                                                     obd->obd_type->typ_debugfs_entry);
1444
1445         lod->lod_debugfs = ldebugfs_add_symlink(obd->obd_name, "lov",
1446                                                 "../lod/%s", obd->obd_name);
1447         if (!lod->lod_debugfs)
1448                 CERROR("%s: failed to create LOV debugfs symlink\n",
1449                        obd->obd_name);
1450
1451         type = container_of(lov, struct obd_type, typ_kobj);
1452         if (!type->typ_procroot)
1453                 RETURN(0);
1454
1455         /* for compatibility we link old procfs's LOV entries to lod ones */
1456         lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
1457                                                type->typ_procroot,
1458                                                "../lod/%s", obd->obd_name);
1459         if (lod->lod_symlink == NULL)
1460                 CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n",
1461                        obd->obd_name);
1462         RETURN(0);
1463
1464 out:
1465         dt_tunables_fini(&lod->lod_dt_dev);
1466
1467         return rc;
1468 }
1469
1470 /**
1471  * Cleanup procfs entries registred for LOD.
1472  *
1473  * \param[in] lod       LOD device
1474  */
1475 void lod_procfs_fini(struct lod_device *lod)
1476 {
1477         struct obd_device *obd = lod2obd(lod);
1478         struct kobject *lov;
1479
1480         if (lod->lod_symlink != NULL) {
1481                 lprocfs_remove(&lod->lod_symlink);
1482                 lod->lod_symlink = NULL;
1483         }
1484
1485         lov = kset_find_obj(lustre_kset, "lov");
1486         if (lov) {
1487                 sysfs_remove_link(lov, obd->obd_name);
1488                 kobject_put(lov);
1489         }
1490
1491         debugfs_remove_recursive(lod->lod_debugfs);
1492
1493         if (obd->obd_proc_entry) {
1494                 lprocfs_remove(&obd->obd_proc_entry);
1495                 obd->obd_proc_entry = NULL;
1496         }
1497
1498         dt_tunables_fini(&lod->lod_dt_dev);
1499 }
1500
1501 #endif /* CONFIG_PROC_FS */