Whamcloud - gitweb
LU-15220 lustre: use 'fallthrough' pseudo keyword for switch
[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 + 255) >> 8);
682 }
683
684 static ssize_t mdt_qos_threshold_rr_show(struct kobject *kobj,
685                                          struct attribute *attr, char *buf)
686 {
687         return __qos_threshold_rr_show(kobj, attr, buf, true);
688 }
689
690 static ssize_t qos_threshold_rr_show(struct kobject *kobj,
691                                      struct attribute *attr, char *buf)
692 {
693         return __qos_threshold_rr_show(kobj, attr, buf, false);
694 }
695
696 /**
697  * Set threshold for "same space on all OSTs" rule.
698  *
699  * This sets the maximum percentage difference of free space between the most
700  * full and most empty OST in the currently available OSTs. If this percentage
701  * is exceeded, use the QoS allocator to select OSTs based on their available
702  * space so that more full OSTs are chosen less often, otherwise use the
703  * round-robin allocator for efficiency and performance.
704  */
705 static ssize_t __qos_threshold_rr_store(struct kobject *kobj,
706                                         struct attribute *attr,
707                                         const char *buffer, size_t count,
708                                         bool is_mdt)
709 {
710         struct dt_device *dt = container_of(kobj, struct dt_device,
711                                             dd_kobj);
712         struct lod_device *lod = dt2lod_dev(dt);
713         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
714                                             &lod->lod_ost_descs;
715         char buf[6], *tmp;
716         unsigned int val;
717         int rc;
718
719         /* "100%\n\0" should be largest string */
720         if (count >= sizeof(buf))
721                 return -ERANGE;
722
723         strncpy(buf, buffer, sizeof(buf));
724         buf[sizeof(buf) - 1] = '\0';
725         tmp = strchr(buf, '%');
726         if (tmp)
727                 *tmp = '\0';
728
729         rc = kstrtouint(buf, 0, &val);
730         if (rc)
731                 return rc;
732
733         if (val > 100)
734                 return -EINVAL;
735         ltd->ltd_qos.lq_threshold_rr = (val << 8) / 100;
736         set_bit(LQ_DIRTY, &ltd->ltd_qos.lq_flags);
737
738         return count;
739 }
740
741 static ssize_t mdt_qos_threshold_rr_store(struct kobject *kobj,
742                                           struct attribute *attr,
743                                           const char *buffer, size_t count)
744 {
745         return __qos_threshold_rr_store(kobj, attr, buffer, count, true);
746 }
747
748 static ssize_t qos_threshold_rr_store(struct kobject *kobj,
749                                       struct attribute *attr,
750                                       const char *buffer, size_t count)
751 {
752         return __qos_threshold_rr_store(kobj, attr, buffer, count, false);
753 }
754
755 LUSTRE_RW_ATTR(mdt_qos_threshold_rr);
756 LUSTRE_RW_ATTR(qos_threshold_rr);
757
758 /**
759  * Show expiration period used to refresh cached statfs data, which
760  * is used to implement QoS/RR striping allocation algorithm.
761  */
762 static ssize_t __qos_maxage_show(struct kobject *kobj, struct attribute *attr,
763                                  char *buf, bool is_mdt)
764 {
765         struct dt_device *dt = container_of(kobj, struct dt_device,
766                                             dd_kobj);
767         struct lod_device *lod = dt2lod_dev(dt);
768         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
769                                             &lod->lod_ost_descs;
770
771         return scnprintf(buf, PAGE_SIZE, "%u\n",
772                          ltd->ltd_lov_desc.ld_qos_maxage);
773 }
774
775 static ssize_t mdt_qos_maxage_show(struct kobject *kobj, struct attribute *attr,
776                                    char *buf)
777 {
778         return __qos_maxage_show(kobj, attr, buf, true);
779 }
780
781 static ssize_t qos_maxage_show(struct kobject *kobj, struct attribute *attr,
782                                char *buf)
783 {
784         return __qos_maxage_show(kobj, attr, buf, true);
785 }
786
787 /**
788  * Set expiration period used to refresh cached statfs data.
789  */
790 static ssize_t __qos_maxage_store(struct kobject *kobj, struct attribute *attr,
791                                   const char *buffer, size_t count, bool is_mdt)
792 {
793         struct dt_device *dt = container_of(kobj, struct dt_device,
794                                             dd_kobj);
795         struct lod_device *lod = dt2lod_dev(dt);
796         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
797                                             &lod->lod_ost_descs;
798         struct lustre_cfg_bufs bufs;
799         struct lu_device *next;
800         struct lustre_cfg *lcfg;
801         char str[32];
802         struct lu_tgt_desc *tgt;
803         int rc;
804         u32 val;
805
806         rc = kstrtouint(buffer, 0, &val);
807         if (rc)
808                 return rc;
809
810         if (val <= 0)
811                 return -EINVAL;
812
813         ltd->ltd_lov_desc.ld_qos_maxage = val;
814
815         /*
816          * propogate the value down to OSPs
817          */
818         lustre_cfg_bufs_reset(&bufs, NULL);
819         snprintf(str, 32, "%smaxage=%u", PARAM_OSP, val);
820         lustre_cfg_bufs_set_string(&bufs, 1, str);
821         OBD_ALLOC(lcfg, lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen));
822         if (lcfg == NULL)
823                 return -ENOMEM;
824         lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
825
826         lod_getref(ltd);
827         ltd_foreach_tgt(ltd, tgt) {
828                 next = &tgt->ltd_tgt->dd_lu_dev;
829                 rc = next->ld_ops->ldo_process_config(NULL, next, lcfg);
830                 if (rc)
831                         CERROR("can't set maxage on #%d: %d\n",
832                                tgt->ltd_index, rc);
833         }
834         lod_putref(lod, ltd);
835         OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens));
836
837         return count;
838 }
839
840 static ssize_t mdt_qos_maxage_store(struct kobject *kobj,
841                                     struct attribute *attr,
842                                     const char *buffer, size_t count)
843 {
844         return __qos_maxage_store(kobj, attr, buffer, count, true);
845 }
846
847 static ssize_t qos_maxage_store(struct kobject *kobj, struct attribute *attr,
848                                 const char *buffer, size_t count)
849 {
850         return __qos_maxage_store(kobj, attr, buffer, count, false);
851 }
852
853 LUSTRE_RW_ATTR(mdt_qos_maxage);
854 LUSTRE_RW_ATTR(qos_maxage);
855
856 static void *lod_tgts_seq_start(struct seq_file *p, loff_t *pos, bool is_mdt)
857 {
858         struct obd_device *obd = p->private;
859         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
860         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
861                                             &lod->lod_ost_descs;
862
863         LASSERT(obd != NULL);
864
865         lod_getref(ltd); /* released in lod_tgts_seq_stop */
866         if (*pos >= ltd->ltd_tgts_size)
867                 return NULL;
868
869         *pos = find_next_bit(ltd->ltd_tgt_bitmap,
870                              ltd->ltd_tgts_size, *pos);
871         if (*pos < ltd->ltd_tgts_size)
872                 return LTD_TGT(ltd, *pos);
873         else
874                 return NULL;
875 }
876
877 static void *lod_mdts_seq_start(struct seq_file *p, loff_t *pos)
878 {
879         return lod_tgts_seq_start(p, pos, true);
880 }
881
882 static void *lod_osts_seq_start(struct seq_file *p, loff_t *pos)
883 {
884         return lod_tgts_seq_start(p, pos, false);
885 }
886
887 static void lod_tgts_seq_stop(struct seq_file *p, void *v, bool is_mdt)
888 {
889         struct obd_device *obd = p->private;
890         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
891         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
892                                             &lod->lod_ost_descs;
893
894         LASSERT(obd != NULL);
895         lod_putref(lod, ltd);
896 }
897
898 static void lod_mdts_seq_stop(struct seq_file *p, void *v)
899 {
900         lod_tgts_seq_stop(p, v, true);
901 }
902
903 static void lod_osts_seq_stop(struct seq_file *p, void *v)
904 {
905         lod_tgts_seq_stop(p, v, false);
906 }
907
908 static void *lod_tgts_seq_next(struct seq_file *p, void *v, loff_t *pos,
909                                bool is_mdt)
910 {
911         struct obd_device *obd = p->private;
912         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
913         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
914                                             &lod->lod_ost_descs;
915
916         (*pos)++;
917         if (*pos > ltd->ltd_tgts_size - 1)
918                 return NULL;
919
920         *pos = find_next_bit(ltd->ltd_tgt_bitmap,
921                              ltd->ltd_tgts_size, *pos);
922         if (*pos < ltd->ltd_tgts_size)
923                 return LTD_TGT(ltd, *pos);
924         else
925                 return NULL;
926 }
927
928 static void *lod_mdts_seq_next(struct seq_file *p, void *v, loff_t *pos)
929 {
930         return lod_tgts_seq_next(p, v, pos, true);
931 }
932
933 static void *lod_osts_seq_next(struct seq_file *p, void *v, loff_t *pos)
934 {
935         return lod_tgts_seq_next(p, v, pos, false);
936 }
937
938 /**
939  * Show active/inactive status for OST found by lod_osts_seq_next().
940  *
941  * \param[in] m         seq file
942  * \param[in] v         unused for single entry
943  *
944  * \retval 0            on success
945  * \retval negative     error code if failed
946  */
947 static int lod_tgts_seq_show(struct seq_file *p, void *v)
948 {
949         struct obd_device *obd = p->private;
950         struct lu_tgt_desc *tgt = v;
951         struct dt_device *next;
952         int rc, active;
953
954         LASSERT(obd->obd_lu_dev);
955
956         next = tgt->ltd_tgt;
957         if (!next)
958                 return -EINVAL;
959
960         /* XXX: should be non-NULL env, but it's very expensive */
961         active = 1;
962         rc = dt_statfs(NULL, next, &tgt->ltd_statfs);
963         if (rc == -ENOTCONN) {
964                 active = 0;
965                 rc = 0;
966         } else if (rc)
967                 return rc;
968
969         seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
970                    obd_uuid2str(&tgt->ltd_uuid),
971                    active ? "" : "IN");
972         return 0;
973 }
974
975 static const struct seq_operations lod_mdts_sops = {
976         .start  = lod_mdts_seq_start,
977         .stop   = lod_mdts_seq_stop,
978         .next   = lod_mdts_seq_next,
979         .show   = lod_tgts_seq_show,
980 };
981
982 static const struct seq_operations lod_osts_sops = {
983         .start  = lod_osts_seq_start,
984         .stop   = lod_osts_seq_stop,
985         .next   = lod_osts_seq_next,
986         .show   = lod_tgts_seq_show,
987 };
988
989 static int lod_mdts_seq_open(struct inode *inode, struct file *file)
990 {
991         struct seq_file *seq;
992         int rc;
993
994         rc = seq_open(file, &lod_mdts_sops);
995         if (rc)
996                 return rc;
997
998         seq = file->private_data;
999         seq->private = PDE_DATA(inode);
1000         return 0;
1001 }
1002
1003 static int lod_osts_seq_open(struct inode *inode, struct file *file)
1004 {
1005         struct seq_file *seq;
1006         int rc;
1007
1008         rc = seq_open(file, &lod_osts_sops);
1009         if (rc)
1010                 return rc;
1011
1012         seq = file->private_data;
1013         seq->private = PDE_DATA(inode);
1014         return 0;
1015 }
1016
1017 /**
1018  * Show whether special failout mode for testing is enabled or not.
1019  */
1020 static ssize_t lmv_failout_show(struct kobject *kobj, struct attribute *attr,
1021                                 char *buf)
1022 {
1023         struct dt_device *dt = container_of(kobj, struct dt_device,
1024                                             dd_kobj);
1025         struct lod_device *lod = dt2lod_dev(dt);
1026
1027         return scnprintf(buf, PAGE_SIZE, "%d\n", lod->lod_lmv_failout ? 1 : 0);
1028 }
1029
1030 /**
1031  * Enable/disable a special failout mode for testing.
1032  *
1033  * This determines whether the LMV will try to continue processing a striped
1034  * directory even if it has a (partly) corrupted entry in the master directory,
1035  * or if it will abort upon finding a corrupted slave directory entry.
1036  */
1037 static ssize_t lmv_failout_store(struct kobject *kobj, struct attribute *attr,
1038                                  const char *buffer, size_t count)
1039 {
1040         struct dt_device *dt = container_of(kobj, struct dt_device,
1041                                             dd_kobj);
1042         struct lod_device *lod = dt2lod_dev(dt);
1043         bool val = 0;
1044         int rc;
1045
1046         rc = kstrtobool(buffer, &val);
1047         if (rc)
1048                 return rc;
1049
1050         lod->lod_lmv_failout = val;
1051
1052         return count;
1053 }
1054 LUSTRE_RW_ATTR(lmv_failout);
1055
1056 static ssize_t mdt_hash_show(struct kobject *kobj, struct attribute *attr,
1057                              char *buf)
1058 {
1059         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
1060         struct lod_device *lod = dt2lod_dev(dt);
1061
1062         return scnprintf(buf, PAGE_SIZE, "%s\n",
1063                 mdt_hash_name[lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern]);
1064 }
1065
1066 static ssize_t mdt_hash_store(struct kobject *kobj, struct attribute *attr,
1067                               const char *buffer, size_t count)
1068 {
1069         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
1070         struct lod_device *lod = dt2lod_dev(dt);
1071         char *hash;
1072         int len;
1073         int i;
1074
1075         hash = kstrndup(buffer, count, GFP_KERNEL);
1076         if (!hash)
1077                 return -ENOMEM;
1078
1079         len = strcspn(hash, "\n ");
1080         hash[len] = '\0';
1081         for (i = LMV_HASH_TYPE_ALL_CHARS; i < LMV_HASH_TYPE_MAX; i++) {
1082                 if (!strcmp(hash, mdt_hash_name[i])) {
1083                         lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern = i;
1084                         kfree(hash);
1085                         return count;
1086                 }
1087         }
1088         kfree(hash);
1089
1090         return -EINVAL;
1091 }
1092 LUSTRE_RW_ATTR(mdt_hash);
1093
1094 static const struct proc_ops lod_proc_mdt_fops = {
1095         PROC_OWNER(THIS_MODULE)
1096         .proc_open      = lod_mdts_seq_open,
1097         .proc_read      = seq_read,
1098         .proc_lseek     = seq_lseek,
1099         .proc_release   = lprocfs_seq_release,
1100 };
1101
1102 static int lod_spill_threshold_pct_seq_show(struct seq_file *m, void *v)
1103 {
1104         struct pool_desc *pool = m->private;
1105
1106         LASSERT(pool != NULL);
1107         seq_printf(m, "%d\n", pool->pool_spill_threshold_pct);
1108
1109         return 0;
1110 }
1111
1112 static ssize_t
1113 lod_spill_threshold_pct_seq_write(struct file *file, const char __user *buffer,
1114                                   size_t count, loff_t *off)
1115 {
1116         struct seq_file *m = file->private_data;
1117         struct pool_desc *pool = m->private;
1118         int rc;
1119         int val;
1120
1121         LASSERT(pool != NULL);
1122
1123         rc = kstrtoint_from_user(buffer, count, 0, &val);
1124         if (rc)
1125                 return rc;
1126
1127         if (val > 100 || val < 0)
1128                 return -EINVAL;
1129
1130         pool->pool_spill_threshold_pct = val;
1131         pool->pool_spill_expire = 0;
1132         if (pool->pool_spill_threshold_pct == 0)
1133                 pool->pool_spill_is_active = false;
1134
1135         return count;
1136 }
1137 LPROC_SEQ_FOPS(lod_spill_threshold_pct);
1138
1139 static int lod_spill_target_seq_show(struct seq_file *m, void *v)
1140 {
1141         struct pool_desc *pool = m->private;
1142
1143         LASSERT(pool != NULL);
1144         seq_printf(m, "%s\n", pool->pool_spill_target);
1145
1146         return 0;
1147 }
1148
1149 static ssize_t
1150 lod_spill_target_seq_write(struct file *file, const char __user *buffer,
1151                            size_t count, loff_t *off)
1152 {
1153         struct seq_file *m = file->private_data;
1154         struct pool_desc *pool = m->private;
1155         struct lod_device *lod;
1156
1157         LASSERT(pool != NULL);
1158         lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
1159
1160         if (count == 0) {
1161                 pool->pool_spill_target[0] = '\0';
1162                 pool->pool_spill_is_active = false;
1163                 return count;
1164         }
1165
1166         if (count > LOV_MAXPOOLNAME - 1)
1167                 return -E2BIG;
1168         if (copy_from_user(pool->pool_spill_target, buffer, count))
1169                 return -EFAULT;
1170
1171         pool->pool_spill_target[count] = '\0';
1172         if (strcmp(pool->pool_name, pool->pool_spill_target) == 0)
1173                 return -ELOOP;
1174         if (!lod_pool_exists(lod, pool->pool_spill_target)) {
1175                 pool->pool_spill_target[0] = '\0';
1176                 pool->pool_spill_expire = 0;
1177                 return -ENODEV;
1178         }
1179
1180         return count;
1181 }
1182 LPROC_SEQ_FOPS(lod_spill_target);
1183
1184 static int lod_spill_is_active_seq_show(struct seq_file *m, void *v)
1185 {
1186         struct pool_desc *pool = m->private;
1187         struct lod_device *lod;
1188         struct lu_env env;
1189         int rc;
1190
1191         if (!pool)
1192                 return -ENODEV;
1193
1194         rc = lu_env_init(&env, LCT_LOCAL);
1195         if (rc)
1196                 return rc;
1197
1198         lod = lu2lod_dev(pool->pool_lobd->obd_lu_dev);
1199         lod_spill_target_refresh(&env, lod, pool);
1200         lu_env_fini(&env);
1201
1202         seq_printf(m, "%d\n", pool->pool_spill_is_active ? 1 : 0);
1203
1204         return 0;
1205 }
1206 LPROC_SEQ_FOPS_RO(lod_spill_is_active);
1207
1208 static int lod_spill_hit_seq_show(struct seq_file *m, void *v)
1209 {
1210         struct pool_desc  *pool = m->private;
1211
1212         LASSERT(pool != NULL);
1213         seq_printf(m, "%d\n", atomic_read(&pool->pool_spill_hit));
1214         return 0;
1215 }
1216 LPROC_SEQ_FOPS_RO(lod_spill_hit);
1217
1218 struct lprocfs_vars lprocfs_lod_spill_vars[] = {
1219         { .name =       "spill_threshold_pct",
1220           .fops =       &lod_spill_threshold_pct_fops },
1221         { .name =       "spill_target",
1222           .fops =       &lod_spill_target_fops },
1223         { .name =       "spill_is_active",
1224           .fops =       &lod_spill_is_active_fops },
1225         { .name =       "spill_hit",
1226           .fops =       &lod_spill_hit_fops },
1227         { NULL }
1228 };
1229
1230 static struct proc_ops lod_proc_target_fops = {
1231         PROC_OWNER(THIS_MODULE)
1232         .proc_open      = lod_osts_seq_open,
1233         .proc_read      = seq_read,
1234         .proc_lseek     = seq_lseek,
1235         .proc_release   = lprocfs_seq_release,
1236 };
1237
1238 static struct attribute *lod_attrs[] = {
1239         &lustre_attr_dom_stripesize.attr,
1240         &lustre_attr_dom_stripesize_max_kb.attr,
1241         &lustre_attr_dom_stripesize_cur_kb.attr,
1242         &lustre_attr_dom_threshold_free_mb.attr,
1243         &lustre_attr_stripesize.attr,
1244         &lustre_attr_stripeoffset.attr,
1245         &lustre_attr_stripecount.attr,
1246         &lustre_attr_max_stripecount.attr,
1247         &lustre_attr_max_mdt_stripecount.attr,
1248         &lustre_attr_stripetype.attr,
1249         &lustre_attr_activeobd.attr,
1250         &lustre_attr_desc_uuid.attr,
1251         &lustre_attr_lmv_failout.attr,
1252         &lustre_attr_numobd.attr,
1253         &lustre_attr_qos_maxage.attr,
1254         &lustre_attr_qos_prio_free.attr,
1255         &lustre_attr_qos_threshold_rr.attr,
1256         &lustre_attr_mdt_stripecount.attr,
1257         &lustre_attr_mdt_stripetype.attr,
1258         &lustre_attr_mdt_activeobd.attr,
1259         &lustre_attr_mdt_numobd.attr,
1260         &lustre_attr_mdt_qos_maxage.attr,
1261         &lustre_attr_mdt_qos_prio_free.attr,
1262         &lustre_attr_mdt_qos_threshold_rr.attr,
1263         &lustre_attr_mdt_hash.attr,
1264         NULL,
1265 };
1266
1267 /**
1268  * Initialize procfs entries for LOD.
1269  *
1270  * \param[in] lod       LOD device
1271  *
1272  * \retval 0            on success
1273  * \retval negative     error code if failed
1274  */
1275 int lod_procfs_init(struct lod_device *lod)
1276 {
1277         struct obd_device *obd = lod2obd(lod);
1278         struct obd_type *type;
1279         struct kobject *lov;
1280         int rc;
1281
1282         lod->lod_dt_dev.dd_ktype.default_attrs = lod_attrs;
1283         rc = dt_tunables_init(&lod->lod_dt_dev, obd->obd_type, obd->obd_name,
1284                               NULL);
1285         if (rc) {
1286                 CERROR("%s: failed to setup DT tunables: %d\n",
1287                        obd->obd_name, rc);
1288                 RETURN(rc);
1289         }
1290
1291         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1292                                                obd->obd_type->typ_procroot,
1293                                                NULL, obd);
1294         if (IS_ERR(obd->obd_proc_entry)) {
1295                 rc = PTR_ERR(obd->obd_proc_entry);
1296                 CERROR("%s: error %d setting up lprocfs\n",
1297                        obd->obd_name, rc);
1298                 GOTO(out, rc);
1299         }
1300
1301         rc = lprocfs_seq_create(obd->obd_proc_entry, "mdt_obd",
1302                                 0444, &lod_proc_mdt_fops, obd);
1303         if (rc) {
1304                 CWARN("%s: Error adding the target_obd file %d\n",
1305                       obd->obd_name, rc);
1306                 GOTO(out, rc);
1307         }
1308
1309         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
1310                                 0444, &lod_proc_target_fops, obd);
1311         if (rc) {
1312                 CWARN("%s: Error adding the target_obd file %d\n",
1313                       obd->obd_name, rc);
1314                 GOTO(out, rc);
1315         }
1316
1317         lod->lod_pool_proc_entry = lprocfs_register("pools",
1318                                                     obd->obd_proc_entry,
1319                                                     NULL, NULL);
1320         if (IS_ERR(lod->lod_pool_proc_entry)) {
1321                 rc = PTR_ERR(lod->lod_pool_proc_entry);
1322                 lod->lod_pool_proc_entry = NULL;
1323                 CWARN("%s: Failed to create pools proc file: %d\n",
1324                       obd->obd_name, rc);
1325                 GOTO(out, rc);
1326         }
1327
1328         lod->lod_spill_proc_entry = lprocfs_register("pool",
1329                                                     obd->obd_proc_entry,
1330                                                     NULL, NULL);
1331         if (IS_ERR(lod->lod_spill_proc_entry)) {
1332                 rc = PTR_ERR(lod->lod_spill_proc_entry);
1333                 lod->lod_spill_proc_entry = NULL;
1334                 CWARN("%s: Failed to create pool proc file: %d\n",
1335                       obd->obd_name, rc);
1336                 GOTO(out, rc);
1337         }
1338
1339         lov = kset_find_obj(lustre_kset, "lov");
1340         if (!lov) {
1341                 CERROR("%s: lov subsystem not found\n", obd->obd_name);
1342                 GOTO(out, rc = -ENODEV);
1343         }
1344
1345         rc = sysfs_create_link(lov, &lod->lod_dt_dev.dd_kobj,
1346                                obd->obd_name);
1347         if (rc)
1348                 CERROR("%s: failed to create LOV sysfs symlink\n",
1349                        obd->obd_name);
1350         kobject_put(lov);
1351
1352         obd->obd_debugfs_entry = debugfs_create_dir(obd->obd_name,
1353                                                     obd->obd_type->typ_debugfs_entry);
1354
1355         lod->lod_debugfs = ldebugfs_add_symlink(obd->obd_name, "lov",
1356                                                 "../lod/%s", obd->obd_name);
1357         if (!lod->lod_debugfs)
1358                 CERROR("%s: failed to create LOV debugfs symlink\n",
1359                        obd->obd_name);
1360
1361         type = container_of(lov, struct obd_type, typ_kobj);
1362         if (!type->typ_procroot)
1363                 RETURN(0);
1364
1365         /* for compatibility we link old procfs's LOV entries to lod ones */
1366         lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
1367                                                type->typ_procroot,
1368                                                "../lod/%s", obd->obd_name);
1369         if (lod->lod_symlink == NULL)
1370                 CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n",
1371                        obd->obd_name);
1372         RETURN(0);
1373
1374 out:
1375         dt_tunables_fini(&lod->lod_dt_dev);
1376
1377         return rc;
1378 }
1379
1380 /**
1381  * Cleanup procfs entries registred for LOD.
1382  *
1383  * \param[in] lod       LOD device
1384  */
1385 void lod_procfs_fini(struct lod_device *lod)
1386 {
1387         struct obd_device *obd = lod2obd(lod);
1388         struct kobject *lov;
1389
1390         if (lod->lod_symlink != NULL) {
1391                 lprocfs_remove(&lod->lod_symlink);
1392                 lod->lod_symlink = NULL;
1393         }
1394
1395         lov = kset_find_obj(lustre_kset, "lov");
1396         if (lov) {
1397                 sysfs_remove_link(lov, obd->obd_name);
1398                 kobject_put(lov);
1399         }
1400
1401         debugfs_remove_recursive(lod->lod_debugfs);
1402
1403         if (obd->obd_proc_entry) {
1404                 lprocfs_remove(&obd->obd_proc_entry);
1405                 obd->obd_proc_entry = NULL;
1406         }
1407
1408         dt_tunables_fini(&lod->lod_dt_dev);
1409 }
1410
1411 #endif /* CONFIG_PROC_FS */