Whamcloud - gitweb
LU-15720 dne: add crush2 hash type
[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 const struct proc_ops lod_proc_mdt_fops = {
1102         PROC_OWNER(THIS_MODULE)
1103         .proc_open      = lod_mdts_seq_open,
1104         .proc_read      = seq_read,
1105         .proc_lseek     = seq_lseek,
1106         .proc_release   = lprocfs_seq_release,
1107 };
1108
1109 static int lod_spill_threshold_pct_seq_show(struct seq_file *m, void *v)
1110 {
1111         struct pool_desc *pool = m->private;
1112
1113         LASSERT(pool != NULL);
1114         seq_printf(m, "%d\n", pool->pool_spill_threshold_pct);
1115
1116         return 0;
1117 }
1118
1119 static ssize_t
1120 lod_spill_threshold_pct_seq_write(struct file *file, const char __user *buffer,
1121                                   size_t count, loff_t *off)
1122 {
1123         struct seq_file *m = file->private_data;
1124         struct pool_desc *pool = m->private;
1125         int rc;
1126         int val;
1127
1128         LASSERT(pool != NULL);
1129
1130         rc = kstrtoint_from_user(buffer, count, 0, &val);
1131         if (rc)
1132                 return rc;
1133
1134         if (val > 100 || val < 0)
1135                 return -EINVAL;
1136
1137         pool->pool_spill_threshold_pct = val;
1138         pool->pool_spill_expire = 0;
1139         if (pool->pool_spill_threshold_pct == 0) {
1140                 pool->pool_spill_is_active = false;
1141                 pool->pool_spill_target[0] = '\0';
1142         }
1143
1144         return count;
1145 }
1146 LPROC_SEQ_FOPS(lod_spill_threshold_pct);
1147
1148 static int lod_spill_target_seq_show(struct seq_file *m, void *v)
1149 {
1150         struct pool_desc *pool = m->private;
1151
1152         LASSERT(pool != NULL);
1153         seq_printf(m, "%s\n", pool->pool_spill_target);
1154
1155         return 0;
1156 }
1157
1158 static DEFINE_MUTEX(lod_spill_loop_mutex);
1159
1160 static int lod_spill_check_loop(struct lod_device *lod,
1161                                 const char *pool,
1162                                 const char *destarg)
1163 {
1164         char dest[LOV_MAXPOOLNAME + 1];
1165         struct pool_desc *tgt;
1166         int rc = 0;
1167
1168         strncpy(dest, destarg, sizeof(dest));
1169
1170         /*
1171          * pool1 -> pool2 -> pool3 ++> pool1
1172          * pool1 -> pool2 ++>pool3 -> pool1
1173          */
1174         while (1) {
1175                 tgt = lod_pool_find(lod, dest);
1176                 if (!tgt) {
1177                         /* no more steps, we're fine */
1178                         break;
1179                 }
1180
1181                 strncpy(dest, tgt->pool_spill_target, sizeof(dest));
1182                 lod_pool_putref(tgt);
1183
1184                 if (strcmp(dest, pool) == 0) {
1185                         rc = -ELOOP;
1186                         break;
1187                 }
1188         }
1189         return rc;
1190 }
1191
1192 static ssize_t
1193 lod_spill_target_seq_write(struct file *file, const char __user *buffer,
1194                            size_t count, loff_t *off)
1195 {
1196         struct seq_file *m = file->private_data;
1197         struct pool_desc *pool = m->private;
1198         struct lod_device *lod;
1199         char tgt_name[LOV_MAXPOOLNAME + 1];
1200         int rc;
1201
1202
1203         LASSERT(pool != NULL);
1204         lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
1205
1206         if (count == 0) {
1207                 pool->pool_spill_target[0] = '\0';
1208                 pool->pool_spill_is_active = false;
1209                 return count;
1210         }
1211
1212         if (count > sizeof(tgt_name) - 1)
1213                 return -E2BIG;
1214         if (copy_from_user(tgt_name, buffer, count))
1215                 return -EFAULT;
1216         tgt_name[count] = '\0';
1217
1218         if (strcmp(pool->pool_name, tgt_name) == 0)
1219                 return -ELOOP;
1220         if (!lod_pool_exists(lod, tgt_name)) {
1221                 pool->pool_spill_target[0] = '\0';
1222                 pool->pool_spill_expire = 0;
1223                 return -ENODEV;
1224         }
1225
1226         /* serialize all checks to protect against racing settings */
1227         mutex_lock(&lod_spill_loop_mutex);
1228
1229         rc = lod_spill_check_loop(lod, pool->pool_name, tgt_name);
1230         if (rc == 0) {
1231                 strncpy(pool->pool_spill_target, tgt_name,
1232                         sizeof(pool->pool_spill_target));
1233                 rc = count;
1234         }
1235
1236         mutex_unlock(&lod_spill_loop_mutex);
1237
1238         return rc;
1239 }
1240 LPROC_SEQ_FOPS(lod_spill_target);
1241
1242 static int lod_spill_is_active_seq_show(struct seq_file *m, void *v)
1243 {
1244         struct pool_desc *pool = m->private;
1245         struct lod_device *lod;
1246         struct lu_env env;
1247         int rc;
1248
1249         if (!pool)
1250                 return -ENODEV;
1251
1252         rc = lu_env_init(&env, LCT_LOCAL);
1253         if (rc)
1254                 return rc;
1255
1256         lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
1257         lod_spill_target_refresh(&env, lod, pool);
1258         lu_env_fini(&env);
1259
1260         seq_printf(m, "%d\n", pool->pool_spill_is_active ? 1 : 0);
1261
1262         return 0;
1263 }
1264 LPROC_SEQ_FOPS_RO(lod_spill_is_active);
1265
1266 static int lod_spill_hit_seq_show(struct seq_file *m, void *v)
1267 {
1268         struct pool_desc  *pool = m->private;
1269
1270         LASSERT(pool != NULL);
1271         seq_printf(m, "%d\n", atomic_read(&pool->pool_spill_hit));
1272         return 0;
1273 }
1274 LPROC_SEQ_FOPS_RO(lod_spill_hit);
1275
1276 struct lprocfs_vars lprocfs_lod_spill_vars[] = {
1277         { .name =       "spill_threshold_pct",
1278           .fops =       &lod_spill_threshold_pct_fops },
1279         { .name =       "spill_target",
1280           .fops =       &lod_spill_target_fops },
1281         { .name =       "spill_is_active",
1282           .fops =       &lod_spill_is_active_fops },
1283         { .name =       "spill_hit",
1284           .fops =       &lod_spill_hit_fops },
1285         { NULL }
1286 };
1287
1288 static struct proc_ops lod_proc_target_fops = {
1289         PROC_OWNER(THIS_MODULE)
1290         .proc_open      = lod_osts_seq_open,
1291         .proc_read      = seq_read,
1292         .proc_lseek     = seq_lseek,
1293         .proc_release   = lprocfs_seq_release,
1294 };
1295
1296 static struct attribute *lod_attrs[] = {
1297         &lustre_attr_dom_stripesize.attr,
1298         &lustre_attr_dom_stripesize_max_kb.attr,
1299         &lustre_attr_dom_stripesize_cur_kb.attr,
1300         &lustre_attr_dom_threshold_free_mb.attr,
1301         &lustre_attr_stripesize.attr,
1302         &lustre_attr_stripeoffset.attr,
1303         &lustre_attr_stripecount.attr,
1304         &lustre_attr_max_stripecount.attr,
1305         &lustre_attr_max_mdt_stripecount.attr,
1306         &lustre_attr_stripetype.attr,
1307         &lustre_attr_activeobd.attr,
1308         &lustre_attr_desc_uuid.attr,
1309         &lustre_attr_lmv_failout.attr,
1310         &lustre_attr_numobd.attr,
1311         &lustre_attr_qos_maxage.attr,
1312         &lustre_attr_qos_prio_free.attr,
1313         &lustre_attr_qos_threshold_rr.attr,
1314         &lustre_attr_mdt_stripecount.attr,
1315         &lustre_attr_mdt_stripetype.attr,
1316         &lustre_attr_mdt_activeobd.attr,
1317         &lustre_attr_mdt_numobd.attr,
1318         &lustre_attr_mdt_qos_maxage.attr,
1319         &lustre_attr_mdt_qos_prio_free.attr,
1320         &lustre_attr_mdt_qos_threshold_rr.attr,
1321         &lustre_attr_mdt_hash.attr,
1322         NULL,
1323 };
1324
1325 /**
1326  * Initialize procfs entries for LOD.
1327  *
1328  * \param[in] lod       LOD device
1329  *
1330  * \retval 0            on success
1331  * \retval negative     error code if failed
1332  */
1333 int lod_procfs_init(struct lod_device *lod)
1334 {
1335         struct obd_device *obd = lod2obd(lod);
1336         struct obd_type *type;
1337         struct kobject *lov;
1338         int rc;
1339
1340         lod->lod_dt_dev.dd_ktype.default_attrs = lod_attrs;
1341         rc = dt_tunables_init(&lod->lod_dt_dev, obd->obd_type, obd->obd_name,
1342                               NULL);
1343         if (rc) {
1344                 CERROR("%s: failed to setup DT tunables: %d\n",
1345                        obd->obd_name, rc);
1346                 RETURN(rc);
1347         }
1348
1349         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1350                                                obd->obd_type->typ_procroot,
1351                                                NULL, obd);
1352         if (IS_ERR(obd->obd_proc_entry)) {
1353                 rc = PTR_ERR(obd->obd_proc_entry);
1354                 CERROR("%s: error %d setting up lprocfs\n",
1355                        obd->obd_name, rc);
1356                 GOTO(out, rc);
1357         }
1358
1359         rc = lprocfs_seq_create(obd->obd_proc_entry, "mdt_obd",
1360                                 0444, &lod_proc_mdt_fops, obd);
1361         if (rc) {
1362                 CWARN("%s: Error adding the target_obd file %d\n",
1363                       obd->obd_name, rc);
1364                 GOTO(out, rc);
1365         }
1366
1367         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
1368                                 0444, &lod_proc_target_fops, obd);
1369         if (rc) {
1370                 CWARN("%s: Error adding the target_obd file %d\n",
1371                       obd->obd_name, rc);
1372                 GOTO(out, rc);
1373         }
1374
1375         lod->lod_pool_proc_entry = lprocfs_register("pools",
1376                                                     obd->obd_proc_entry,
1377                                                     NULL, NULL);
1378         if (IS_ERR(lod->lod_pool_proc_entry)) {
1379                 rc = PTR_ERR(lod->lod_pool_proc_entry);
1380                 lod->lod_pool_proc_entry = NULL;
1381                 CWARN("%s: Failed to create pools proc file: %d\n",
1382                       obd->obd_name, rc);
1383                 GOTO(out, rc);
1384         }
1385
1386         lod->lod_spill_proc_entry = lprocfs_register("pool",
1387                                                     obd->obd_proc_entry,
1388                                                     NULL, NULL);
1389         if (IS_ERR(lod->lod_spill_proc_entry)) {
1390                 rc = PTR_ERR(lod->lod_spill_proc_entry);
1391                 lod->lod_spill_proc_entry = NULL;
1392                 CWARN("%s: Failed to create pool proc file: %d\n",
1393                       obd->obd_name, rc);
1394                 GOTO(out, rc);
1395         }
1396
1397         lov = kset_find_obj(lustre_kset, "lov");
1398         if (!lov) {
1399                 CERROR("%s: lov subsystem not found\n", obd->obd_name);
1400                 GOTO(out, rc = -ENODEV);
1401         }
1402
1403         rc = sysfs_create_link(lov, &lod->lod_dt_dev.dd_kobj,
1404                                obd->obd_name);
1405         if (rc)
1406                 CERROR("%s: failed to create LOV sysfs symlink\n",
1407                        obd->obd_name);
1408         kobject_put(lov);
1409
1410         obd->obd_debugfs_entry = debugfs_create_dir(obd->obd_name,
1411                                                     obd->obd_type->typ_debugfs_entry);
1412
1413         lod->lod_debugfs = ldebugfs_add_symlink(obd->obd_name, "lov",
1414                                                 "../lod/%s", obd->obd_name);
1415         if (!lod->lod_debugfs)
1416                 CERROR("%s: failed to create LOV debugfs symlink\n",
1417                        obd->obd_name);
1418
1419         type = container_of(lov, struct obd_type, typ_kobj);
1420         if (!type->typ_procroot)
1421                 RETURN(0);
1422
1423         /* for compatibility we link old procfs's LOV entries to lod ones */
1424         lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
1425                                                type->typ_procroot,
1426                                                "../lod/%s", obd->obd_name);
1427         if (lod->lod_symlink == NULL)
1428                 CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n",
1429                        obd->obd_name);
1430         RETURN(0);
1431
1432 out:
1433         dt_tunables_fini(&lod->lod_dt_dev);
1434
1435         return rc;
1436 }
1437
1438 /**
1439  * Cleanup procfs entries registred for LOD.
1440  *
1441  * \param[in] lod       LOD device
1442  */
1443 void lod_procfs_fini(struct lod_device *lod)
1444 {
1445         struct obd_device *obd = lod2obd(lod);
1446         struct kobject *lov;
1447
1448         if (lod->lod_symlink != NULL) {
1449                 lprocfs_remove(&lod->lod_symlink);
1450                 lod->lod_symlink = NULL;
1451         }
1452
1453         lov = kset_find_obj(lustre_kset, "lov");
1454         if (lov) {
1455                 sysfs_remove_link(lov, obd->obd_name);
1456                 kobject_put(lov);
1457         }
1458
1459         debugfs_remove_recursive(lod->lod_debugfs);
1460
1461         if (obd->obd_proc_entry) {
1462                 lprocfs_remove(&obd->obd_proc_entry);
1463                 obd->obd_proc_entry = NULL;
1464         }
1465
1466         dt_tunables_fini(&lod->lod_dt_dev);
1467 }
1468
1469 #endif /* CONFIG_PROC_FS */