Whamcloud - gitweb
018c551eeabe2a385a042890f2186d11caca7951
[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 i;
1075
1076         hash = kstrndup(buffer, count, GFP_KERNEL);
1077         if (!hash)
1078                 return -ENOMEM;
1079
1080         len = strcspn(hash, "\n ");
1081         hash[len] = '\0';
1082         for (i = LMV_HASH_TYPE_ALL_CHARS; i < LMV_HASH_TYPE_MAX; i++) {
1083                 if (!strcmp(hash, mdt_hash_name[i])) {
1084                         lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern = i;
1085                         kfree(hash);
1086                         return count;
1087                 }
1088         }
1089         kfree(hash);
1090
1091         return -EINVAL;
1092 }
1093 LUSTRE_RW_ATTR(mdt_hash);
1094
1095 static const struct proc_ops lod_proc_mdt_fops = {
1096         PROC_OWNER(THIS_MODULE)
1097         .proc_open      = lod_mdts_seq_open,
1098         .proc_read      = seq_read,
1099         .proc_lseek     = seq_lseek,
1100         .proc_release   = lprocfs_seq_release,
1101 };
1102
1103 static int lod_spill_threshold_pct_seq_show(struct seq_file *m, void *v)
1104 {
1105         struct pool_desc *pool = m->private;
1106
1107         LASSERT(pool != NULL);
1108         seq_printf(m, "%d\n", pool->pool_spill_threshold_pct);
1109
1110         return 0;
1111 }
1112
1113 static ssize_t
1114 lod_spill_threshold_pct_seq_write(struct file *file, const char __user *buffer,
1115                                   size_t count, loff_t *off)
1116 {
1117         struct seq_file *m = file->private_data;
1118         struct pool_desc *pool = m->private;
1119         int rc;
1120         int val;
1121
1122         LASSERT(pool != NULL);
1123
1124         rc = kstrtoint_from_user(buffer, count, 0, &val);
1125         if (rc)
1126                 return rc;
1127
1128         if (val > 100 || val < 0)
1129                 return -EINVAL;
1130
1131         pool->pool_spill_threshold_pct = val;
1132         pool->pool_spill_expire = 0;
1133         if (pool->pool_spill_threshold_pct == 0)
1134                 pool->pool_spill_is_active = false;
1135
1136         return count;
1137 }
1138 LPROC_SEQ_FOPS(lod_spill_threshold_pct);
1139
1140 static int lod_spill_target_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, "%s\n", pool->pool_spill_target);
1146
1147         return 0;
1148 }
1149
1150 static ssize_t
1151 lod_spill_target_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         struct lod_device *lod;
1157
1158         LASSERT(pool != NULL);
1159         lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
1160
1161         if (count == 0) {
1162                 pool->pool_spill_target[0] = '\0';
1163                 pool->pool_spill_is_active = false;
1164                 return count;
1165         }
1166
1167         if (count > LOV_MAXPOOLNAME - 1)
1168                 return -E2BIG;
1169         if (copy_from_user(pool->pool_spill_target, buffer, count))
1170                 return -EFAULT;
1171
1172         pool->pool_spill_target[count] = '\0';
1173         if (strcmp(pool->pool_name, pool->pool_spill_target) == 0)
1174                 return -ELOOP;
1175         if (!lod_pool_exists(lod, pool->pool_spill_target)) {
1176                 pool->pool_spill_target[0] = '\0';
1177                 pool->pool_spill_expire = 0;
1178                 return -ENODEV;
1179         }
1180
1181         return count;
1182 }
1183 LPROC_SEQ_FOPS(lod_spill_target);
1184
1185 static int lod_spill_is_active_seq_show(struct seq_file *m, void *v)
1186 {
1187         struct pool_desc *pool = m->private;
1188         struct lod_device *lod;
1189         struct lu_env env;
1190         int rc;
1191
1192         if (!pool)
1193                 return -ENODEV;
1194
1195         rc = lu_env_init(&env, LCT_LOCAL);
1196         if (rc)
1197                 return rc;
1198
1199         lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
1200         lod_spill_target_refresh(&env, lod, pool);
1201         lu_env_fini(&env);
1202
1203         seq_printf(m, "%d\n", pool->pool_spill_is_active ? 1 : 0);
1204
1205         return 0;
1206 }
1207 LPROC_SEQ_FOPS_RO(lod_spill_is_active);
1208
1209 static int lod_spill_hit_seq_show(struct seq_file *m, void *v)
1210 {
1211         struct pool_desc  *pool = m->private;
1212
1213         LASSERT(pool != NULL);
1214         seq_printf(m, "%d\n", atomic_read(&pool->pool_spill_hit));
1215         return 0;
1216 }
1217 LPROC_SEQ_FOPS_RO(lod_spill_hit);
1218
1219 struct lprocfs_vars lprocfs_lod_spill_vars[] = {
1220         { .name =       "spill_threshold_pct",
1221           .fops =       &lod_spill_threshold_pct_fops },
1222         { .name =       "spill_target",
1223           .fops =       &lod_spill_target_fops },
1224         { .name =       "spill_is_active",
1225           .fops =       &lod_spill_is_active_fops },
1226         { .name =       "spill_hit",
1227           .fops =       &lod_spill_hit_fops },
1228         { NULL }
1229 };
1230
1231 static struct proc_ops lod_proc_target_fops = {
1232         PROC_OWNER(THIS_MODULE)
1233         .proc_open      = lod_osts_seq_open,
1234         .proc_read      = seq_read,
1235         .proc_lseek     = seq_lseek,
1236         .proc_release   = lprocfs_seq_release,
1237 };
1238
1239 static struct attribute *lod_attrs[] = {
1240         &lustre_attr_dom_stripesize.attr,
1241         &lustre_attr_dom_stripesize_max_kb.attr,
1242         &lustre_attr_dom_stripesize_cur_kb.attr,
1243         &lustre_attr_dom_threshold_free_mb.attr,
1244         &lustre_attr_stripesize.attr,
1245         &lustre_attr_stripeoffset.attr,
1246         &lustre_attr_stripecount.attr,
1247         &lustre_attr_max_stripecount.attr,
1248         &lustre_attr_max_mdt_stripecount.attr,
1249         &lustre_attr_stripetype.attr,
1250         &lustre_attr_activeobd.attr,
1251         &lustre_attr_desc_uuid.attr,
1252         &lustre_attr_lmv_failout.attr,
1253         &lustre_attr_numobd.attr,
1254         &lustre_attr_qos_maxage.attr,
1255         &lustre_attr_qos_prio_free.attr,
1256         &lustre_attr_qos_threshold_rr.attr,
1257         &lustre_attr_mdt_stripecount.attr,
1258         &lustre_attr_mdt_stripetype.attr,
1259         &lustre_attr_mdt_activeobd.attr,
1260         &lustre_attr_mdt_numobd.attr,
1261         &lustre_attr_mdt_qos_maxage.attr,
1262         &lustre_attr_mdt_qos_prio_free.attr,
1263         &lustre_attr_mdt_qos_threshold_rr.attr,
1264         &lustre_attr_mdt_hash.attr,
1265         NULL,
1266 };
1267
1268 /**
1269  * Initialize procfs entries for LOD.
1270  *
1271  * \param[in] lod       LOD device
1272  *
1273  * \retval 0            on success
1274  * \retval negative     error code if failed
1275  */
1276 int lod_procfs_init(struct lod_device *lod)
1277 {
1278         struct obd_device *obd = lod2obd(lod);
1279         struct obd_type *type;
1280         struct kobject *lov;
1281         int rc;
1282
1283         lod->lod_dt_dev.dd_ktype.default_attrs = lod_attrs;
1284         rc = dt_tunables_init(&lod->lod_dt_dev, obd->obd_type, obd->obd_name,
1285                               NULL);
1286         if (rc) {
1287                 CERROR("%s: failed to setup DT tunables: %d\n",
1288                        obd->obd_name, rc);
1289                 RETURN(rc);
1290         }
1291
1292         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1293                                                obd->obd_type->typ_procroot,
1294                                                NULL, obd);
1295         if (IS_ERR(obd->obd_proc_entry)) {
1296                 rc = PTR_ERR(obd->obd_proc_entry);
1297                 CERROR("%s: error %d setting up lprocfs\n",
1298                        obd->obd_name, rc);
1299                 GOTO(out, rc);
1300         }
1301
1302         rc = lprocfs_seq_create(obd->obd_proc_entry, "mdt_obd",
1303                                 0444, &lod_proc_mdt_fops, obd);
1304         if (rc) {
1305                 CWARN("%s: Error adding the target_obd file %d\n",
1306                       obd->obd_name, rc);
1307                 GOTO(out, rc);
1308         }
1309
1310         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
1311                                 0444, &lod_proc_target_fops, obd);
1312         if (rc) {
1313                 CWARN("%s: Error adding the target_obd file %d\n",
1314                       obd->obd_name, rc);
1315                 GOTO(out, rc);
1316         }
1317
1318         lod->lod_pool_proc_entry = lprocfs_register("pools",
1319                                                     obd->obd_proc_entry,
1320                                                     NULL, NULL);
1321         if (IS_ERR(lod->lod_pool_proc_entry)) {
1322                 rc = PTR_ERR(lod->lod_pool_proc_entry);
1323                 lod->lod_pool_proc_entry = NULL;
1324                 CWARN("%s: Failed to create pools proc file: %d\n",
1325                       obd->obd_name, rc);
1326                 GOTO(out, rc);
1327         }
1328
1329         lod->lod_spill_proc_entry = lprocfs_register("pool",
1330                                                     obd->obd_proc_entry,
1331                                                     NULL, NULL);
1332         if (IS_ERR(lod->lod_spill_proc_entry)) {
1333                 rc = PTR_ERR(lod->lod_spill_proc_entry);
1334                 lod->lod_spill_proc_entry = NULL;
1335                 CWARN("%s: Failed to create pool proc file: %d\n",
1336                       obd->obd_name, rc);
1337                 GOTO(out, rc);
1338         }
1339
1340         lov = kset_find_obj(lustre_kset, "lov");
1341         if (!lov) {
1342                 CERROR("%s: lov subsystem not found\n", obd->obd_name);
1343                 GOTO(out, rc = -ENODEV);
1344         }
1345
1346         rc = sysfs_create_link(lov, &lod->lod_dt_dev.dd_kobj,
1347                                obd->obd_name);
1348         if (rc)
1349                 CERROR("%s: failed to create LOV sysfs symlink\n",
1350                        obd->obd_name);
1351         kobject_put(lov);
1352
1353         obd->obd_debugfs_entry = debugfs_create_dir(obd->obd_name,
1354                                                     obd->obd_type->typ_debugfs_entry);
1355
1356         lod->lod_debugfs = ldebugfs_add_symlink(obd->obd_name, "lov",
1357                                                 "../lod/%s", obd->obd_name);
1358         if (!lod->lod_debugfs)
1359                 CERROR("%s: failed to create LOV debugfs symlink\n",
1360                        obd->obd_name);
1361
1362         type = container_of(lov, struct obd_type, typ_kobj);
1363         if (!type->typ_procroot)
1364                 RETURN(0);
1365
1366         /* for compatibility we link old procfs's LOV entries to lod ones */
1367         lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
1368                                                type->typ_procroot,
1369                                                "../lod/%s", obd->obd_name);
1370         if (lod->lod_symlink == NULL)
1371                 CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n",
1372                        obd->obd_name);
1373         RETURN(0);
1374
1375 out:
1376         dt_tunables_fini(&lod->lod_dt_dev);
1377
1378         return rc;
1379 }
1380
1381 /**
1382  * Cleanup procfs entries registred for LOD.
1383  *
1384  * \param[in] lod       LOD device
1385  */
1386 void lod_procfs_fini(struct lod_device *lod)
1387 {
1388         struct obd_device *obd = lod2obd(lod);
1389         struct kobject *lov;
1390
1391         if (lod->lod_symlink != NULL) {
1392                 lprocfs_remove(&lod->lod_symlink);
1393                 lod->lod_symlink = NULL;
1394         }
1395
1396         lov = kset_find_obj(lustre_kset, "lov");
1397         if (lov) {
1398                 sysfs_remove_link(lov, obd->obd_name);
1399                 kobject_put(lov);
1400         }
1401
1402         debugfs_remove_recursive(lod->lod_debugfs);
1403
1404         if (obd->obd_proc_entry) {
1405                 lprocfs_remove(&obd->obd_proc_entry);
1406                 obd->obd_proc_entry = NULL;
1407         }
1408
1409         dt_tunables_fini(&lod->lod_dt_dev);
1410 }
1411
1412 #endif /* CONFIG_PROC_FS */