Whamcloud - gitweb
LU-13004 ptlrpc: Allow BULK_BUF_KIOV to accept a kvec
[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  * Lustre is a trademark of Sun Microsystems, Inc.
31  */
32 #define DEBUG_SUBSYSTEM S_CLASS
33
34 #include <lprocfs_status.h>
35 #include <obd_class.h>
36 #include <linux/seq_file.h>
37 #include "lod_internal.h"
38 #include <uapi/linux/lustre/lustre_param.h>
39
40 /*
41  * Notice, all the functions below (except for lod_procfs_init() and
42  * lod_procfs_fini()) are not supposed to be used directly. They are
43  * called by Linux kernel's procfs.
44  */
45
46 #ifdef CONFIG_PROC_FS
47
48 /**
49  * Show DoM default stripe size.
50  */
51 static ssize_t dom_stripesize_show(struct kobject *kobj, struct attribute *attr,
52                                    char *buf)
53 {
54         struct dt_device *dt = container_of(kobj, struct dt_device,
55                                             dd_kobj);
56         struct lod_device *lod = dt2lod_dev(dt);
57
58         return snprintf(buf, PAGE_SIZE, "%u\n", lod->lod_dom_max_stripesize);
59 }
60
61 /**
62  * Set DoM default stripe size.
63  */
64 static ssize_t dom_stripesize_store(struct kobject *kobj,
65                                     struct attribute *attr, const char *buffer,
66                                     size_t count)
67 {
68         struct dt_device *dt = container_of(kobj, struct dt_device,
69                                             dd_kobj);
70         struct lod_device *lod = dt2lod_dev(dt);
71         u64 val;
72         int rc;
73
74         rc = sysfs_memparse(buffer, count, &val, "B");
75         if (rc < 0)
76                 return rc;
77
78         /* 1GB is the limit */
79         if (val > (1ULL << 30))
80                 return -ERANGE;
81
82         if (val > 0) {
83                 if (val < LOV_MIN_STRIPE_SIZE) {
84                         LCONSOLE_INFO("Increasing provided stripe size to "
85                                       "a minimum value %u\n",
86                                       LOV_MIN_STRIPE_SIZE);
87                         val = LOV_MIN_STRIPE_SIZE;
88                 } else if (val & (LOV_MIN_STRIPE_SIZE - 1)) {
89                         val &= ~(LOV_MIN_STRIPE_SIZE - 1);
90                         LCONSOLE_WARN("Changing provided stripe size to %llu "
91                                       "(a multiple of minimum %u)\n",
92                                       val, LOV_MIN_STRIPE_SIZE);
93                 }
94         }
95
96         lod->lod_dom_max_stripesize = val;
97
98         return count;
99 }
100
101 LUSTRE_RW_ATTR(dom_stripesize);
102
103 static ssize_t stripesize_show(struct kobject *kobj, struct attribute *attr,
104                                char *buf)
105 {
106         struct dt_device *dt = container_of(kobj, struct dt_device,
107                                             dd_kobj);
108         struct lod_device *lod = dt2lod_dev(dt);
109
110         return snprintf(buf, PAGE_SIZE, "%llu\n",
111                         lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_size);
112 }
113
114 static ssize_t stripesize_store(struct kobject *kobj, struct attribute *attr,
115                                 const char *buffer, size_t count)
116 {
117         struct dt_device *dt = container_of(kobj, struct dt_device,
118                                             dd_kobj);
119         struct lod_device *lod = dt2lod_dev(dt);
120         u64 val;
121         int rc;
122
123         rc = sysfs_memparse(buffer, count, &val, "B");
124         if (rc < 0)
125                 return rc;
126
127         lod_fix_desc_stripe_size(&val);
128         lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_size = val;
129
130         return count;
131 }
132
133 LUSTRE_RW_ATTR(stripesize);
134
135 /**
136  * Show default stripe offset.
137  */
138 static ssize_t stripeoffset_show(struct kobject *kobj, struct attribute *attr,
139                                  char *buf)
140 {
141         struct dt_device *dt = container_of(kobj, struct dt_device,
142                                             dd_kobj);
143         struct lod_device *lod = dt2lod_dev(dt);
144
145         return snprintf(buf, PAGE_SIZE, "%lld\n",
146                 lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_offset);
147 }
148
149 /**
150  * Set default stripe offset.
151  *
152  * Usually contains -1 allowing Lustre to balance objects among OST
153  * otherwise may cause severe OST imbalance.
154  */
155 static ssize_t stripeoffset_store(struct kobject *kobj,
156                                     struct attribute *attr,
157                                     const char *buffer, size_t count)
158 {
159         struct dt_device *dt = container_of(kobj, struct dt_device,
160                                             dd_kobj);
161         struct lod_device *lod = dt2lod_dev(dt);
162         long val;
163         int rc;
164
165         rc = kstrtol(buffer, 0, &val);
166         if (rc)
167                 return rc;
168
169         if (val < -1 || val > LOV_MAX_STRIPE_COUNT)
170                 return -ERANGE;
171
172         lod->lod_ost_descs.ltd_lov_desc.ld_default_stripe_offset = val;
173
174         return count;
175 }
176
177 LUSTRE_RW_ATTR(stripeoffset);
178
179 /**
180  * Show default striping pattern (LOV_PATTERN_*).
181  */
182 static ssize_t __stripetype_show(struct kobject *kobj, struct attribute *attr,
183                                  char *buf, bool is_mdt)
184 {
185         struct dt_device *dt = container_of(kobj, struct dt_device,
186                                             dd_kobj);
187         struct lod_device *lod = dt2lod_dev(dt);
188         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
189                                             &lod->lod_ost_descs;
190
191         return snprintf(buf, PAGE_SIZE, "%u\n", ltd->ltd_lov_desc.ld_pattern);
192 }
193
194 static ssize_t mdt_stripetype_show(struct kobject *kobj, struct attribute *attr,
195                                    char *buf)
196 {
197         return __stripetype_show(kobj, attr, buf, true);
198 }
199
200 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
201                                char *buf)
202 {
203         return __stripetype_show(kobj, attr, buf, false);
204 }
205
206 /**
207  * Set default striping pattern (a number, not a human-readable string).
208  */
209 static ssize_t __stripetype_store(struct kobject *kobj, struct attribute *attr,
210                                   const char *buffer, size_t count, bool is_mdt)
211 {
212         struct dt_device *dt = container_of(kobj, struct dt_device,
213                                             dd_kobj);
214         struct lod_device *lod = dt2lod_dev(dt);
215         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
216                                             &lod->lod_ost_descs;
217         u32 pattern;
218         int rc;
219
220         rc = kstrtouint(buffer, 0, &pattern);
221         if (rc)
222                 return rc;
223
224         if (is_mdt)
225                 lod_fix_lmv_desc_pattern(&pattern);
226         else
227                 lod_fix_desc_pattern(&pattern);
228
229         ltd->ltd_lov_desc.ld_pattern = pattern;
230
231         return count;
232 }
233
234 static ssize_t mdt_stripetype_store(struct kobject *kobj,
235                                     struct attribute *attr, const char *buffer,
236                                     size_t count)
237 {
238         return __stripetype_store(kobj, attr, buffer, count, true);
239 }
240
241 static ssize_t stripetype_store(struct kobject *kobj,
242                                     struct attribute *attr, const char *buffer,
243                                     size_t count)
244 {
245         return __stripetype_store(kobj, attr, buffer, count, false);
246 }
247
248 LUSTRE_RW_ATTR(mdt_stripetype);
249 LUSTRE_RW_ATTR(stripetype);
250
251 /**
252  * Show default number of stripes.
253  */
254 static ssize_t __stripecount_show(struct kobject *kobj, struct attribute *attr,
255                                   char *buf, bool is_mdt)
256 {
257         struct dt_device *dt = container_of(kobj, struct dt_device,
258                                             dd_kobj);
259         struct lod_device *lod = dt2lod_dev(dt);
260         struct lov_desc *desc = is_mdt ? &lod->lod_mdt_descs.ltd_lov_desc :
261                                          &lod->lod_ost_descs.ltd_lov_desc;
262
263         return snprintf(buf, PAGE_SIZE, "%d\n",
264                       (s16)(desc->ld_default_stripe_count + 1) - 1);
265 }
266
267 static ssize_t mdt_stripecount_show(struct kobject *kobj,
268                                     struct attribute *attr, char *buf)
269 {
270         return __stripecount_show(kobj, attr, buf, true);
271 }
272
273 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
274                                 char *buf)
275 {
276         return __stripecount_show(kobj, attr, buf, false);
277 }
278
279 /**
280  * Set default number of stripes.
281  */
282 static ssize_t __stripecount_store(struct kobject *kobj, struct attribute *attr,
283                                    const char *buffer, size_t count,
284                                    bool is_mdt)
285 {
286         struct dt_device *dt = container_of(kobj, struct dt_device,
287                                             dd_kobj);
288         struct lod_device *lod = dt2lod_dev(dt);
289         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
290                                             &lod->lod_ost_descs;
291         int stripe_count;
292         int rc;
293
294         rc = kstrtoint(buffer, 0, &stripe_count);
295         if (rc)
296                 return rc;
297
298         if (stripe_count < -1)
299                 return -ERANGE;
300
301         lod_fix_desc_stripe_count(&stripe_count);
302         ltd->ltd_lov_desc.ld_default_stripe_count = stripe_count;
303
304         return count;
305 }
306
307 static ssize_t mdt_stripecount_store(struct kobject *kobj,
308                                      struct attribute *attr,
309                                      const char *buffer, size_t count)
310 {
311         return __stripecount_store(kobj, attr, buffer, count, true);
312 }
313
314 static ssize_t stripecount_store(struct kobject *kobj,
315                                  struct attribute *attr,
316                                  const char *buffer, size_t count)
317 {
318         return __stripecount_store(kobj, attr, buffer, count, false);
319 }
320
321 LUSTRE_RW_ATTR(mdt_stripecount);
322 LUSTRE_RW_ATTR(stripecount);
323
324 /**
325  * Show number of targets.
326  */
327 static ssize_t __numobd_show(struct kobject *kobj, struct attribute *attr,
328                              char *buf, bool is_mdt)
329 {
330         struct dt_device *dt = container_of(kobj, struct dt_device,
331                                             dd_kobj);
332         struct lod_device *lod = dt2lod_dev(dt);
333         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
334                                             &lod->lod_ost_descs;
335
336         return snprintf(buf, PAGE_SIZE, "%u\n", ltd->ltd_lov_desc.ld_tgt_count);
337 }
338
339 static ssize_t mdt_numobd_show(struct kobject *kobj, struct attribute *attr,
340                                char *buf)
341 {
342         return __numobd_show(kobj, attr, buf, true);
343 }
344
345 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
346                            char *buf)
347 {
348         return __numobd_show(kobj, attr, buf, false);
349 }
350
351 LUSTRE_RO_ATTR(mdt_numobd);
352 LUSTRE_RO_ATTR(numobd);
353
354 /**
355  * Show number of active targets.
356  */
357 static ssize_t __activeobd_show(struct kobject *kobj, struct attribute *attr,
358                                 char *buf, bool is_mdt)
359 {
360         struct dt_device *dt = container_of(kobj, struct dt_device,
361                                             dd_kobj);
362         struct lod_device *lod = dt2lod_dev(dt);
363         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
364                                             &lod->lod_ost_descs;
365
366         return snprintf(buf, PAGE_SIZE, "%u\n",
367                         ltd->ltd_lov_desc.ld_active_tgt_count);
368 }
369
370 static ssize_t mdt_activeobd_show(struct kobject *kobj, struct attribute *attr,
371                                   char *buf)
372 {
373         return __activeobd_show(kobj, attr, buf, true);
374 }
375
376 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
377                               char *buf)
378 {
379         return __activeobd_show(kobj, attr, buf, false);
380 }
381
382 LUSTRE_RO_ATTR(mdt_activeobd);
383 LUSTRE_RO_ATTR(activeobd);
384
385 /**
386  * Show UUID of LOD device.
387  */
388 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
389                               char *buf)
390 {
391         struct dt_device *dt = container_of(kobj, struct dt_device,
392                                             dd_kobj);
393         struct lod_device *lod = dt2lod_dev(dt);
394
395         return snprintf(buf, PAGE_SIZE, "%s\n",
396                        lod->lod_ost_descs.ltd_lov_desc.ld_uuid.uuid);
397 }
398 LUSTRE_RO_ATTR(desc_uuid);
399
400 /**
401  * Show QoS priority parameter.
402  *
403  * The printed value is a percentage value (0-100%) indicating the priority
404  * of free space compared to performance. 0% means select OSTs equally
405  * regardless of their free space, 100% means select OSTs only by their free
406  * space even if it results in very imbalanced load on the OSTs.
407  */
408 static ssize_t __qos_prio_free_show(struct kobject *kobj,
409                                     struct attribute *attr, char *buf,
410                                     bool is_mdt)
411 {
412         struct dt_device *dt = container_of(kobj, struct dt_device,
413                                             dd_kobj);
414         struct lod_device *lod = dt2lod_dev(dt);
415         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
416                                             &lod->lod_ost_descs;
417
418         return snprintf(buf, PAGE_SIZE, "%d%%\n",
419                        (ltd->ltd_qos.lq_prio_free * 100 + 255) >> 8);
420 }
421
422 static ssize_t mdt_qos_prio_free_show(struct kobject *kobj,
423                                       struct attribute *attr, char *buf)
424 {
425         return __qos_prio_free_show(kobj, attr, buf, true);
426 }
427
428 static ssize_t qos_prio_free_show(struct kobject *kobj,
429                                   struct attribute *attr, char *buf)
430 {
431         return __qos_prio_free_show(kobj, attr, buf, false);
432 }
433
434 /**
435  * Set QoS free space priority parameter.
436  *
437  * Set the relative priority of free OST space compared to OST load when OSTs
438  * are space imbalanced.  See qos_priofree_show() for description of
439  * this parameter.  See qos_threshold_rr_store() and lq_threshold_rr to
440  * determine what constitutes "space imbalanced" OSTs.
441  */
442 static ssize_t __qos_prio_free_store(struct kobject *kobj,
443                                      struct attribute *attr,
444                                      const char *buffer, size_t count,
445                                      bool is_mdt)
446 {
447         struct dt_device *dt = container_of(kobj, struct dt_device,
448                                             dd_kobj);
449         struct lod_device *lod = dt2lod_dev(dt);
450         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
451                                             &lod->lod_ost_descs;
452         unsigned int val;
453         int rc;
454
455         rc = kstrtouint(buffer, 0, &val);
456         if (rc)
457                 return rc;
458
459         if (val > 100)
460                 return -EINVAL;
461         ltd->ltd_qos.lq_prio_free = (val << 8) / 100;
462         ltd->ltd_qos.lq_dirty = 1;
463         ltd->ltd_qos.lq_reset = 1;
464
465         return count;
466 }
467
468 static ssize_t mdt_qos_prio_free_store(struct kobject *kobj,
469                                        struct attribute *attr,
470                                        const char *buffer, size_t count)
471 {
472         return __qos_prio_free_store(kobj, attr, buffer, count, true);
473 }
474
475 static ssize_t qos_prio_free_store(struct kobject *kobj, struct attribute *attr,
476                                    const char *buffer, size_t count)
477 {
478         return __qos_prio_free_store(kobj, attr, buffer, count, false);
479 }
480
481 LUSTRE_RW_ATTR(mdt_qos_prio_free);
482 LUSTRE_RW_ATTR(qos_prio_free);
483
484 /**
485  * Show threshold for "same space on all OSTs" rule.
486  */
487 static ssize_t __qos_threshold_rr_show(struct kobject *kobj,
488                                        struct attribute *attr, char *buf,
489                                        bool is_mdt)
490 {
491         struct dt_device *dt = container_of(kobj, struct dt_device,
492                                             dd_kobj);
493         struct lod_device *lod = dt2lod_dev(dt);
494         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
495                                             &lod->lod_ost_descs;
496
497         return snprintf(buf, PAGE_SIZE, "%d%%\n",
498                        (ltd->ltd_qos.lq_threshold_rr * 100 + 255) >> 8);
499 }
500
501 static ssize_t mdt_qos_threshold_rr_show(struct kobject *kobj,
502                                          struct attribute *attr, char *buf)
503 {
504         return __qos_threshold_rr_show(kobj, attr, buf, true);
505 }
506
507 static ssize_t qos_threshold_rr_show(struct kobject *kobj,
508                                      struct attribute *attr, char *buf)
509 {
510         return __qos_threshold_rr_show(kobj, attr, buf, false);
511 }
512
513 /**
514  * Set threshold for "same space on all OSTs" rule.
515  *
516  * This sets the maximum percentage difference of free space between the most
517  * full and most empty OST in the currently available OSTs. If this percentage
518  * is exceeded, use the QoS allocator to select OSTs based on their available
519  * space so that more full OSTs are chosen less often, otherwise use the
520  * round-robin allocator for efficiency and performance.
521  */
522 static ssize_t __qos_threshold_rr_store(struct kobject *kobj,
523                                         struct attribute *attr,
524                                         const char *buffer, size_t count,
525                                         bool is_mdt)
526 {
527         struct dt_device *dt = container_of(kobj, struct dt_device,
528                                             dd_kobj);
529         struct lod_device *lod = dt2lod_dev(dt);
530         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
531                                             &lod->lod_ost_descs;
532         char buf[6], *tmp;
533         unsigned int val;
534         int rc;
535
536         /* "100%\n\0" should be largest string */
537         if (count >= sizeof(buf))
538                 return -ERANGE;
539
540         strncpy(buf, buffer, sizeof(buf));
541         buf[sizeof(buf) - 1] = '\0';
542         tmp = strchr(buf, '%');
543         if (tmp)
544                 *tmp = '\0';
545
546         rc = kstrtouint(buf, 0, &val);
547         if (rc)
548                 return rc;
549
550         if (val > 100)
551                 return -EINVAL;
552         ltd->ltd_qos.lq_threshold_rr = (val << 8) / 100;
553         ltd->ltd_qos.lq_dirty = 1;
554
555         return count;
556 }
557
558 static ssize_t mdt_qos_threshold_rr_store(struct kobject *kobj,
559                                           struct attribute *attr,
560                                           const char *buffer, size_t count)
561 {
562         return __qos_threshold_rr_store(kobj, attr, buffer, count, true);
563 }
564
565 static ssize_t qos_threshold_rr_store(struct kobject *kobj,
566                                       struct attribute *attr,
567                                       const char *buffer, size_t count)
568 {
569         return __qos_threshold_rr_store(kobj, attr, buffer, count, false);
570 }
571
572 LUSTRE_RW_ATTR(mdt_qos_threshold_rr);
573 LUSTRE_RW_ATTR(qos_threshold_rr);
574
575 /**
576  * Show expiration period used to refresh cached statfs data, which
577  * is used to implement QoS/RR striping allocation algorithm.
578  */
579 static ssize_t __qos_maxage_show(struct kobject *kobj, struct attribute *attr,
580                                  char *buf, bool is_mdt)
581 {
582         struct dt_device *dt = container_of(kobj, struct dt_device,
583                                             dd_kobj);
584         struct lod_device *lod = dt2lod_dev(dt);
585         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
586                                             &lod->lod_ost_descs;
587
588         return snprintf(buf, PAGE_SIZE, "%u Sec\n",
589                        ltd->ltd_lov_desc.ld_qos_maxage);
590 }
591
592 static ssize_t mdt_qos_maxage_show(struct kobject *kobj, struct attribute *attr,
593                                    char *buf)
594 {
595         return __qos_maxage_show(kobj, attr, buf, true);
596 }
597
598 static ssize_t qos_maxage_show(struct kobject *kobj, struct attribute *attr,
599                                char *buf)
600 {
601         return __qos_maxage_show(kobj, attr, buf, true);
602 }
603
604 /**
605  * Set expiration period used to refresh cached statfs data.
606  */
607 static ssize_t __qos_maxage_store(struct kobject *kobj, struct attribute *attr,
608                                   const char *buffer, size_t count, bool is_mdt)
609 {
610         struct dt_device *dt = container_of(kobj, struct dt_device,
611                                             dd_kobj);
612         struct lod_device *lod = dt2lod_dev(dt);
613         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
614                                             &lod->lod_ost_descs;
615         struct lustre_cfg_bufs bufs;
616         struct lu_device *next;
617         struct lustre_cfg *lcfg;
618         char str[32];
619         struct lu_tgt_desc *tgt;
620         int rc;
621         u32 val;
622
623         rc = kstrtouint(buffer, 0, &val);
624         if (rc)
625                 return rc;
626
627         if (val <= 0)
628                 return -EINVAL;
629
630         ltd->ltd_lov_desc.ld_qos_maxage = val;
631
632         /*
633          * propogate the value down to OSPs
634          */
635         lustre_cfg_bufs_reset(&bufs, NULL);
636         snprintf(str, 32, "%smaxage=%u", PARAM_OSP, val);
637         lustre_cfg_bufs_set_string(&bufs, 1, str);
638         OBD_ALLOC(lcfg, lustre_cfg_len(bufs.lcfg_bufcount, bufs.lcfg_buflen));
639         if (lcfg == NULL)
640                 return -ENOMEM;
641         lustre_cfg_init(lcfg, LCFG_PARAM, &bufs);
642
643         lod_getref(ltd);
644         ltd_foreach_tgt(ltd, tgt) {
645                 next = &tgt->ltd_tgt->dd_lu_dev;
646                 rc = next->ld_ops->ldo_process_config(NULL, next, lcfg);
647                 if (rc)
648                         CERROR("can't set maxage on #%d: %d\n",
649                                tgt->ltd_index, rc);
650         }
651         lod_putref(lod, ltd);
652         OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount, lcfg->lcfg_buflens));
653
654         return count;
655 }
656
657 static ssize_t mdt_qos_maxage_store(struct kobject *kobj,
658                                     struct attribute *attr,
659                                     const char *buffer, size_t count)
660 {
661         return __qos_maxage_store(kobj, attr, buffer, count, true);
662 }
663
664 static ssize_t qos_maxage_store(struct kobject *kobj, struct attribute *attr,
665                                 const char *buffer, size_t count)
666 {
667         return __qos_maxage_store(kobj, attr, buffer, count, false);
668 }
669
670 LUSTRE_RW_ATTR(mdt_qos_maxage);
671 LUSTRE_RW_ATTR(qos_maxage);
672
673 static void *lod_tgts_seq_start(struct seq_file *p, loff_t *pos, bool is_mdt)
674 {
675         struct obd_device *dev = p->private;
676         struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
677         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
678                                             &lod->lod_ost_descs;
679
680         LASSERT(dev != NULL);
681
682         lod_getref(ltd); /* released in lod_tgts_seq_stop */
683         if (*pos >= ltd->ltd_tgt_bitmap->size)
684                 return NULL;
685
686         *pos = find_next_bit(ltd->ltd_tgt_bitmap->data,
687                              ltd->ltd_tgt_bitmap->size, *pos);
688         if (*pos < ltd->ltd_tgt_bitmap->size)
689                 return LTD_TGT(ltd, *pos);
690         else
691                 return NULL;
692 }
693
694 static void *lod_mdts_seq_start(struct seq_file *p, loff_t *pos)
695 {
696         return lod_tgts_seq_start(p, pos, true);
697 }
698
699 static void *lod_osts_seq_start(struct seq_file *p, loff_t *pos)
700 {
701         return lod_tgts_seq_start(p, pos, false);
702 }
703
704 static void lod_tgts_seq_stop(struct seq_file *p, void *v, bool is_mdt)
705 {
706         struct obd_device *dev = p->private;
707         struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
708         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
709                                             &lod->lod_ost_descs;
710
711         LASSERT(dev != NULL);
712         lod_putref(lod, ltd);
713 }
714
715 static void lod_mdts_seq_stop(struct seq_file *p, void *v)
716 {
717         lod_tgts_seq_stop(p, v, true);
718 }
719
720 static void lod_osts_seq_stop(struct seq_file *p, void *v)
721 {
722         lod_tgts_seq_stop(p, v, false);
723 }
724
725 static void *lod_tgts_seq_next(struct seq_file *p, void *v, loff_t *pos,
726                                bool is_mdt)
727 {
728         struct obd_device *dev = p->private;
729         struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
730         struct lu_tgt_descs *ltd = is_mdt ? &lod->lod_mdt_descs :
731                                             &lod->lod_ost_descs;
732
733         if (*pos >= ltd->ltd_tgt_bitmap->size - 1)
734                 return NULL;
735
736         *pos = find_next_bit(ltd->ltd_tgt_bitmap->data,
737                              ltd->ltd_tgt_bitmap->size, *pos + 1);
738         if (*pos < ltd->ltd_tgt_bitmap->size)
739                 return LTD_TGT(ltd, *pos);
740         else
741                 return NULL;
742 }
743
744 static void *lod_mdts_seq_next(struct seq_file *p, void *v, loff_t *pos)
745 {
746         return lod_tgts_seq_next(p, v, pos, true);
747 }
748
749 static void *lod_osts_seq_next(struct seq_file *p, void *v, loff_t *pos)
750 {
751         return lod_tgts_seq_next(p, v, pos, false);
752 }
753
754 /**
755  * Show active/inactive status for OST found by lod_osts_seq_next().
756  *
757  * \param[in] m         seq file
758  * \param[in] v         unused for single entry
759  *
760  * \retval 0            on success
761  * \retval negative     error code if failed
762  */
763 static int lod_tgts_seq_show(struct seq_file *p, void *v)
764 {
765         struct obd_device *obd = p->private;
766         struct lu_tgt_desc *tgt = v;
767         struct dt_device *next;
768         int rc, active;
769
770         LASSERT(obd->obd_lu_dev);
771
772         next = tgt->ltd_tgt;
773         if (!next)
774                 return -EINVAL;
775
776         /* XXX: should be non-NULL env, but it's very expensive */
777         active = 1;
778         rc = dt_statfs(NULL, next, &tgt->ltd_statfs);
779         if (rc == -ENOTCONN) {
780                 active = 0;
781                 rc = 0;
782         } else if (rc)
783                 return rc;
784
785         seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
786                    obd_uuid2str(&tgt->ltd_uuid),
787                    active ? "" : "IN");
788         return 0;
789 }
790
791 static const struct seq_operations lod_mdts_sops = {
792         .start  = lod_mdts_seq_start,
793         .stop   = lod_mdts_seq_stop,
794         .next   = lod_mdts_seq_next,
795         .show   = lod_tgts_seq_show,
796 };
797
798 static const struct seq_operations lod_osts_sops = {
799         .start  = lod_osts_seq_start,
800         .stop   = lod_osts_seq_stop,
801         .next   = lod_osts_seq_next,
802         .show   = lod_tgts_seq_show,
803 };
804
805 static int lod_mdts_seq_open(struct inode *inode, struct file *file)
806 {
807         struct seq_file *seq;
808         int rc;
809
810         rc = seq_open(file, &lod_mdts_sops);
811         if (rc)
812                 return rc;
813
814         seq = file->private_data;
815         seq->private = PDE_DATA(inode);
816         return 0;
817 }
818
819 static int lod_osts_seq_open(struct inode *inode, struct file *file)
820 {
821         struct seq_file *seq;
822         int rc;
823
824         rc = seq_open(file, &lod_osts_sops);
825         if (rc)
826                 return rc;
827
828         seq = file->private_data;
829         seq->private = PDE_DATA(inode);
830         return 0;
831 }
832
833 /**
834  * Show whether special failout mode for testing is enabled or not.
835  */
836 static ssize_t lmv_failout_show(struct kobject *kobj, struct attribute *attr,
837                                 char *buf)
838 {
839         struct dt_device *dt = container_of(kobj, struct dt_device,
840                                             dd_kobj);
841         struct lod_device *lod = dt2lod_dev(dt);
842
843         return snprintf(buf, PAGE_SIZE, "%d\n", lod->lod_lmv_failout ? 1 : 0);
844 }
845
846 /**
847  * Enable/disable a special failout mode for testing.
848  *
849  * This determines whether the LMV will try to continue processing a striped
850  * directory even if it has a (partly) corrupted entry in the master directory,
851  * or if it will abort upon finding a corrupted slave directory entry.
852  */
853 static ssize_t lmv_failout_store(struct kobject *kobj, struct attribute *attr,
854                                  const char *buffer, size_t count)
855 {
856         struct dt_device *dt = container_of(kobj, struct dt_device,
857                                             dd_kobj);
858         struct lod_device *lod = dt2lod_dev(dt);
859         bool val = 0;
860         int rc;
861
862         rc = kstrtobool(buffer, &val);
863         if (rc)
864                 return rc;
865
866         lod->lod_lmv_failout = val;
867
868         return count;
869 }
870 LUSTRE_RW_ATTR(lmv_failout);
871
872 static struct lprocfs_vars lprocfs_lod_obd_vars[] = {
873         { NULL }
874 };
875
876 static const struct file_operations lod_proc_mdt_fops = {
877         .owner   = THIS_MODULE,
878         .open    = lod_mdts_seq_open,
879         .read    = seq_read,
880         .llseek  = seq_lseek,
881         .release = lprocfs_seq_release,
882 };
883
884 static const struct file_operations lod_proc_target_fops = {
885         .owner   = THIS_MODULE,
886         .open    = lod_osts_seq_open,
887         .read    = seq_read,
888         .llseek  = seq_lseek,
889         .release = lprocfs_seq_release,
890 };
891
892 static struct attribute *lod_attrs[] = {
893         &lustre_attr_dom_stripesize.attr,
894         &lustre_attr_stripesize.attr,
895         &lustre_attr_stripeoffset.attr,
896         &lustre_attr_stripecount.attr,
897         &lustre_attr_stripetype.attr,
898         &lustre_attr_activeobd.attr,
899         &lustre_attr_desc_uuid.attr,
900         &lustre_attr_lmv_failout.attr,
901         &lustre_attr_numobd.attr,
902         &lustre_attr_qos_maxage.attr,
903         &lustre_attr_qos_prio_free.attr,
904         &lustre_attr_qos_threshold_rr.attr,
905         &lustre_attr_mdt_stripecount.attr,
906         &lustre_attr_mdt_stripetype.attr,
907         &lustre_attr_mdt_activeobd.attr,
908         &lustre_attr_mdt_numobd.attr,
909         &lustre_attr_mdt_qos_maxage.attr,
910         &lustre_attr_mdt_qos_prio_free.attr,
911         &lustre_attr_mdt_qos_threshold_rr.attr,
912         NULL,
913 };
914
915 /**
916  * Initialize procfs entries for LOD.
917  *
918  * \param[in] lod       LOD device
919  *
920  * \retval 0            on success
921  * \retval negative     error code if failed
922  */
923 int lod_procfs_init(struct lod_device *lod)
924 {
925         struct lprocfs_vars ldebugfs_obd_vars[] = { { NULL } };
926         struct obd_device *obd = lod2obd(lod);
927         struct obd_type *type;
928         struct kobject *lov;
929         int rc;
930
931         lod->lod_dt_dev.dd_ktype.default_attrs = lod_attrs;
932         rc = dt_tunables_init(&lod->lod_dt_dev, obd->obd_type, obd->obd_name,
933                               ldebugfs_obd_vars);
934         if (rc) {
935                 CERROR("%s: failed to setup DT tunables: %d\n",
936                        obd->obd_name, rc);
937                 RETURN(rc);
938         }
939
940         obd->obd_vars = lprocfs_lod_obd_vars;
941         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
942                                                obd->obd_type->typ_procroot,
943                                                obd->obd_vars, obd);
944         if (IS_ERR(obd->obd_proc_entry)) {
945                 rc = PTR_ERR(obd->obd_proc_entry);
946                 CERROR("%s: error %d setting up lprocfs\n",
947                        obd->obd_name, rc);
948                 GOTO(out, rc);
949         }
950
951         rc = lprocfs_seq_create(obd->obd_proc_entry, "mdt_obd",
952                                 0444, &lod_proc_mdt_fops, obd);
953         if (rc) {
954                 CWARN("%s: Error adding the target_obd file %d\n",
955                       obd->obd_name, rc);
956                 GOTO(out, rc);
957         }
958
959         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
960                                 0444, &lod_proc_target_fops, obd);
961         if (rc) {
962                 CWARN("%s: Error adding the target_obd file %d\n",
963                       obd->obd_name, rc);
964                 GOTO(out, rc);
965         }
966
967         lod->lod_pool_proc_entry = lprocfs_register("pools",
968                                                     obd->obd_proc_entry,
969                                                     NULL, NULL);
970         if (IS_ERR(lod->lod_pool_proc_entry)) {
971                 rc = PTR_ERR(lod->lod_pool_proc_entry);
972                 lod->lod_pool_proc_entry = NULL;
973                 CWARN("%s: Failed to create pool proc file: %d\n",
974                       obd->obd_name, rc);
975                 GOTO(out, rc);
976         }
977
978         lov = kset_find_obj(lustre_kset, "lov");
979         if (!lov) {
980                 CERROR("%s: lov subsystem not found\n", obd->obd_name);
981                 GOTO(out, rc = -ENODEV);
982         }
983
984         rc = sysfs_create_link(lov, &lod->lod_dt_dev.dd_kobj,
985                                obd->obd_name);
986         if (rc)
987                 CERROR("%s: failed to create LOV sysfs symlink\n",
988                        obd->obd_name);
989         kobject_put(lov);
990
991         lod->lod_debugfs = ldebugfs_add_symlink(obd->obd_name, "lov",
992                                                 "../lod/%s", obd->obd_name);
993         if (!lod->lod_debugfs)
994                 CERROR("%s: failed to create LOV debugfs symlink\n",
995                        obd->obd_name);
996
997         type = container_of(lov, struct obd_type, typ_kobj);
998         if (!type->typ_procroot)
999                 RETURN(0);
1000
1001         /* for compatibility we link old procfs's LOV entries to lod ones */
1002         lod->lod_symlink = lprocfs_add_symlink(obd->obd_name,
1003                                                type->typ_procroot,
1004                                                "../lod/%s", obd->obd_name);
1005         if (lod->lod_symlink == NULL)
1006                 CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n",
1007                        obd->obd_name);
1008         RETURN(0);
1009
1010 out:
1011         dt_tunables_fini(&lod->lod_dt_dev);
1012
1013         return rc;
1014 }
1015
1016 /**
1017  * Cleanup procfs entries registred for LOD.
1018  *
1019  * \param[in] lod       LOD device
1020  */
1021 void lod_procfs_fini(struct lod_device *lod)
1022 {
1023         struct obd_device *obd = lod2obd(lod);
1024         struct kobject *lov;
1025
1026         if (lod->lod_symlink != NULL) {
1027                 lprocfs_remove(&lod->lod_symlink);
1028                 lod->lod_symlink = NULL;
1029         }
1030
1031         lov = kset_find_obj(lustre_kset, "lov");
1032         if (lov) {
1033                 sysfs_remove_link(lov, obd->obd_name);
1034                 kobject_put(lov);
1035         }
1036
1037         debugfs_remove_recursive(lod->lod_debugfs);
1038
1039         if (obd->obd_proc_entry) {
1040                 lprocfs_remove(&obd->obd_proc_entry);
1041                 obd->obd_proc_entry = NULL;
1042         }
1043
1044         dt_tunables_fini(&lod->lod_dt_dev);
1045 }
1046
1047 #endif /* CONFIG_PROC_FS */