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