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