Whamcloud - gitweb
b93881b63a45350d900d228183ea6983fd0bc749
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_lproc.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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2015, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  *
31  * lustre/osd/osd_lproc.c
32  *
33  * Author: Mikhail Pershin <tappro@sun.com>
34  */
35
36 #define DEBUG_SUBSYSTEM S_OSD
37
38 #include <lprocfs_status.h>
39
40 #include "osd_internal.h"
41
42 void osd_brw_stats_update(struct osd_device *osd, struct osd_iobuf *iobuf)
43 {
44         struct brw_stats *bs = &osd->od_brw_stats;
45         sector_t         *last_block = NULL;
46         struct page     **pages = iobuf->dr_pages;
47         struct page      *last_page = NULL;
48         unsigned long     discont_pages = 0;
49         unsigned long     discont_blocks = 0;
50         sector_t         *blocks = iobuf->dr_blocks;
51         int               i, nr_pages = iobuf->dr_npages;
52         int               blocks_per_page;
53         int               rw = iobuf->dr_rw;
54
55         if (unlikely(nr_pages == 0))
56                 return;
57
58         blocks_per_page = PAGE_SIZE >> osd_sb(osd)->s_blocksize_bits;
59
60         lprocfs_oh_tally_log2_pcpu(&bs->bs_hist[BRW_R_PAGES + rw], nr_pages);
61
62         while (nr_pages-- > 0) {
63                 if (last_page && (*pages)->index != (last_page->index + 1))
64                         discont_pages++;
65                 last_page = *pages;
66                 pages++;
67                 for (i = 0; i < blocks_per_page; i++) {
68                         if (last_block && *blocks != (*last_block + 1))
69                                 discont_blocks++;
70                         last_block = blocks++;
71                 }
72         }
73
74         lprocfs_oh_tally_pcpu(&bs->bs_hist[BRW_R_DISCONT_PAGES+rw],
75                               discont_pages);
76         lprocfs_oh_tally_pcpu(&bs->bs_hist[BRW_R_DISCONT_BLOCKS+rw],
77                               discont_blocks);
78 }
79
80 static int osd_stats_init(struct osd_device *osd)
81 {
82         int result = -ENOMEM;
83
84         ENTRY;
85         osd->od_stats = lprocfs_alloc_stats(LPROC_OSD_LAST, 0);
86         if (osd->od_stats) {
87                 lprocfs_counter_init(osd->od_stats, LPROC_OSD_GET_PAGE,
88                                      LPROCFS_CNTR_AVGMINMAX|LPROCFS_CNTR_STDDEV,
89                                      "get_page", "usec");
90                 lprocfs_counter_init(osd->od_stats, LPROC_OSD_NO_PAGE,
91                                      LPROCFS_CNTR_AVGMINMAX,
92                                      "get_page_failures", "num");
93                 lprocfs_counter_init(osd->od_stats, LPROC_OSD_CACHE_ACCESS,
94                                      LPROCFS_CNTR_AVGMINMAX,
95                                      "cache_access", "pages");
96                 lprocfs_counter_init(osd->od_stats, LPROC_OSD_CACHE_HIT,
97                                      LPROCFS_CNTR_AVGMINMAX,
98                                      "cache_hit", "pages");
99                 lprocfs_counter_init(osd->od_stats, LPROC_OSD_CACHE_MISS,
100                                      LPROCFS_CNTR_AVGMINMAX,
101                                      "cache_miss", "pages");
102 #if OSD_THANDLE_STATS
103                 lprocfs_counter_init(osd->od_stats, LPROC_OSD_THANDLE_STARTING,
104                                      LPROCFS_CNTR_AVGMINMAX,
105                                      "thandle starting", "usec");
106                 lprocfs_counter_init(osd->od_stats, LPROC_OSD_THANDLE_OPEN,
107                                      LPROCFS_CNTR_AVGMINMAX,
108                                      "thandle open", "usec");
109                 lprocfs_counter_init(osd->od_stats, LPROC_OSD_THANDLE_CLOSING,
110                                      LPROCFS_CNTR_AVGMINMAX,
111                                      "thandle closing", "usec");
112 #endif
113                 result = 0;
114         }
115
116         ldebugfs_register_osd_stats(osd->od_dt_dev.dd_debugfs_entry,
117                                     &osd->od_brw_stats, osd->od_stats);
118
119         RETURN(result);
120 }
121
122 static ssize_t fstype_show(struct kobject *kobj, struct attribute *attr,
123                            char *buf)
124 {
125         return sprintf(buf, "ldiskfs\n");
126 }
127 LUSTRE_RO_ATTR(fstype);
128
129 static ssize_t mntdev_show(struct kobject *kobj, struct attribute *attr,
130                            char *buf)
131 {
132         struct dt_device *dt = container_of(kobj, struct dt_device,
133                                             dd_kobj);
134         struct osd_device *osd = osd_dt_dev(dt);
135
136         LASSERT(osd);
137         if (unlikely(!osd->od_mnt))
138                 return -EINPROGRESS;
139
140         return sprintf(buf, "%s\n", osd->od_mntdev);
141 }
142 LUSTRE_RO_ATTR(mntdev);
143
144 static ssize_t read_cache_enable_show(struct kobject *kobj,
145                                       struct attribute *attr,
146                                       char *buf)
147 {
148         struct dt_device *dt = container_of(kobj, struct dt_device,
149                                             dd_kobj);
150         struct osd_device *osd = osd_dt_dev(dt);
151
152         LASSERT(osd);
153         if (unlikely(!osd->od_mnt))
154                 return -EINPROGRESS;
155
156         return sprintf(buf, "%u\n", osd->od_read_cache);
157 }
158
159 static ssize_t read_cache_enable_store(struct kobject *kobj,
160                                        struct attribute *attr,
161                                        const char *buffer, size_t count)
162 {
163         struct dt_device *dt = container_of(kobj, struct dt_device,
164                                             dd_kobj);
165         struct osd_device *osd = osd_dt_dev(dt);
166         bool val;
167         int rc;
168
169         LASSERT(osd);
170         if (unlikely(!osd->od_mnt))
171                 return -EINPROGRESS;
172
173         rc = kstrtobool(buffer, &val);
174         if (rc)
175                 return rc;
176
177         osd->od_read_cache = !!val;
178         return count;
179 }
180 LUSTRE_RW_ATTR(read_cache_enable);
181
182 static ssize_t writethrough_cache_enable_show(struct kobject *kobj,
183                                               struct attribute *attr,
184                                               char *buf)
185 {
186         struct dt_device *dt = container_of(kobj, struct dt_device,
187                                             dd_kobj);
188         struct osd_device *osd = osd_dt_dev(dt);
189
190         LASSERT(osd);
191         if (unlikely(!osd->od_mnt))
192                 return -EINPROGRESS;
193
194         return sprintf(buf, "%u\n", osd->od_writethrough_cache);
195 }
196
197 static ssize_t writethrough_cache_enable_store(struct kobject *kobj,
198                                                struct attribute *attr,
199                                                const char *buffer,
200                                                size_t count)
201 {
202         struct dt_device *dt = container_of(kobj, struct dt_device,
203                                             dd_kobj);
204         struct osd_device *osd = osd_dt_dev(dt);
205         bool val;
206         int rc;
207
208         LASSERT(osd);
209         if (unlikely(!osd->od_mnt))
210                 return -EINPROGRESS;
211
212         rc = kstrtobool(buffer, &val);
213         if (rc)
214                 return rc;
215
216         osd->od_writethrough_cache = !!val;
217         return count;
218 }
219 LUSTRE_RW_ATTR(writethrough_cache_enable);
220
221 static ssize_t enable_projid_xattr_show(struct kobject *kobj,
222                                         struct attribute *attr,
223                                         char *buf)
224 {
225         struct dt_device *dt = container_of(kobj, struct dt_device,
226                                             dd_kobj);
227         struct osd_device *osd = osd_dt_dev(dt);
228
229         LASSERT(osd);
230         if (unlikely(!osd->od_mnt))
231                 return -EINPROGRESS;
232
233         return snprintf(buf, PAGE_SIZE, "%u\n", osd->od_enable_projid_xattr);
234 }
235
236 static ssize_t enable_projid_xattr_store(struct kobject *kobj,
237                                         struct attribute *attr,
238                                         const char *buffer,
239                                         size_t count)
240 {
241         struct dt_device *dt = container_of(kobj, struct dt_device,
242                                             dd_kobj);
243         struct osd_device *osd = osd_dt_dev(dt);
244         bool val;
245         int rc;
246
247         LASSERT(osd);
248         if (unlikely(!osd->od_mnt))
249                 return -EINPROGRESS;
250
251         rc = kstrtobool(buffer, &val);
252         if (rc)
253                 return rc;
254
255         osd->od_enable_projid_xattr = !!val;
256         return count;
257 }
258 LUSTRE_RW_ATTR(enable_projid_xattr);
259
260 static ssize_t fallocate_zero_blocks_show(struct kobject *kobj,
261                                           struct attribute *attr,
262                                           char *buf)
263 {
264         struct dt_device *dt = container_of(kobj, struct dt_device,
265                                             dd_kobj);
266         struct osd_device *osd = osd_dt_dev(dt);
267
268         LASSERT(osd);
269         if (unlikely(!osd->od_mnt))
270                 return -EINPROGRESS;
271
272         return scnprintf(buf, PAGE_SIZE, "%d\n", osd->od_fallocate_zero_blocks);
273 }
274
275 /*
276  * Set how fallocate() interacts with the backing filesystem:
277  * -1: fallocate is disabled and returns -EOPNOTSUPP
278  *  0: fallocate allocates unwritten extents (like ext4)
279  *  1: fallocate zeroes allocated extents on disk
280  */
281 static ssize_t fallocate_zero_blocks_store(struct kobject *kobj,
282                                            struct attribute *attr,
283                                            const char *buffer, size_t count)
284 {
285         struct dt_device *dt = container_of(kobj, struct dt_device,
286                                             dd_kobj);
287         struct osd_device *osd = osd_dt_dev(dt);
288         long val;
289         int rc;
290
291         LASSERT(osd);
292         if (unlikely(!osd->od_mnt))
293                 return -EINPROGRESS;
294
295         rc = kstrtol(buffer, 0, &val);
296         if (rc)
297                 return rc;
298
299         if (val < -1 || val > 1)
300                 return -EINVAL;
301
302         osd->od_fallocate_zero_blocks = val;
303         return count;
304 }
305 LUSTRE_RW_ATTR(fallocate_zero_blocks);
306
307 ssize_t force_sync_store(struct kobject *kobj, struct attribute *attr,
308                          const char *buffer, size_t count)
309 {
310         struct dt_device *dt = container_of(kobj, struct dt_device,
311                                             dd_kobj);
312         struct osd_device *osd = osd_dt_dev(dt);
313         struct lu_env env;
314         int rc;
315
316         LASSERT(osd);
317         if (unlikely(!osd->od_mnt))
318                 return -EINPROGRESS;
319
320         rc = lu_env_init(&env, LCT_LOCAL);
321         if (rc)
322                 return rc;
323
324         rc = dt_sync(&env, dt);
325         lu_env_fini(&env);
326
327         return rc == 0 ? count : rc;
328 }
329 LUSTRE_WO_ATTR(force_sync);
330
331 static ssize_t nonrotational_show(struct kobject *kobj, struct attribute *attr,
332                                   char *buf)
333 {
334         struct dt_device *dt = container_of(kobj, struct dt_device,
335                                             dd_kobj);
336         struct osd_device *osd = osd_dt_dev(dt);
337
338         LASSERT(osd);
339         if (unlikely(!osd->od_mnt))
340                 return -EINPROGRESS;
341
342         return sprintf(buf, "%u\n", osd->od_nonrotational);
343 }
344
345 static ssize_t nonrotational_store(struct kobject *kobj,
346                                    struct attribute *attr, const char *buffer,
347                                    size_t count)
348 {
349         struct dt_device *dt = container_of(kobj, struct dt_device,
350                                             dd_kobj);
351         struct osd_device *osd = osd_dt_dev(dt);
352         bool val;
353         int rc;
354
355         LASSERT(osd);
356         if (unlikely(!osd->od_mnt))
357                 return -EINPROGRESS;
358
359         rc = kstrtobool(buffer, &val);
360         if (rc)
361                 return rc;
362
363         osd->od_nonrotational = val;
364         return count;
365 }
366 LUSTRE_RW_ATTR(nonrotational);
367
368 static ssize_t pdo_show(struct kobject *kobj, struct attribute *attr,
369                         char *buf)
370 {
371         return sprintf(buf, "%s\n", ldiskfs_pdo ? "ON" : "OFF");
372 }
373
374 static ssize_t pdo_store(struct kobject *kobj, struct attribute *attr,
375                          const char *buffer, size_t count)
376 {
377         bool pdo;
378         int rc;
379
380         rc = kstrtobool(buffer, &pdo);
381         if (rc != 0)
382                 return rc;
383
384         ldiskfs_pdo = pdo;
385
386         return count;
387 }
388 LUSTRE_RW_ATTR(pdo);
389
390 static ssize_t auto_scrub_show(struct kobject *kobj, struct attribute *attr,
391                                char *buf)
392 {
393         struct dt_device *dt = container_of(kobj, struct dt_device,
394                                             dd_kobj);
395         struct osd_device *dev = osd_dt_dev(dt);
396
397         LASSERT(dev);
398         if (unlikely(!dev->od_mnt))
399                 return -EINPROGRESS;
400
401         return scnprintf(buf, PAGE_SIZE, "%lld\n",
402                          dev->od_scrub.os_scrub.os_auto_scrub_interval);
403 }
404
405 static ssize_t auto_scrub_store(struct kobject *kobj, struct attribute *attr,
406                                 const char *buffer, size_t count)
407 {
408         struct dt_device *dt = container_of(kobj, struct dt_device,
409                                             dd_kobj);
410         struct osd_device *dev = osd_dt_dev(dt);
411         s64 val;
412         int rc;
413
414         LASSERT(dev);
415         if (unlikely(!dev->od_mnt))
416                 return -EINPROGRESS;
417
418         rc = kstrtoll(buffer, 0, &val);
419         if (rc)
420                 return rc;
421
422         dev->od_scrub.os_scrub.os_auto_scrub_interval = val;
423         return count;
424 }
425 LUSTRE_RW_ATTR(auto_scrub);
426
427 static ssize_t full_scrub_ratio_show(struct kobject *kobj,
428                                      struct attribute *attr,
429                                      char *buf)
430 {
431         struct dt_device *dt = container_of(kobj, struct dt_device,
432                                             dd_kobj);
433         struct osd_device *dev = osd_dt_dev(dt);
434
435         LASSERT(dev);
436         if (unlikely(!dev->od_mnt))
437                 return -EINPROGRESS;
438
439         return sprintf(buf, "%llu\n", dev->od_full_scrub_ratio);
440 }
441
442 static ssize_t full_scrub_ratio_store(struct kobject *kobj,
443                                       struct attribute *attr,
444                                       const char *buffer, size_t count)
445 {
446         struct dt_device *dt = container_of(kobj, struct dt_device,
447                                             dd_kobj);
448         struct osd_device *dev = osd_dt_dev(dt);
449         s64 val;
450         int rc;
451
452         LASSERT(dev);
453         if (unlikely(!dev->od_mnt))
454                 return -EINPROGRESS;
455
456         rc = kstrtoll(buffer, 0, &val);
457         if (rc)
458                 return rc;
459
460         if (val < 0)
461                 return -EINVAL;
462
463         dev->od_full_scrub_ratio = val;
464         return count;
465 }
466 LUSTRE_RW_ATTR(full_scrub_ratio);
467
468 static ssize_t full_scrub_threshold_rate_show(struct kobject *kobj,
469                                               struct attribute *attr,
470                                               char *buf)
471 {
472         struct dt_device *dt = container_of(kobj, struct dt_device,
473                                             dd_kobj);
474         struct osd_device *dev = osd_dt_dev(dt);
475
476         LASSERT(dev);
477         if (unlikely(!dev->od_mnt))
478                 return -EINPROGRESS;
479
480         return sprintf(buf, "%llu (bad OI mappings/minute)\n",
481                        dev->od_full_scrub_threshold_rate);
482 }
483
484 static ssize_t full_scrub_threshold_rate_store(struct kobject *kobj,
485                                                struct attribute *attr,
486                                                const char *buffer, size_t count)
487 {
488         struct dt_device *dt = container_of(kobj, struct dt_device,
489                                             dd_kobj);
490         struct osd_device *dev = osd_dt_dev(dt);
491         u64 val;
492         int rc;
493
494         LASSERT(dev);
495         if (unlikely(!dev->od_mnt))
496                 return -EINPROGRESS;
497
498         rc = kstrtoull(buffer, 0, &val);
499         if (rc != 0)
500                 return rc;
501
502         dev->od_full_scrub_threshold_rate = val;
503         return count;
504 }
505 LUSTRE_RW_ATTR(full_scrub_threshold_rate);
506
507 static ssize_t extent_bytes_allocation_show(struct kobject *kobj,
508                                             struct attribute *attr, char *buf)
509 {
510         struct dt_device *dt = container_of(kobj, struct dt_device,
511                                             dd_kobj);
512         struct osd_device *dev = osd_dt_dev(dt);
513         int i;
514         unsigned int min = (unsigned int)(~0), cur;
515
516         for_each_online_cpu(i) {
517                 cur = *per_cpu_ptr(dev->od_extent_bytes_percpu, i);
518                 if (cur < min)
519                         min = cur;
520         }
521         return snprintf(buf, PAGE_SIZE, "%u\n", min);
522 }
523 LUSTRE_RO_ATTR(extent_bytes_allocation);
524
525 static int ldiskfs_osd_oi_scrub_seq_show(struct seq_file *m, void *data)
526 {
527         struct osd_device *dev = osd_dt_dev((struct dt_device *)m->private);
528
529         LASSERT(dev != NULL);
530         if (unlikely(dev->od_mnt == NULL))
531                 return -EINPROGRESS;
532
533         osd_scrub_dump(m, dev);
534         return 0;
535 }
536
537 LDEBUGFS_SEQ_FOPS_RO(ldiskfs_osd_oi_scrub);
538
539 static int ldiskfs_osd_readcache_seq_show(struct seq_file *m, void *data)
540 {
541         struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
542
543         LASSERT(osd != NULL);
544         if (unlikely(osd->od_mnt == NULL))
545                 return -EINPROGRESS;
546
547         seq_printf(m, "%llu\n", osd->od_readcache_max_filesize);
548         return 0;
549 }
550
551 static ssize_t
552 ldiskfs_osd_readcache_seq_write(struct file *file, const char __user *buffer,
553                                 size_t count, loff_t *off)
554 {
555         struct seq_file *m = file->private_data;
556         struct dt_device *dt = m->private;
557         struct osd_device *osd = osd_dt_dev(dt);
558         char kernbuf[22] = "";
559         u64 val;
560         int rc;
561
562         LASSERT(osd != NULL);
563         if (unlikely(osd->od_mnt == NULL))
564                 return -EINPROGRESS;
565
566         if (count >= sizeof(kernbuf))
567                 return -EINVAL;
568
569         if (copy_from_user(kernbuf, buffer, count))
570                 return -EFAULT;
571         kernbuf[count] = 0;
572
573         rc = sysfs_memparse(kernbuf, count, &val, "B");
574         if (rc < 0)
575                 return rc;
576
577         osd->od_readcache_max_filesize = val > OSD_MAX_CACHE_SIZE ?
578                                          OSD_MAX_CACHE_SIZE : val;
579         return count;
580 }
581
582 LDEBUGFS_SEQ_FOPS(ldiskfs_osd_readcache);
583
584 static int ldiskfs_osd_readcache_max_io_seq_show(struct seq_file *m, void *data)
585 {
586         struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
587
588         LASSERT(osd != NULL);
589         if (unlikely(osd->od_mnt == NULL))
590                 return -EINPROGRESS;
591
592         seq_printf(m, "%lu\n", osd->od_readcache_max_iosize >> 20);
593         return 0;
594 }
595
596 static ssize_t
597 ldiskfs_osd_readcache_max_io_seq_write(struct file *file,
598                                        const char __user *buffer,
599                                        size_t count, loff_t *off)
600 {
601         struct seq_file *m = file->private_data;
602         struct dt_device *dt = m->private;
603         struct osd_device *osd = osd_dt_dev(dt);
604         char kernbuf[22] = "";
605         u64 val;
606         int rc;
607
608         LASSERT(osd != NULL);
609         if (unlikely(osd->od_mnt == NULL))
610                 return -EINPROGRESS;
611
612         if (count >= sizeof(kernbuf))
613                 return -EINVAL;
614
615         if (copy_from_user(kernbuf, buffer, count))
616                 return -EFAULT;
617         kernbuf[count] = 0;
618
619         rc = sysfs_memparse(kernbuf, count, &val, "MiB");
620         if (rc < 0)
621                 return rc;
622
623         if (val > PTLRPC_MAX_BRW_SIZE)
624                 return -ERANGE;
625         osd->od_readcache_max_iosize = val;
626         return count;
627 }
628
629 LDEBUGFS_SEQ_FOPS(ldiskfs_osd_readcache_max_io);
630
631 static int ldiskfs_osd_writethrough_max_io_seq_show(struct seq_file *m,
632                                                     void *data)
633 {
634         struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
635
636         LASSERT(osd != NULL);
637         if (unlikely(osd->od_mnt == NULL))
638                 return -EINPROGRESS;
639
640         seq_printf(m, "%lu\n", osd->od_writethrough_max_iosize >> 20);
641         return 0;
642 }
643
644 static ssize_t
645 ldiskfs_osd_writethrough_max_io_seq_write(struct file *file,
646                                        const char __user *buffer,
647                                        size_t count, loff_t *off)
648 {
649         struct seq_file *m = file->private_data;
650         struct dt_device *dt = m->private;
651         struct osd_device *osd = osd_dt_dev(dt);
652         char kernbuf[22] = "";
653         u64 val;
654         int rc;
655
656         LASSERT(osd != NULL);
657         if (unlikely(osd->od_mnt == NULL))
658                 return -EINPROGRESS;
659
660         if (count >= sizeof(kernbuf))
661                 return -EINVAL;
662
663         if (copy_from_user(kernbuf, buffer, count))
664                 return -EFAULT;
665         kernbuf[count] = 0;
666
667         rc = sysfs_memparse(kernbuf, count, &val, "MiB");
668         if (rc < 0)
669                 return rc;
670
671         if (val > PTLRPC_MAX_BRW_SIZE)
672                 return -ERANGE;
673         osd->od_writethrough_max_iosize = val;
674         return count;
675 }
676
677 LDEBUGFS_SEQ_FOPS(ldiskfs_osd_writethrough_max_io);
678
679 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 52, 0)
680 static ssize_t index_in_idif_show(struct kobject *kobj, struct attribute *attr,
681                                   char *buf)
682 {
683         struct dt_device *dt = container_of(kobj, struct dt_device,
684                                             dd_kobj);
685         struct osd_device *dev = osd_dt_dev(dt);
686
687         LASSERT(dev);
688         if (unlikely(!dev->od_mnt))
689                 return -EINPROGRESS;
690
691         return sprintf(buf, "%d\n", (int)(dev->od_index_in_idif));
692 }
693
694 static ssize_t index_in_idif_store(struct kobject *kobj,
695                                    struct attribute *attr,
696                                    const char *buffer, size_t count)
697 {
698         struct dt_device *dt = container_of(kobj, struct dt_device,
699                                             dd_kobj);
700         struct osd_device *dev = osd_dt_dev(dt);
701         struct lu_target *tgt;
702         struct lu_env env;
703         bool val;
704         int rc;
705
706         LASSERT(dev);
707         if (unlikely(!dev->od_mnt))
708                 return -EINPROGRESS;
709
710         rc = kstrtobool(buffer, &val);
711         if (rc)
712                 return rc;
713
714         if (dev->od_index_in_idif) {
715                 if (val)
716                         return count;
717
718                 LCONSOLE_WARN("%s: OST-index in IDIF has been enabled, "
719                               "it cannot be reverted back.\n", osd_name(dev));
720                 return -EPERM;
721         }
722
723         if (!val)
724                 return count;
725
726         rc = lu_env_init(&env, LCT_DT_THREAD);
727         if (rc)
728                 return rc;
729
730         tgt = dev->od_dt_dev.dd_lu_dev.ld_site->ls_tgt;
731         tgt->lut_lsd.lsd_feature_rocompat |= OBD_ROCOMPAT_IDX_IN_IDIF;
732         rc = tgt_server_data_update(&env, tgt, 1);
733         lu_env_fini(&env);
734         if (rc < 0)
735                 return rc;
736
737         LCONSOLE_INFO("%s: enable OST-index in IDIF successfully, "
738                       "it cannot be reverted back.\n", osd_name(dev));
739
740         dev->od_index_in_idif = 1;
741         return count;
742 }
743 LUSTRE_RW_ATTR(index_in_idif);
744
745 int osd_register_proc_index_in_idif(struct osd_device *osd)
746 {
747         struct dt_device *dt = &osd->od_dt_dev;
748
749         return sysfs_create_file(&dt->dd_kobj, &lustre_attr_index_in_idif.attr);
750 }
751 #endif
752
753 static ssize_t index_backup_show(struct kobject *kobj, struct attribute *attr,
754                                  char *buf)
755 {
756         struct dt_device *dt = container_of(kobj, struct dt_device,
757                                             dd_kobj);
758         struct osd_device *dev = osd_dt_dev(dt);
759
760         LASSERT(dev);
761         if (unlikely(!dev->od_mnt))
762                 return -EINPROGRESS;
763
764         return sprintf(buf, "%d\n", dev->od_index_backup_policy);
765 }
766
767 ssize_t index_backup_store(struct kobject *kobj, struct attribute *attr,
768                            const char *buffer, size_t count)
769 {
770         struct dt_device *dt = container_of(kobj, struct dt_device,
771                                            dd_kobj);
772         struct osd_device *dev = osd_dt_dev(dt);
773         int val;
774         int rc;
775
776         LASSERT(dev);
777         if (unlikely(!dev->od_mnt))
778                 return -EINPROGRESS;
779
780         rc = kstrtoint(buffer, 0, &val);
781         if (rc)
782                 return rc;
783
784         dev->od_index_backup_policy = val;
785         return count;
786 }
787 LUSTRE_RW_ATTR(index_backup);
788
789 struct ldebugfs_vars ldebugfs_osd_obd_vars[] = {
790         { .name =       "oi_scrub",
791           .fops =       &ldiskfs_osd_oi_scrub_fops      },
792         { .name =       "readcache_max_filesize",
793           .fops =       &ldiskfs_osd_readcache_fops     },
794         { .name =       "readcache_max_io_mb",
795           .fops =       &ldiskfs_osd_readcache_max_io_fops      },
796         { .name =       "writethrough_max_io_mb",
797           .fops =       &ldiskfs_osd_writethrough_max_io_fops   },
798         { NULL }
799 };
800
801 static struct attribute *ldiskfs_attrs[] = {
802         &lustre_attr_read_cache_enable.attr,
803         &lustre_attr_writethrough_cache_enable.attr,
804         &lustre_attr_enable_projid_xattr.attr,
805         &lustre_attr_fstype.attr,
806         &lustre_attr_mntdev.attr,
807         &lustre_attr_fallocate_zero_blocks.attr,
808         &lustre_attr_force_sync.attr,
809         &lustre_attr_nonrotational.attr,
810         &lustre_attr_index_backup.attr,
811         &lustre_attr_auto_scrub.attr,
812         &lustre_attr_pdo.attr,
813         &lustre_attr_full_scrub_ratio.attr,
814         &lustre_attr_full_scrub_threshold_rate.attr,
815         &lustre_attr_extent_bytes_allocation.attr,
816         NULL,
817 };
818
819 int osd_procfs_init(struct osd_device *osd, const char *name)
820 {
821         struct obd_type *type;
822         int rc;
823
824         ENTRY;
825
826         /* at the moment there is no linkage between lu_type
827          * and obd_type, so we lookup obd_type this way
828          */
829         type = class_search_type(LUSTRE_OSD_LDISKFS_NAME);
830
831         LASSERT(name);
832         LASSERT(type);
833
834         CDEBUG(D_CONFIG, "%s: register osd-ldiskfs tunable parameters\n", name);
835
836         /* put reference taken by class_search_type */
837         kobject_put(&type->typ_kobj);
838
839         osd->od_dt_dev.dd_ktype.default_attrs = ldiskfs_attrs;
840         rc = dt_tunables_init(&osd->od_dt_dev, type, name,
841                               ldebugfs_osd_obd_vars);
842         if (rc) {
843                 CERROR("%s: cannot setup sysfs / debugfs entry: %d\n",
844                        name, rc);
845                 GOTO(out, rc);
846         }
847
848         if (osd->od_proc_entry)
849                 RETURN(0);
850
851         /* Find the type procroot and add the proc entry for this device */
852         osd->od_proc_entry = lprocfs_register(name, type->typ_procroot,
853                                               NULL, &osd->od_dt_dev);
854         if (IS_ERR(osd->od_proc_entry)) {
855                 rc = PTR_ERR(osd->od_proc_entry);
856                 CERROR("Error %d setting up lprocfs for %s\n",
857                        rc, name);
858                 osd->od_proc_entry = NULL;
859                 GOTO(out, rc);
860         }
861
862         rc = osd_stats_init(osd);
863
864         EXIT;
865 out:
866         if (rc)
867                 osd_procfs_fini(osd);
868         return rc;
869 }
870
871 int osd_procfs_fini(struct osd_device *osd)
872 {
873         lprocfs_fini_brw_stats(&osd->od_brw_stats);
874
875         if (osd->od_stats)
876                 lprocfs_free_stats(&osd->od_stats);
877
878         if (osd->od_proc_entry)
879                 lprocfs_remove(&osd->od_proc_entry);
880
881         return dt_tunables_fini(&osd->od_dt_dev);
882 }