Whamcloud - gitweb
LU-14677 sec: migrate/extend/split on encrypted file
[fs/lustre-release.git] / lustre / lod / lproc_lod.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  */
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 /**
285  * Show default striping pattern (LOV_PATTERN_*).
286  */
287 static ssize_t __stripetype_show(struct kobject *kobj, struct attribute *attr,
288                                  char *buf, bool is_mdt)
289 {
290         struct dt_device *dt = container_of(kobj, struct dt_device,
291                                             dd_kobj);
292         struct lod_device *lod = dt2lod_dev(dt);
293         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
294                                             &lod->lod_ost_descs;
295
296         return scnprintf(buf, PAGE_SIZE, "%u\n", ltd->ltd_lov_desc.ld_pattern);
297 }
298
299 static ssize_t mdt_stripetype_show(struct kobject *kobj, struct attribute *attr,
300                                    char *buf)
301 {
302         return __stripetype_show(kobj, attr, buf, true);
303 }
304
305 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
306                                char *buf)
307 {
308         return __stripetype_show(kobj, attr, buf, false);
309 }
310
311 /**
312  * Set default striping pattern (a number, not a human-readable string).
313  */
314 static ssize_t __stripetype_store(struct kobject *kobj, struct attribute *attr,
315                                   const char *buffer, size_t count, bool is_mdt)
316 {
317         struct dt_device *dt = container_of(kobj, struct dt_device,
318                                             dd_kobj);
319         struct lod_device *lod = dt2lod_dev(dt);
320         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
321                                             &lod->lod_ost_descs;
322         u32 pattern;
323         int rc;
324
325         rc = kstrtouint(buffer, 0, &pattern);
326         if (rc)
327                 return rc;
328
329         if (is_mdt)
330                 lod_fix_lmv_desc_pattern(&pattern);
331         else
332                 lod_fix_desc_pattern(&pattern);
333
334         ltd->ltd_lov_desc.ld_pattern = pattern;
335
336         return count;
337 }
338
339 static ssize_t mdt_stripetype_store(struct kobject *kobj,
340                                     struct attribute *attr, const char *buffer,
341                                     size_t count)
342 {
343         return __stripetype_store(kobj, attr, buffer, count, true);
344 }
345
346 static ssize_t stripetype_store(struct kobject *kobj,
347                                     struct attribute *attr, const char *buffer,
348                                     size_t count)
349 {
350         return __stripetype_store(kobj, attr, buffer, count, false);
351 }
352
353 LUSTRE_RW_ATTR(mdt_stripetype);
354 LUSTRE_RW_ATTR(stripetype);
355
356 /**
357  * Show default number of stripes.
358  */
359 static ssize_t __stripecount_show(struct kobject *kobj, struct attribute *attr,
360                                   char *buf, bool is_mdt)
361 {
362         struct dt_device *dt = container_of(kobj, struct dt_device,
363                                             dd_kobj);
364         struct lod_device *lod = dt2lod_dev(dt);
365         struct lov_desc *desc = is_mdt ? &lod->lod_mdt_descs.ltd_lov_desc :
366                                          &lod->lod_ost_descs.ltd_lov_desc;
367
368         return scnprintf(buf, PAGE_SIZE, "%d\n",
369                          (s16)(desc->ld_default_stripe_count + 1) - 1);
370 }
371
372 static ssize_t mdt_stripecount_show(struct kobject *kobj,
373                                     struct attribute *attr, char *buf)
374 {
375         return __stripecount_show(kobj, attr, buf, true);
376 }
377
378 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
379                                 char *buf)
380 {
381         return __stripecount_show(kobj, attr, buf, false);
382 }
383
384 /**
385  * Set default number of stripes.
386  */
387 static ssize_t __stripecount_store(struct kobject *kobj, struct attribute *attr,
388                                    const char *buffer, size_t count,
389                                    bool is_mdt)
390 {
391         struct dt_device *dt = container_of(kobj, struct dt_device,
392                                             dd_kobj);
393         struct lod_device *lod = dt2lod_dev(dt);
394         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
395                                             &lod->lod_ost_descs;
396         int stripe_count;
397         int rc;
398
399         rc = kstrtoint(buffer, 0, &stripe_count);
400         if (rc)
401                 return rc;
402
403         if (stripe_count < -1)
404                 return -ERANGE;
405
406         lod_fix_desc_stripe_count(&stripe_count);
407         ltd->ltd_lov_desc.ld_default_stripe_count = stripe_count;
408
409         return count;
410 }
411
412 static ssize_t mdt_stripecount_store(struct kobject *kobj,
413                                      struct attribute *attr,
414                                      const char *buffer, size_t count)
415 {
416         return __stripecount_store(kobj, attr, buffer, count, true);
417 }
418
419 static ssize_t stripecount_store(struct kobject *kobj,
420                                  struct attribute *attr,
421                                  const char *buffer, size_t count)
422 {
423         return __stripecount_store(kobj, attr, buffer, count, false);
424 }
425
426 LUSTRE_RW_ATTR(mdt_stripecount);
427 LUSTRE_RW_ATTR(stripecount);
428
429 /**
430  * Show number of targets.
431  */
432 static ssize_t __numobd_show(struct kobject *kobj, struct attribute *attr,
433                              char *buf, bool is_mdt)
434 {
435         struct dt_device *dt = container_of(kobj, struct dt_device,
436                                             dd_kobj);
437         struct lod_device *lod = dt2lod_dev(dt);
438         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
439                                             &lod->lod_ost_descs;
440
441         return scnprintf(buf, PAGE_SIZE, "%u\n",
442                          ltd->ltd_lov_desc.ld_tgt_count);
443 }
444
445 static ssize_t mdt_numobd_show(struct kobject *kobj, struct attribute *attr,
446                                char *buf)
447 {
448         return __numobd_show(kobj, attr, buf, true);
449 }
450
451 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
452                            char *buf)
453 {
454         return __numobd_show(kobj, attr, buf, false);
455 }
456
457 LUSTRE_RO_ATTR(mdt_numobd);
458 LUSTRE_RO_ATTR(numobd);
459
460 /**
461  * Show number of active targets.
462  */
463 static ssize_t __activeobd_show(struct kobject *kobj, struct attribute *attr,
464                                 char *buf, bool is_mdt)
465 {
466         struct dt_device *dt = container_of(kobj, struct dt_device,
467                                             dd_kobj);
468         struct lod_device *lod = dt2lod_dev(dt);
469         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
470                                             &lod->lod_ost_descs;
471
472         return scnprintf(buf, PAGE_SIZE, "%u\n",
473                          ltd->ltd_lov_desc.ld_active_tgt_count);
474 }
475
476 static ssize_t mdt_activeobd_show(struct kobject *kobj, struct attribute *attr,
477                                   char *buf)
478 {
479         return __activeobd_show(kobj, attr, buf, true);
480 }
481
482 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
483                               char *buf)
484 {
485         return __activeobd_show(kobj, attr, buf, false);
486 }
487
488 LUSTRE_RO_ATTR(mdt_activeobd);
489 LUSTRE_RO_ATTR(activeobd);
490
491 /**
492  * Show UUID of LOD device.
493  */
494 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
495                               char *buf)
496 {
497         struct dt_device *dt = container_of(kobj, struct dt_device,
498                                             dd_kobj);
499         struct lod_device *lod = dt2lod_dev(dt);
500
501         return scnprintf(buf, PAGE_SIZE, "%s\n",
502                          lod->lod_ost_descs.ltd_lov_desc.ld_uuid.uuid);
503 }
504 LUSTRE_RO_ATTR(desc_uuid);
505
506 /**
507  * Show QoS priority parameter.
508  *
509  * The printed value is a percentage value (0-100%) indicating the priority
510  * of free space compared to performance. 0% means select OSTs equally
511  * regardless of their free space, 100% means select OSTs only by their free
512  * space even if it results in very imbalanced load on the OSTs.
513  */
514 static ssize_t __qos_prio_free_show(struct kobject *kobj,
515                                     struct attribute *attr, char *buf,
516                                     bool is_mdt)
517 {
518         struct dt_device *dt = container_of(kobj, struct dt_device,
519                                             dd_kobj);
520         struct lod_device *lod = dt2lod_dev(dt);
521         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
522                                             &lod->lod_ost_descs;
523
524         return scnprintf(buf, PAGE_SIZE, "%d%%\n",
525                          (ltd->ltd_qos.lq_prio_free * 100 + 255) >> 8);
526 }
527
528 static ssize_t mdt_qos_prio_free_show(struct kobject *kobj,
529                                       struct attribute *attr, char *buf)
530 {
531         return __qos_prio_free_show(kobj, attr, buf, true);
532 }
533
534 static ssize_t qos_prio_free_show(struct kobject *kobj,
535                                   struct attribute *attr, char *buf)
536 {
537         return __qos_prio_free_show(kobj, attr, buf, false);
538 }
539
540 /**
541  * Set QoS free space priority parameter.
542  *
543  * Set the relative priority of free OST space compared to OST load when OSTs
544  * are space imbalanced.  See qos_priofree_show() for description of
545  * this parameter.  See qos_threshold_rr_store() and lq_threshold_rr to
546  * determine what constitutes "space imbalanced" OSTs.
547  */
548 static ssize_t __qos_prio_free_store(struct kobject *kobj,
549                                      struct attribute *attr,
550                                      const char *buffer, size_t count,
551                                      bool is_mdt)
552 {
553         struct dt_device *dt = container_of(kobj, struct dt_device,
554                                             dd_kobj);
555         struct lod_device *lod = dt2lod_dev(dt);
556         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
557                                             &lod->lod_ost_descs;
558         unsigned int val;
559         int rc;
560
561         rc = kstrtouint(buffer, 0, &val);
562         if (rc)
563                 return rc;
564
565         if (val > 100)
566                 return -EINVAL;
567         ltd->ltd_qos.lq_prio_free = (val << 8) / 100;
568         set_bit(LQ_DIRTY, &ltd->ltd_qos.lq_flags);
569         set_bit(LQ_RESET, &ltd->ltd_qos.lq_flags);
570
571         return count;
572 }
573
574 static ssize_t mdt_qos_prio_free_store(struct kobject *kobj,
575                                        struct attribute *attr,
576                                        const char *buffer, size_t count)
577 {
578         return __qos_prio_free_store(kobj, attr, buffer, count, true);
579 }
580
581 static ssize_t qos_prio_free_store(struct kobject *kobj, struct attribute *attr,
582                                    const char *buffer, size_t count)
583 {
584         return __qos_prio_free_store(kobj, attr, buffer, count, false);
585 }
586
587 LUSTRE_RW_ATTR(mdt_qos_prio_free);
588 LUSTRE_RW_ATTR(qos_prio_free);
589
590 /**
591  * Show threshold for "same space on all OSTs" rule.
592  */
593 static ssize_t __qos_threshold_rr_show(struct kobject *kobj,
594                                        struct attribute *attr, char *buf,
595                                        bool is_mdt)
596 {
597         struct dt_device *dt = container_of(kobj, struct dt_device,
598                                             dd_kobj);
599         struct lod_device *lod = dt2lod_dev(dt);
600         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
601                                             &lod->lod_ost_descs;
602
603         return scnprintf(buf, PAGE_SIZE, "%d%%\n",
604                          (ltd->ltd_qos.lq_threshold_rr * 100 + 255) >> 8);
605 }
606
607 static ssize_t mdt_qos_threshold_rr_show(struct kobject *kobj,
608                                          struct attribute *attr, char *buf)
609 {
610         return __qos_threshold_rr_show(kobj, attr, buf, true);
611 }
612
613 static ssize_t qos_threshold_rr_show(struct kobject *kobj,
614                                      struct attribute *attr, char *buf)
615 {
616         return __qos_threshold_rr_show(kobj, attr, buf, false);
617 }
618
619 /**
620  * Set threshold for "same space on all OSTs" rule.
621  *
622  * This sets the maximum percentage difference of free space between the most
623  * full and most empty OST in the currently available OSTs. If this percentage
624  * is exceeded, use the QoS allocator to select OSTs based on their available
625  * space so that more full OSTs are chosen less often, otherwise use the
626  * round-robin allocator for efficiency and performance.
627  */
628 static ssize_t __qos_threshold_rr_store(struct kobject *kobj,
629                                         struct attribute *attr,
630                                         const char *buffer, size_t count,
631                                         bool is_mdt)
632 {
633         struct dt_device *dt = container_of(kobj, struct dt_device,
634                                             dd_kobj);
635         struct lod_device *lod = dt2lod_dev(dt);
636         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
637                                             &lod->lod_ost_descs;
638         char buf[6], *tmp;
639         unsigned int val;
640         int rc;
641
642         /* "100%\n\0" should be largest string */
643         if (count >= sizeof(buf))
644                 return -ERANGE;
645
646         strncpy(buf, buffer, sizeof(buf));
647         buf[sizeof(buf) - 1] = '\0';
648         tmp = strchr(buf, '%');
649         if (tmp)
650                 *tmp = '\0';
651
652         rc = kstrtouint(buf, 0, &val);
653         if (rc)
654                 return rc;
655
656         if (val > 100)
657                 return -EINVAL;
658         ltd->ltd_qos.lq_threshold_rr = (val << 8) / 100;
659         set_bit(LQ_DIRTY, &ltd->ltd_qos.lq_flags);
660
661         return count;
662 }
663
664 static ssize_t mdt_qos_threshold_rr_store(struct kobject *kobj,
665                                           struct attribute *attr,
666                                           const char *buffer, size_t count)
667 {
668         return __qos_threshold_rr_store(kobj, attr, buffer, count, true);
669 }
670
671 static ssize_t qos_threshold_rr_store(struct kobject *kobj,
672                                       struct attribute *attr,
673                                       const char *buffer, size_t count)
674 {
675         return __qos_threshold_rr_store(kobj, attr, buffer, count, false);
676 }
677
678 LUSTRE_RW_ATTR(mdt_qos_threshold_rr);
679 LUSTRE_RW_ATTR(qos_threshold_rr);
680
681 /**
682  * Show expiration period used to refresh cached statfs data, which
683  * is used to implement QoS/RR striping allocation algorithm.
684  */
685 static ssize_t __qos_maxage_show(struct kobject *kobj, struct attribute *attr,
686                                  char *buf, bool is_mdt)
687 {
688         struct dt_device *dt = container_of(kobj, struct dt_device,
689                                             dd_kobj);
690         struct lod_device *lod = dt2lod_dev(dt);
691         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
692                                             &lod->lod_ost_descs;
693
694         return scnprintf(buf, PAGE_SIZE, "%u Sec\n",
695                          ltd->ltd_lov_desc.ld_qos_maxage);
696 }
697
698 static ssize_t mdt_qos_maxage_show(struct kobject *kobj, struct attribute *attr,
699                                    char *buf)
700 {
701         return __qos_maxage_show(kobj, attr, buf, true);
702 }
703
704 static ssize_t qos_maxage_show(struct kobject *kobj, struct attribute *attr,
705                                char *buf)
706 {
707         return __qos_maxage_show(kobj, attr, buf, true);
708 }
709
710 /**
711  * Set expiration period used to refresh cached statfs data.
712  */
713 static ssize_t __qos_maxage_store(struct kobject *kobj, struct attribute *attr,
714                                   const char *buffer, size_t count, bool is_mdt)
715 {
716         struct dt_device *dt = container_of(kobj, struct dt_device,
717                                             dd_kobj);
718         struct lod_device *lod = dt2lod_dev(dt);
719         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
720                                             &lod->lod_ost_descs;
721         struct lustre_cfg_bufs bufs;
722         struct lu_device *next;
723         struct lustre_cfg *lcfg;
724         char str[32];
725         struct lu_tgt_desc *tgt;
726         int rc;
727         u32 val;
728
729         rc = kstrtouint(buffer, 0, &val);
730         if (rc)
731                 return rc;
732
733         if (val <= 0)
734                 return -EINVAL;
735
736         ltd->ltd_lov_desc.ld_qos_maxage = val;
737
738         /*
739          * propogate the value down to OSPs
740          */
741         lustre_cfg_bufs_reset(&bufs, NULL);
742         snprintf(str, 32, "%smaxage=%u", PARAM_OSP, val);
743         lustre_cfg_bufs_set_string(&bufs, 1, str);
744         OBD_ALLOC(lcfg, lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen));
745         if (lcfg == NULL)
746                 return -ENOMEM;
747         lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
748
749         lod_getref(ltd);
750         ltd_foreach_tgt(ltd, tgt) {
751                 next = &tgt->ltd_tgt->dd_lu_dev;
752                 rc = next->ld_ops->ldo_process_config(NULL, next, lcfg);
753                 if (rc)
754                         CERROR("can't set maxage on #%d: %d\n",
755                                tgt->ltd_index, rc);
756         }
757         lod_putref(lod, ltd);
758         OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens));
759
760         return count;
761 }
762
763 static ssize_t mdt_qos_maxage_store(struct kobject *kobj,
764                                     struct attribute *attr,
765                                     const char *buffer, size_t count)
766 {
767         return __qos_maxage_store(kobj, attr, buffer, count, true);
768 }
769
770 static ssize_t qos_maxage_store(struct kobject *kobj, struct attribute *attr,
771                                 const char *buffer, size_t count)
772 {
773         return __qos_maxage_store(kobj, attr, buffer, count, false);
774 }
775
776 LUSTRE_RW_ATTR(mdt_qos_maxage);
777 LUSTRE_RW_ATTR(qos_maxage);
778
779 static void *lod_tgts_seq_start(struct seq_file *p, loff_t *pos, bool is_mdt)
780 {
781         struct obd_device *obd = p->private;
782         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
783         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
784                                             &lod->lod_ost_descs;
785
786         LASSERT(obd != NULL);
787
788         lod_getref(ltd); /* released in lod_tgts_seq_stop */
789         if (*pos >= ltd->ltd_tgts_size)
790                 return NULL;
791
792         *pos = find_next_bit(ltd->ltd_tgt_bitmap,
793                              ltd->ltd_tgts_size, *pos);
794         if (*pos < ltd->ltd_tgts_size)
795                 return LTD_TGT(ltd, *pos);
796         else
797                 return NULL;
798 }
799
800 static void *lod_mdts_seq_start(struct seq_file *p, loff_t *pos)
801 {
802         return lod_tgts_seq_start(p, pos, true);
803 }
804
805 static void *lod_osts_seq_start(struct seq_file *p, loff_t *pos)
806 {
807         return lod_tgts_seq_start(p, pos, false);
808 }
809
810 static void lod_tgts_seq_stop(struct seq_file *p, void *v, bool is_mdt)
811 {
812         struct obd_device *obd = p->private;
813         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
814         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
815                                             &lod->lod_ost_descs;
816
817         LASSERT(obd != NULL);
818         lod_putref(lod, ltd);
819 }
820
821 static void lod_mdts_seq_stop(struct seq_file *p, void *v)
822 {
823         lod_tgts_seq_stop(p, v, true);
824 }
825
826 static void lod_osts_seq_stop(struct seq_file *p, void *v)
827 {
828         lod_tgts_seq_stop(p, v, false);
829 }
830
831 static void *lod_tgts_seq_next(struct seq_file *p, void *v, loff_t *pos,
832                                bool is_mdt)
833 {
834         struct obd_device *obd = p->private;
835         struct lod_device *lod = lu2lod_dev(obd->obd_lu_dev);
836         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
837                                             &lod->lod_ost_descs;
838
839         (*pos)++;
840         if (*pos > ltd->ltd_tgts_size - 1)
841                 return NULL;
842
843         *pos = find_next_bit(ltd->ltd_tgt_bitmap,
844                              ltd->ltd_tgts_size, *pos);
845         if (*pos < ltd->ltd_tgts_size)
846                 return LTD_TGT(ltd, *pos);
847         else
848                 return NULL;
849 }
850
851 static void *lod_mdts_seq_next(struct seq_file *p, void *v, loff_t *pos)
852 {
853         return lod_tgts_seq_next(p, v, pos, true);
854 }
855
856 static void *lod_osts_seq_next(struct seq_file *p, void *v, loff_t *pos)
857 {
858         return lod_tgts_seq_next(p, v, pos, false);
859 }
860
861 /**
862  * Show active/inactive status for OST found by lod_osts_seq_next().
863  *
864  * \param[in] m         seq file
865  * \param[in] v         unused for single entry
866  *
867  * \retval 0            on success
868  * \retval negative     error code if failed
869  */
870 static int lod_tgts_seq_show(struct seq_file *p, void *v)
871 {
872         struct obd_device *obd = p->private;
873         struct lu_tgt_desc *tgt = v;
874         struct dt_device *next;
875         int rc, active;
876
877         LASSERT(obd->obd_lu_dev);
878
879         next = tgt->ltd_tgt;
880         if (!next)
881                 return -EINVAL;
882
883         /* XXX: should be non-NULL env, but it's very expensive */
884         active = 1;
885         rc = dt_statfs(NULL, next, &tgt->ltd_statfs);
886         if (rc == -ENOTCONN) {
887                 active = 0;
888                 rc = 0;
889         } else if (rc)
890                 return rc;
891
892         seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
893                    obd_uuid2str(&tgt->ltd_uuid),
894                    active ? "" : "IN");
895         return 0;
896 }
897
898 static const struct seq_operations lod_mdts_sops = {
899         .start  = lod_mdts_seq_start,
900         .stop   = lod_mdts_seq_stop,
901         .next   = lod_mdts_seq_next,
902         .show   = lod_tgts_seq_show,
903 };
904
905 static const struct seq_operations lod_osts_sops = {
906         .start  = lod_osts_seq_start,
907         .stop   = lod_osts_seq_stop,
908         .next   = lod_osts_seq_next,
909         .show   = lod_tgts_seq_show,
910 };
911
912 static int lod_mdts_seq_open(struct inode *inode, struct file *file)
913 {
914         struct seq_file *seq;
915         int rc;
916
917         rc = seq_open(file, &lod_mdts_sops);
918         if (rc)
919                 return rc;
920
921         seq = file->private_data;
922         seq->private = PDE_DATA(inode);
923         return 0;
924 }
925
926 static int lod_osts_seq_open(struct inode *inode, struct file *file)
927 {
928         struct seq_file *seq;
929         int rc;
930
931         rc = seq_open(file, &lod_osts_sops);
932         if (rc)
933                 return rc;
934
935         seq = file->private_data;
936         seq->private = PDE_DATA(inode);
937         return 0;
938 }
939
940 /**
941  * Show whether special failout mode for testing is enabled or not.
942  */
943 static ssize_t lmv_failout_show(struct kobject *kobj, struct attribute *attr,
944                                 char *buf)
945 {
946         struct dt_device *dt = container_of(kobj, struct dt_device,
947                                             dd_kobj);
948         struct lod_device *lod = dt2lod_dev(dt);
949
950         return scnprintf(buf, PAGE_SIZE, "%d\n", lod->lod_lmv_failout ? 1 : 0);
951 }
952
953 /**
954  * Enable/disable a special failout mode for testing.
955  *
956  * This determines whether the LMV will try to continue processing a striped
957  * directory even if it has a (partly) corrupted entry in the master directory,
958  * or if it will abort upon finding a corrupted slave directory entry.
959  */
960 static ssize_t lmv_failout_store(struct kobject *kobj, struct attribute *attr,
961                                  const char *buffer, size_t count)
962 {
963         struct dt_device *dt = container_of(kobj, struct dt_device,
964                                             dd_kobj);
965         struct lod_device *lod = dt2lod_dev(dt);
966         bool val = 0;
967         int rc;
968
969         rc = kstrtobool(buffer, &val);
970         if (rc)
971                 return rc;
972
973         lod->lod_lmv_failout = val;
974
975         return count;
976 }
977 LUSTRE_RW_ATTR(lmv_failout);
978
979 static ssize_t mdt_hash_show(struct kobject *kobj, struct attribute *attr,
980                              char *buf)
981 {
982         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
983         struct lod_device *lod = dt2lod_dev(dt);
984
985         return scnprintf(buf, PAGE_SIZE, "%s\n",
986                 mdt_hash_name[lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern]);
987 }
988
989 static ssize_t mdt_hash_store(struct kobject *kobj, struct attribute *attr,
990                               const char *buffer, size_t count)
991 {
992         struct dt_device *dt = container_of(kobj, struct dt_device, dd_kobj);
993         struct lod_device *lod = dt2lod_dev(dt);
994         char *hash;
995         int len;
996         int i;
997
998         hash = kstrndup(buffer, count, GFP_KERNEL);
999         if (!hash)
1000                 return -ENOMEM;
1001
1002         len = strcspn(hash, "\n ");
1003         hash[len] = '\0';
1004         for (i = LMV_HASH_TYPE_ALL_CHARS; i < LMV_HASH_TYPE_MAX; i++) {
1005                 if (!strcmp(hash, mdt_hash_name[i])) {
1006                         lod->lod_mdt_descs.ltd_lmv_desc.ld_pattern = i;
1007                         kfree(hash);
1008                         return count;
1009                 }
1010         }
1011         kfree(hash);
1012
1013         return -EINVAL;
1014 }
1015 LUSTRE_RW_ATTR(mdt_hash);
1016
1017 static const struct proc_ops lod_proc_mdt_fops = {
1018         PROC_OWNER(THIS_MODULE)
1019         .proc_open      = lod_mdts_seq_open,
1020         .proc_read      = seq_read,
1021         .proc_lseek     = seq_lseek,
1022         .proc_release   = lprocfs_seq_release,
1023 };
1024
1025 static struct proc_ops lod_proc_target_fops = {
1026         PROC_OWNER(THIS_MODULE)
1027         .proc_open      = lod_osts_seq_open,
1028         .proc_read      = seq_read,
1029         .proc_lseek     = seq_lseek,
1030         .proc_release   = lprocfs_seq_release,
1031 };
1032
1033 static struct attribute *lod_attrs[] = {
1034         &lustre_attr_dom_stripesize.attr,
1035         &lustre_attr_dom_stripesize_max_kb.attr,
1036         &lustre_attr_dom_stripesize_cur_kb.attr,
1037         &lustre_attr_dom_threshold_free_mb.attr,
1038         &lustre_attr_stripesize.attr,
1039         &lustre_attr_stripeoffset.attr,
1040         &lustre_attr_stripecount.attr,
1041         &lustre_attr_stripetype.attr,
1042         &lustre_attr_activeobd.attr,
1043         &lustre_attr_desc_uuid.attr,
1044         &lustre_attr_lmv_failout.attr,
1045         &lustre_attr_numobd.attr,
1046         &lustre_attr_qos_maxage.attr,
1047         &lustre_attr_qos_prio_free.attr,
1048         &lustre_attr_qos_threshold_rr.attr,
1049         &lustre_attr_mdt_stripecount.attr,
1050         &lustre_attr_mdt_stripetype.attr,
1051         &lustre_attr_mdt_activeobd.attr,
1052         &lustre_attr_mdt_numobd.attr,
1053         &lustre_attr_mdt_qos_maxage.attr,
1054         &lustre_attr_mdt_qos_prio_free.attr,
1055         &lustre_attr_mdt_qos_threshold_rr.attr,
1056         &lustre_attr_mdt_hash.attr,
1057         NULL,
1058 };
1059
1060 /**
1061  * Initialize procfs entries for LOD.
1062  *
1063  * \param[in] lod       LOD device
1064  *
1065  * \retval 0            on success
1066  * \retval negative     error code if failed
1067  */
1068 int lod_procfs_init(struct lod_device *lod)
1069 {
1070         struct obd_device *obd = lod2obd(lod);
1071         struct obd_type *type;
1072         struct kobject *lov;
1073         int rc;
1074
1075         lod->lod_dt_dev.dd_ktype.default_attrs = lod_attrs;
1076         rc = dt_tunables_init(&lod->lod_dt_dev, obd->obd_type, obd->obd_name,
1077                               NULL);
1078         if (rc) {
1079                 CERROR("%s: failed to setup DT tunables: %d\n",
1080                        obd->obd_name, rc);
1081                 RETURN(rc);
1082         }
1083
1084         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
1085                                                obd->obd_type->typ_procroot,
1086                                                NULL, obd);
1087         if (IS_ERR(obd->obd_proc_entry)) {
1088                 rc = PTR_ERR(obd->obd_proc_entry);
1089                 CERROR("%s: error %d setting up lprocfs\n",
1090                        obd->obd_name, rc);
1091                 GOTO(out, rc);
1092         }
1093
1094         rc = lprocfs_seq_create(obd->obd_proc_entry, "mdt_obd",
1095                                 0444, &lod_proc_mdt_fops, obd);
1096         if (rc) {
1097                 CWARN("%s: Error adding the target_obd file %d\n",
1098                       obd->obd_name, rc);
1099                 GOTO(out, rc);
1100         }
1101
1102         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
1103                                 0444, &lod_proc_target_fops, obd);
1104         if (rc) {
1105                 CWARN("%s: Error adding the target_obd file %d\n",
1106                       obd->obd_name, rc);
1107                 GOTO(out, rc);
1108         }
1109
1110         lod->lod_pool_proc_entry = lprocfs_register("pools",
1111                                                     obd->obd_proc_entry,
1112                                                     NULL, NULL);
1113         if (IS_ERR(lod->lod_pool_proc_entry)) {
1114                 rc = PTR_ERR(lod->lod_pool_proc_entry);
1115                 lod->lod_pool_proc_entry = NULL;
1116                 CWARN("%s: Failed to create pool proc file: %d\n",
1117                       obd->obd_name, rc);
1118                 GOTO(out, rc);
1119         }
1120
1121         lov = kset_find_obj(lustre_kset, "lov");
1122         if (!lov) {
1123                 CERROR("%s: lov subsystem not found\n", obd->obd_name);
1124                 GOTO(out, rc = -ENODEV);
1125         }
1126
1127         rc = sysfs_create_link(lov, &lod->lod_dt_dev.dd_kobj,
1128                                obd->obd_name);
1129         if (rc)
1130                 CERROR("%s: failed to create LOV sysfs symlink\n",
1131                        obd->obd_name);
1132         kobject_put(lov);
1133
1134         lod->lod_debugfs = ldebugfs_add_symlink(obd->obd_name, "lov",
1135                                                 "../lod/%s", obd->obd_name);
1136         if (!lod->lod_debugfs)
1137                 CERROR("%s: failed to create LOV debugfs symlink\n",
1138                        obd->obd_name);
1139
1140         type = container_of(lov, struct obd_type, typ_kobj);
1141         if (!type->typ_procroot)
1142                 RETURN(0);
1143
1144         /* for compatibility we link old procfs's LOV entries to lod ones */
1145         lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
1146                                                type->typ_procroot,
1147                                                "../lod/%s", obd->obd_name);
1148         if (lod->lod_symlink == NULL)
1149                 CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n",
1150                        obd->obd_name);
1151         RETURN(0);
1152
1153 out:
1154         dt_tunables_fini(&lod->lod_dt_dev);
1155
1156         return rc;
1157 }
1158
1159 /**
1160  * Cleanup procfs entries registred for LOD.
1161  *
1162  * \param[in] lod       LOD device
1163  */
1164 void lod_procfs_fini(struct lod_device *lod)
1165 {
1166         struct obd_device *obd = lod2obd(lod);
1167         struct kobject *lov;
1168
1169         if (lod->lod_symlink != NULL) {
1170                 lprocfs_remove(&lod->lod_symlink);
1171                 lod->lod_symlink = NULL;
1172         }
1173
1174         lov = kset_find_obj(lustre_kset, "lov");
1175         if (lov) {
1176                 sysfs_remove_link(lov, obd->obd_name);
1177                 kobject_put(lov);
1178         }
1179
1180         debugfs_remove_recursive(lod->lod_debugfs);
1181
1182         if (obd->obd_proc_entry) {
1183                 lprocfs_remove(&obd->obd_proc_entry);
1184                 obd->obd_proc_entry = NULL;
1185         }
1186
1187         dt_tunables_fini(&lod->lod_dt_dev);
1188 }
1189
1190 #endif /* CONFIG_PROC_FS */