Whamcloud - gitweb
LU-13799 llite: Implement lower/upper aio
[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 fallocate_zero_blocks_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 scnprintf(buf, PAGE_SIZE, "%d\n", osd->od_fallocate_zero_blocks);
234 }
235
236 /*
237  * Set how fallocate() interacts with the backing filesystem:
238  * -1: fallocate is disabled and returns -EOPNOTSUPP
239  *  0: fallocate allocates unwritten extents (like ext4)
240  *  1: fallocate zeroes allocated extents on disk
241  */
242 static ssize_t fallocate_zero_blocks_store(struct kobject *kobj,
243                                            struct attribute *attr,
244                                            const char *buffer, size_t count)
245 {
246         struct dt_device *dt = container_of(kobj, struct dt_device,
247                                             dd_kobj);
248         struct osd_device *osd = osd_dt_dev(dt);
249         long val;
250         int rc;
251
252         LASSERT(osd);
253         if (unlikely(!osd->od_mnt))
254                 return -EINPROGRESS;
255
256         rc = kstrtol(buffer, 0, &val);
257         if (rc)
258                 return rc;
259
260         if (val < -1 || val > 1)
261                 return -EINVAL;
262
263         osd->od_fallocate_zero_blocks = val;
264         return count;
265 }
266 LUSTRE_RW_ATTR(fallocate_zero_blocks);
267
268 ssize_t force_sync_store(struct kobject *kobj, struct attribute *attr,
269                          const char *buffer, size_t count)
270 {
271         struct dt_device *dt = container_of(kobj, struct dt_device,
272                                             dd_kobj);
273         struct osd_device *osd = osd_dt_dev(dt);
274         struct lu_env env;
275         int rc;
276
277         LASSERT(osd);
278         if (unlikely(!osd->od_mnt))
279                 return -EINPROGRESS;
280
281         rc = lu_env_init(&env, LCT_LOCAL);
282         if (rc)
283                 return rc;
284
285         rc = dt_sync(&env, dt);
286         lu_env_fini(&env);
287
288         return rc == 0 ? count : rc;
289 }
290 LUSTRE_WO_ATTR(force_sync);
291
292 static ssize_t nonrotational_show(struct kobject *kobj, struct attribute *attr,
293                                   char *buf)
294 {
295         struct dt_device *dt = container_of(kobj, struct dt_device,
296                                             dd_kobj);
297         struct osd_device *osd = osd_dt_dev(dt);
298
299         LASSERT(osd);
300         if (unlikely(!osd->od_mnt))
301                 return -EINPROGRESS;
302
303         return sprintf(buf, "%u\n", osd->od_nonrotational);
304 }
305
306 static ssize_t nonrotational_store(struct kobject *kobj,
307                                    struct attribute *attr, const char *buffer,
308                                    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         bool val;
314         int rc;
315
316         LASSERT(osd);
317         if (unlikely(!osd->od_mnt))
318                 return -EINPROGRESS;
319
320         rc = kstrtobool(buffer, &val);
321         if (rc)
322                 return rc;
323
324         osd->od_nonrotational = val;
325         return count;
326 }
327 LUSTRE_RW_ATTR(nonrotational);
328
329 static ssize_t pdo_show(struct kobject *kobj, struct attribute *attr,
330                         char *buf)
331 {
332         return sprintf(buf, "%s\n", ldiskfs_pdo ? "ON" : "OFF");
333 }
334
335 static ssize_t pdo_store(struct kobject *kobj, struct attribute *attr,
336                          const char *buffer, size_t count)
337 {
338         bool pdo;
339         int rc;
340
341         rc = kstrtobool(buffer, &pdo);
342         if (rc != 0)
343                 return rc;
344
345         ldiskfs_pdo = pdo;
346
347         return count;
348 }
349 LUSTRE_RW_ATTR(pdo);
350
351 static ssize_t auto_scrub_show(struct kobject *kobj, struct attribute *attr,
352                                char *buf)
353 {
354         struct dt_device *dt = container_of(kobj, struct dt_device,
355                                             dd_kobj);
356         struct osd_device *dev = osd_dt_dev(dt);
357
358         LASSERT(dev);
359         if (unlikely(!dev->od_mnt))
360                 return -EINPROGRESS;
361
362         return scnprintf(buf, PAGE_SIZE, "%lld\n",
363                          dev->od_scrub.os_scrub.os_auto_scrub_interval);
364 }
365
366 static ssize_t auto_scrub_store(struct kobject *kobj, struct attribute *attr,
367                                 const char *buffer, size_t count)
368 {
369         struct dt_device *dt = container_of(kobj, struct dt_device,
370                                             dd_kobj);
371         struct osd_device *dev = osd_dt_dev(dt);
372         s64 val;
373         int rc;
374
375         LASSERT(dev);
376         if (unlikely(!dev->od_mnt))
377                 return -EINPROGRESS;
378
379         rc = kstrtoll(buffer, 0, &val);
380         if (rc)
381                 return rc;
382
383         dev->od_scrub.os_scrub.os_auto_scrub_interval = val;
384         return count;
385 }
386 LUSTRE_RW_ATTR(auto_scrub);
387
388 static ssize_t full_scrub_ratio_show(struct kobject *kobj,
389                                      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 sprintf(buf, "%llu\n", dev->od_full_scrub_ratio);
401 }
402
403 static ssize_t full_scrub_ratio_store(struct kobject *kobj,
404                                       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         if (val < 0)
422                 return -EINVAL;
423
424         dev->od_full_scrub_ratio = val;
425         return count;
426 }
427 LUSTRE_RW_ATTR(full_scrub_ratio);
428
429 static ssize_t full_scrub_threshold_rate_show(struct kobject *kobj,
430                                               struct attribute *attr,
431                                               char *buf)
432 {
433         struct dt_device *dt = container_of(kobj, struct dt_device,
434                                             dd_kobj);
435         struct osd_device *dev = osd_dt_dev(dt);
436
437         LASSERT(dev);
438         if (unlikely(!dev->od_mnt))
439                 return -EINPROGRESS;
440
441         return sprintf(buf, "%llu (bad OI mappings/minute)\n",
442                        dev->od_full_scrub_threshold_rate);
443 }
444
445 static ssize_t full_scrub_threshold_rate_store(struct kobject *kobj,
446                                                struct attribute *attr,
447                                                const char *buffer, size_t count)
448 {
449         struct dt_device *dt = container_of(kobj, struct dt_device,
450                                             dd_kobj);
451         struct osd_device *dev = osd_dt_dev(dt);
452         u64 val;
453         int rc;
454
455         LASSERT(dev);
456         if (unlikely(!dev->od_mnt))
457                 return -EINPROGRESS;
458
459         rc = kstrtoull(buffer, 0, &val);
460         if (rc != 0)
461                 return rc;
462
463         dev->od_full_scrub_threshold_rate = val;
464         return count;
465 }
466 LUSTRE_RW_ATTR(full_scrub_threshold_rate);
467
468 static ssize_t extent_bytes_allocation_show(struct kobject *kobj,
469                                             struct attribute *attr, 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         int i;
475         unsigned int min = (unsigned int)(~0), cur;
476
477         for_each_online_cpu(i) {
478                 cur = *per_cpu_ptr(dev->od_extent_bytes_percpu, i);
479                 if (cur < min)
480                         min = cur;
481         }
482         return snprintf(buf, PAGE_SIZE, "%u\n", min);
483 }
484 LUSTRE_RO_ATTR(extent_bytes_allocation);
485
486 static int ldiskfs_osd_oi_scrub_seq_show(struct seq_file *m, void *data)
487 {
488         struct osd_device *dev = osd_dt_dev((struct dt_device *)m->private);
489
490         LASSERT(dev != NULL);
491         if (unlikely(dev->od_mnt == NULL))
492                 return -EINPROGRESS;
493
494         osd_scrub_dump(m, dev);
495         return 0;
496 }
497
498 LDEBUGFS_SEQ_FOPS_RO(ldiskfs_osd_oi_scrub);
499
500 static int ldiskfs_osd_readcache_seq_show(struct seq_file *m, void *data)
501 {
502         struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
503
504         LASSERT(osd != NULL);
505         if (unlikely(osd->od_mnt == NULL))
506                 return -EINPROGRESS;
507
508         seq_printf(m, "%llu\n", osd->od_readcache_max_filesize);
509         return 0;
510 }
511
512 static ssize_t
513 ldiskfs_osd_readcache_seq_write(struct file *file, const char __user *buffer,
514                                 size_t count, loff_t *off)
515 {
516         struct seq_file *m = file->private_data;
517         struct dt_device *dt = m->private;
518         struct osd_device *osd = osd_dt_dev(dt);
519         char kernbuf[22] = "";
520         u64 val;
521         int rc;
522
523         LASSERT(osd != NULL);
524         if (unlikely(osd->od_mnt == NULL))
525                 return -EINPROGRESS;
526
527         if (count >= sizeof(kernbuf))
528                 return -EINVAL;
529
530         if (copy_from_user(kernbuf, buffer, count))
531                 return -EFAULT;
532         kernbuf[count] = 0;
533
534         rc = sysfs_memparse(kernbuf, count, &val, "B");
535         if (rc < 0)
536                 return rc;
537
538         osd->od_readcache_max_filesize = val > OSD_MAX_CACHE_SIZE ?
539                                          OSD_MAX_CACHE_SIZE : val;
540         return count;
541 }
542
543 LDEBUGFS_SEQ_FOPS(ldiskfs_osd_readcache);
544
545 static int ldiskfs_osd_readcache_max_io_seq_show(struct seq_file *m, void *data)
546 {
547         struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
548
549         LASSERT(osd != NULL);
550         if (unlikely(osd->od_mnt == NULL))
551                 return -EINPROGRESS;
552
553         seq_printf(m, "%lu\n", osd->od_readcache_max_iosize >> 20);
554         return 0;
555 }
556
557 static ssize_t
558 ldiskfs_osd_readcache_max_io_seq_write(struct file *file,
559                                        const char __user *buffer,
560                                        size_t count, loff_t *off)
561 {
562         struct seq_file *m = file->private_data;
563         struct dt_device *dt = m->private;
564         struct osd_device *osd = osd_dt_dev(dt);
565         char kernbuf[22] = "";
566         u64 val;
567         int rc;
568
569         LASSERT(osd != NULL);
570         if (unlikely(osd->od_mnt == NULL))
571                 return -EINPROGRESS;
572
573         if (count >= sizeof(kernbuf))
574                 return -EINVAL;
575
576         if (copy_from_user(kernbuf, buffer, count))
577                 return -EFAULT;
578         kernbuf[count] = 0;
579
580         rc = sysfs_memparse(kernbuf, count, &val, "MiB");
581         if (rc < 0)
582                 return rc;
583
584         if (val > PTLRPC_MAX_BRW_SIZE)
585                 return -ERANGE;
586         osd->od_readcache_max_iosize = val;
587         return count;
588 }
589
590 LDEBUGFS_SEQ_FOPS(ldiskfs_osd_readcache_max_io);
591
592 static int ldiskfs_osd_writethrough_max_io_seq_show(struct seq_file *m,
593                                                     void *data)
594 {
595         struct osd_device *osd = osd_dt_dev((struct dt_device *)m->private);
596
597         LASSERT(osd != NULL);
598         if (unlikely(osd->od_mnt == NULL))
599                 return -EINPROGRESS;
600
601         seq_printf(m, "%lu\n", osd->od_writethrough_max_iosize >> 20);
602         return 0;
603 }
604
605 static ssize_t
606 ldiskfs_osd_writethrough_max_io_seq_write(struct file *file,
607                                        const char __user *buffer,
608                                        size_t count, loff_t *off)
609 {
610         struct seq_file *m = file->private_data;
611         struct dt_device *dt = m->private;
612         struct osd_device *osd = osd_dt_dev(dt);
613         char kernbuf[22] = "";
614         u64 val;
615         int rc;
616
617         LASSERT(osd != NULL);
618         if (unlikely(osd->od_mnt == NULL))
619                 return -EINPROGRESS;
620
621         if (count >= sizeof(kernbuf))
622                 return -EINVAL;
623
624         if (copy_from_user(kernbuf, buffer, count))
625                 return -EFAULT;
626         kernbuf[count] = 0;
627
628         rc = sysfs_memparse(kernbuf, count, &val, "MiB");
629         if (rc < 0)
630                 return rc;
631
632         if (val > PTLRPC_MAX_BRW_SIZE)
633                 return -ERANGE;
634         osd->od_writethrough_max_iosize = val;
635         return count;
636 }
637
638 LDEBUGFS_SEQ_FOPS(ldiskfs_osd_writethrough_max_io);
639
640 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 52, 0)
641 static ssize_t index_in_idif_show(struct kobject *kobj, struct attribute *attr,
642                                   char *buf)
643 {
644         struct dt_device *dt = container_of(kobj, struct dt_device,
645                                             dd_kobj);
646         struct osd_device *dev = osd_dt_dev(dt);
647
648         LASSERT(dev);
649         if (unlikely(!dev->od_mnt))
650                 return -EINPROGRESS;
651
652         return sprintf(buf, "%d\n", (int)(dev->od_index_in_idif));
653 }
654
655 static ssize_t index_in_idif_store(struct kobject *kobj,
656                                    struct attribute *attr,
657                                    const char *buffer, size_t count)
658 {
659         struct dt_device *dt = container_of(kobj, struct dt_device,
660                                             dd_kobj);
661         struct osd_device *dev = osd_dt_dev(dt);
662         struct lu_target *tgt;
663         struct lu_env env;
664         bool val;
665         int rc;
666
667         LASSERT(dev);
668         if (unlikely(!dev->od_mnt))
669                 return -EINPROGRESS;
670
671         rc = kstrtobool(buffer, &val);
672         if (rc)
673                 return rc;
674
675         if (dev->od_index_in_idif) {
676                 if (val)
677                         return count;
678
679                 LCONSOLE_WARN("%s: OST-index in IDIF has been enabled, "
680                               "it cannot be reverted back.\n", osd_name(dev));
681                 return -EPERM;
682         }
683
684         if (!val)
685                 return count;
686
687         rc = lu_env_init(&env, LCT_DT_THREAD);
688         if (rc)
689                 return rc;
690
691         tgt = dev->od_dt_dev.dd_lu_dev.ld_site->ls_tgt;
692         tgt->lut_lsd.lsd_feature_rocompat |= OBD_ROCOMPAT_IDX_IN_IDIF;
693         rc = tgt_server_data_update(&env, tgt, 1);
694         lu_env_fini(&env);
695         if (rc < 0)
696                 return rc;
697
698         LCONSOLE_INFO("%s: enable OST-index in IDIF successfully, "
699                       "it cannot be reverted back.\n", osd_name(dev));
700
701         dev->od_index_in_idif = 1;
702         return count;
703 }
704 LUSTRE_RW_ATTR(index_in_idif);
705
706 int osd_register_proc_index_in_idif(struct osd_device *osd)
707 {
708         struct dt_device *dt = &osd->od_dt_dev;
709
710         return sysfs_create_file(&dt->dd_kobj, &lustre_attr_index_in_idif.attr);
711 }
712 #endif
713
714 static ssize_t index_backup_show(struct kobject *kobj, struct attribute *attr,
715                                  char *buf)
716 {
717         struct dt_device *dt = container_of(kobj, struct dt_device,
718                                             dd_kobj);
719         struct osd_device *dev = osd_dt_dev(dt);
720
721         LASSERT(dev);
722         if (unlikely(!dev->od_mnt))
723                 return -EINPROGRESS;
724
725         return sprintf(buf, "%d\n", dev->od_index_backup_policy);
726 }
727
728 ssize_t index_backup_store(struct kobject *kobj, struct attribute *attr,
729                            const char *buffer, size_t count)
730 {
731         struct dt_device *dt = container_of(kobj, struct dt_device,
732                                            dd_kobj);
733         struct osd_device *dev = osd_dt_dev(dt);
734         int val;
735         int rc;
736
737         LASSERT(dev);
738         if (unlikely(!dev->od_mnt))
739                 return -EINPROGRESS;
740
741         rc = kstrtoint(buffer, 0, &val);
742         if (rc)
743                 return rc;
744
745         dev->od_index_backup_policy = val;
746         return count;
747 }
748 LUSTRE_RW_ATTR(index_backup);
749
750 struct ldebugfs_vars ldebugfs_osd_obd_vars[] = {
751         { .name =       "oi_scrub",
752           .fops =       &ldiskfs_osd_oi_scrub_fops      },
753         { .name =       "readcache_max_filesize",
754           .fops =       &ldiskfs_osd_readcache_fops     },
755         { .name =       "readcache_max_io_mb",
756           .fops =       &ldiskfs_osd_readcache_max_io_fops      },
757         { .name =       "writethrough_max_io_mb",
758           .fops =       &ldiskfs_osd_writethrough_max_io_fops   },
759         { NULL }
760 };
761
762 static struct attribute *ldiskfs_attrs[] = {
763         &lustre_attr_read_cache_enable.attr,
764         &lustre_attr_writethrough_cache_enable.attr,
765         &lustre_attr_fstype.attr,
766         &lustre_attr_mntdev.attr,
767         &lustre_attr_fallocate_zero_blocks.attr,
768         &lustre_attr_force_sync.attr,
769         &lustre_attr_nonrotational.attr,
770         &lustre_attr_index_backup.attr,
771         &lustre_attr_auto_scrub.attr,
772         &lustre_attr_pdo.attr,
773         &lustre_attr_full_scrub_ratio.attr,
774         &lustre_attr_full_scrub_threshold_rate.attr,
775         &lustre_attr_extent_bytes_allocation.attr,
776         NULL,
777 };
778
779 int osd_procfs_init(struct osd_device *osd, const char *name)
780 {
781         struct obd_type *type;
782         int rc;
783
784         ENTRY;
785
786         /* at the moment there is no linkage between lu_type
787          * and obd_type, so we lookup obd_type this way
788          */
789         type = class_search_type(LUSTRE_OSD_LDISKFS_NAME);
790
791         LASSERT(name);
792         LASSERT(type);
793
794         CDEBUG(D_CONFIG, "%s: register osd-ldiskfs tunable parameters\n", name);
795
796         /* put reference taken by class_search_type */
797         kobject_put(&type->typ_kobj);
798
799         osd->od_dt_dev.dd_ktype.default_attrs = ldiskfs_attrs;
800         rc = dt_tunables_init(&osd->od_dt_dev, type, name,
801                               ldebugfs_osd_obd_vars);
802         if (rc) {
803                 CERROR("%s: cannot setup sysfs / debugfs entry: %d\n",
804                        name, rc);
805                 GOTO(out, rc);
806         }
807
808         if (osd->od_proc_entry)
809                 RETURN(0);
810
811         /* Find the type procroot and add the proc entry for this device */
812         osd->od_proc_entry = lprocfs_register(name, type->typ_procroot,
813                                               NULL, &osd->od_dt_dev);
814         if (IS_ERR(osd->od_proc_entry)) {
815                 rc = PTR_ERR(osd->od_proc_entry);
816                 CERROR("Error %d setting up lprocfs for %s\n",
817                        rc, name);
818                 osd->od_proc_entry = NULL;
819                 GOTO(out, rc);
820         }
821
822         rc = osd_stats_init(osd);
823
824         EXIT;
825 out:
826         if (rc)
827                 osd_procfs_fini(osd);
828         return rc;
829 }
830
831 int osd_procfs_fini(struct osd_device *osd)
832 {
833         lprocfs_fini_brw_stats(&osd->od_brw_stats);
834
835         if (osd->od_stats)
836                 lprocfs_free_stats(&osd->od_stats);
837
838         if (osd->od_proc_entry)
839                 lprocfs_remove(&osd->od_proc_entry);
840
841         return dt_tunables_fini(&osd->od_dt_dev);
842 }