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