Whamcloud - gitweb
b39135f19a42482c1c352a13a6007a673ba4e2ab
[fs/lustre-release.git] / lustre / ofd / lproc_ofd.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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2016, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  *
32  * lustre/ofd/lproc_ofd.c
33  *
34  * This file provides functions of procfs interface for OBD Filter Device (OFD).
35  *
36  * Author: Andreas Dilger <andreas.dilger@intel.com>
37  * Author: Mikhail Pershin <mike.pershin@intel.com>
38  * Author: Johann Lombardi <johann.lombardi@intel.com>
39  * Author: Fan Yong <fan.yong@intel.com>
40  */
41
42 #define DEBUG_SUBSYSTEM S_CLASS
43
44 #include <obd.h>
45 #include <lprocfs_status.h>
46 #include <linux/seq_file.h>
47 #include <lustre_lfsck.h>
48
49 #include "ofd_internal.h"
50
51 #ifdef CONFIG_PROC_FS
52
53 /**
54  * Show number of FID allocation sequences.
55  *
56  * \param[in] m         seq_file handle
57  * \param[in] data      unused for single entry
58  *
59  * \retval              0 on success
60  * \retval              negative value on error
61  */
62 static int ofd_seqs_seq_show(struct seq_file *m, void *data)
63 {
64         struct obd_device *obd = m->private;
65         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
66
67         seq_printf(m, "%u\n", ofd->ofd_seq_count);
68         return 0;
69 }
70 LPROC_SEQ_FOPS_RO(ofd_seqs);
71
72 /**
73  * Show estimate of total amount of dirty data on clients.
74  *
75  * \param[in] m         seq_file handle
76  * \param[in] data      unused for single entry
77  *
78  * \retval              0 on success
79  * \retval              negative value on error
80  */
81 static int ofd_tot_dirty_seq_show(struct seq_file *m, void *data)
82 {
83         struct obd_device *obd = m->private;
84         struct tg_grants_data *tgd;
85
86         LASSERT(obd != NULL);
87         tgd = &obd->u.obt.obt_lut->lut_tgd;
88         seq_printf(m, "%llu\n", tgd->tgd_tot_dirty);
89         return 0;
90 }
91 LPROC_SEQ_FOPS_RO(ofd_tot_dirty);
92
93 /**
94  * Show total amount of space granted to clients.
95  *
96  * \param[in] m         seq_file handle
97  * \param[in] data      unused for single entry
98  *
99  * \retval              0 on success
100  * \retval              negative value on error
101  */
102 static int ofd_tot_granted_seq_show(struct seq_file *m, void *data)
103 {
104         struct obd_device *obd = m->private;
105         struct tg_grants_data *tgd;
106
107         LASSERT(obd != NULL);
108         tgd = &obd->u.obt.obt_lut->lut_tgd;
109         seq_printf(m, "%llu\n", tgd->tgd_tot_granted);
110         return 0;
111 }
112 LPROC_SEQ_FOPS_RO(ofd_tot_granted);
113
114 /**
115  * Show total amount of space used by IO in progress.
116  *
117  * \param[in] m         seq_file handle
118  * \param[in] data      unused for single entry
119  *
120  * \retval              0 on success
121  * \retval              negative value on error
122  */
123 static int ofd_tot_pending_seq_show(struct seq_file *m, void *data)
124 {
125         struct obd_device *obd = m->private;
126         struct tg_grants_data *tgd;
127
128         LASSERT(obd != NULL);
129         tgd = &obd->u.obt.obt_lut->lut_tgd;
130         seq_printf(m, "%llu\n", tgd->tgd_tot_pending);
131         return 0;
132 }
133 LPROC_SEQ_FOPS_RO(ofd_tot_pending);
134
135 /**
136  * Show total number of grants for precreate.
137  *
138  * \param[in] m         seq_file handle
139  * \param[in] data      unused for single entry
140  *
141  * \retval              0 on success
142  * \retval              negative value on error
143  */
144 static int ofd_grant_precreate_seq_show(struct seq_file *m, void *data)
145 {
146         struct obd_device *obd = m->private;
147
148         LASSERT(obd != NULL);
149         seq_printf(m, "%ld\n",
150                    obd->obd_self_export->exp_target_data.ted_grant);
151         return 0;
152 }
153 LPROC_SEQ_FOPS_RO(ofd_grant_precreate);
154
155 /**
156  * Show number of precreates allowed in a single transaction.
157  *
158  * \param[in] m         seq_file handle
159  * \param[in] data      unused for single entry
160  *
161  * \retval              0 on success
162  * \retval              negative value on error
163  */
164 static int ofd_precreate_batch_seq_show(struct seq_file *m, void *data)
165 {
166         struct obd_device *obd = m->private;
167         struct ofd_device *ofd;
168
169         LASSERT(obd != NULL);
170         ofd = ofd_dev(obd->obd_lu_dev);
171         seq_printf(m, "%d\n", ofd->ofd_precreate_batch);
172         return 0;
173 }
174
175 /**
176  * Change number of precreates allowed in a single transaction.
177  *
178  * \param[in] file      proc file
179  * \param[in] buffer    string which represents maximum number
180  * \param[in] count     \a buffer length
181  * \param[in] off       unused for single entry
182  *
183  * \retval              \a count on success
184  * \retval              negative number on error
185  */
186 static ssize_t
187 ofd_precreate_batch_seq_write(struct file *file, const char __user *buffer,
188                               size_t count, loff_t *off)
189 {
190         struct seq_file *m = file->private_data;
191         struct obd_device *obd = m->private;
192         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
193         __s64 val;
194         int rc;
195
196         rc = lprocfs_str_to_s64(buffer, count, &val);
197         if (rc)
198                 return rc;
199
200         if (val < 1 || val > INT_MAX)
201                 return -EINVAL;
202
203         spin_lock(&ofd->ofd_batch_lock);
204         ofd->ofd_precreate_batch = val;
205         spin_unlock(&ofd->ofd_batch_lock);
206         return count;
207 }
208 LPROC_SEQ_FOPS(ofd_precreate_batch);
209
210 /**
211  * Show the last used ID for each FID sequence used by OFD.
212  *
213  * \param[in] m         seq_file handle
214  * \param[in] data      unused for single entry
215  *
216  * \retval              0 on success
217  * \retval              negative value on error
218  */
219 static int ofd_last_id_seq_show(struct seq_file *m, void *data)
220 {
221         struct obd_device       *obd = m->private;
222         struct ofd_device       *ofd;
223         struct ofd_seq          *oseq = NULL;
224
225         if (obd == NULL)
226                 return 0;
227
228         ofd = ofd_dev(obd->obd_lu_dev);
229
230         read_lock(&ofd->ofd_seq_list_lock);
231         list_for_each_entry(oseq, &ofd->ofd_seq_list, os_list) {
232                 __u64 seq;
233
234                 seq = ostid_seq(&oseq->os_oi) == 0 ?
235                       fid_idif_seq(ostid_id(&oseq->os_oi),
236                                    ofd->ofd_lut.lut_lsd.lsd_osd_index) :
237                       ostid_seq(&oseq->os_oi);
238                 seq_printf(m, DOSTID"\n", seq, ostid_id(&oseq->os_oi));
239         }
240         read_unlock(&ofd->ofd_seq_list_lock);
241         return 0;
242 }
243 LPROC_SEQ_FOPS_RO(ofd_last_id);
244
245 /**
246  * Show maximum number of Filter Modification Data (FMD) maintained by OFD.
247  *
248  * \param[in] m         seq_file handle
249  * \param[in] data      unused for single entry
250  *
251  * \retval              0 on success
252  * \retval              negative value on error
253  */
254 static int ofd_fmd_max_num_seq_show(struct seq_file *m, void *data)
255 {
256         struct obd_device *obd = m->private;
257         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
258
259         seq_printf(m, "%u\n", ofd->ofd_fmd_max_num);
260         return 0;
261 }
262
263 /**
264  * Change number of FMDs maintained by OFD.
265  *
266  * This defines how large the list of FMDs can be.
267  *
268  * \param[in] file      proc file
269  * \param[in] buffer    string which represents maximum number
270  * \param[in] count     \a buffer length
271  * \param[in] off       unused for single entry
272  *
273  * \retval              \a count on success
274  * \retval              negative number on error
275  */
276 static ssize_t
277 ofd_fmd_max_num_seq_write(struct file *file, const char __user *buffer,
278                           size_t count, loff_t *off)
279 {
280         struct seq_file *m = file->private_data;
281         struct obd_device *obd = m->private;
282         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
283         __s64 val;
284         int rc;
285
286         rc = lprocfs_str_to_s64(buffer, count, &val);
287         if (rc)
288                 return rc;
289
290         if (val > 65536 || val < 1)
291                 return -EINVAL;
292
293         ofd->ofd_fmd_max_num = val;
294         return count;
295 }
296 LPROC_SEQ_FOPS(ofd_fmd_max_num);
297
298 /**
299  * Show the maximum age of FMD data in seconds.
300  *
301  * Though it is shown in seconds, it is stored internally in units
302  * of jiffies for efficiency.
303  *
304  * \param[in] m         seq_file handle
305  * \param[in] data      unused for single entry
306  *
307  * \retval              0 on success
308  * \retval              negative value on error
309  */
310 static int ofd_fmd_max_age_seq_show(struct seq_file *m, void *data)
311 {
312         struct obd_device *obd = m->private;
313         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
314
315         seq_printf(m, "%ld\n", jiffies_to_msecs(ofd->ofd_fmd_max_age) /
316                    MSEC_PER_SEC);
317         return 0;
318 }
319
320 /**
321  * Set the maximum age of FMD data in seconds.
322  *
323  * This defines how long FMD data stays in the FMD list.
324  * It is stored internally in units of jiffies for efficiency.
325  *
326  * \param[in] file      proc file
327  * \param[in] buffer    string which represents maximum number
328  * \param[in] count     \a buffer length
329  * \param[in] off       unused for single entry
330  *
331  * \retval              \a count on success
332  * \retval              negative number on error
333  */
334 static ssize_t
335 ofd_fmd_max_age_seq_write(struct file *file, const char __user *buffer,
336                           size_t count, loff_t *off)
337 {
338         struct seq_file         *m = file->private_data;
339         struct obd_device       *obd = m->private;
340         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
341         __s64                    val;
342         int                      rc;
343
344         rc = lprocfs_str_to_s64(buffer, count, &val);
345         if (rc)
346                 return rc;
347
348         if (val > 65536 || val < 1)
349                 return -EINVAL;
350
351         ofd->ofd_fmd_max_age = msecs_to_jiffies(val * MSEC_PER_SEC);
352         return count;
353 }
354 LPROC_SEQ_FOPS(ofd_fmd_max_age);
355
356 /**
357  * Show if the OFD is in degraded mode.
358  *
359  * Degraded means OFD has a failed drive or is undergoing RAID rebuild.
360  * The MDS will try to avoid using this OST for new object allocations
361  * to reduce the impact to global IO performance when clients writing to
362  * this OST are slowed down.  It also reduces the contention on the OST
363  * RAID device, allowing it to rebuild more quickly.
364  *
365  * \param[in] m         seq_file handle
366  * \param[in] data      unused for single entry
367  *
368  * \retval              0 on success
369  * \retval              negative value on error
370  */
371 static int ofd_degraded_seq_show(struct seq_file *m, void *data)
372 {
373         struct obd_device *obd = m->private;
374         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
375
376         seq_printf(m, "%u\n", ofd->ofd_raid_degraded);
377         return 0;
378 }
379
380 /**
381  * Set OFD to degraded mode.
382  *
383  * This is used to interface to userspace administrative tools for
384  * the underlying RAID storage, so that they can mark an OST
385  * as having degraded performance.
386  *
387  * \param[in] file      proc file
388  * \param[in] buffer    string which represents mode
389  *                      1: set degraded mode
390  *                      0: unset degraded mode
391  * \param[in] count     \a buffer length
392  * \param[in] off       unused for single entry
393  *
394  * \retval              \a count on success
395  * \retval              negative number on error
396  */
397 static ssize_t
398 ofd_degraded_seq_write(struct file *file, const char __user *buffer,
399                        size_t count, loff_t *off)
400 {
401         struct seq_file *m = file->private_data;
402         struct obd_device *obd = m->private;
403         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
404         int rc;
405         __s64 val;
406
407         rc = lprocfs_str_to_s64(buffer, count, &val);
408         if (rc)
409                 return rc;
410
411         spin_lock(&ofd->ofd_flags_lock);
412         ofd->ofd_raid_degraded = !!val;
413         spin_unlock(&ofd->ofd_flags_lock);
414         return count;
415 }
416 LPROC_SEQ_FOPS(ofd_degraded);
417
418 /**
419  * Show OFD filesystem type.
420  *
421  * \param[in] m         seq_file handle
422  * \param[in] data      unused for single entry
423  *
424  * \retval              0 on success
425  * \retval              negative value on error
426  */
427 static int ofd_fstype_seq_show(struct seq_file *m, void *data)
428 {
429         struct obd_device *obd = m->private;
430         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
431         struct lu_device  *d;
432
433         LASSERT(ofd->ofd_osd);
434         d = &ofd->ofd_osd->dd_lu_dev;
435         LASSERT(d->ld_type);
436         seq_printf(m, "%s\n", d->ld_type->ldt_name);
437         return 0;
438 }
439 LPROC_SEQ_FOPS_RO(ofd_fstype);
440
441 /**
442  * Show journal handling mode: synchronous or asynchronous.
443  *
444  * When running in asynchronous mode the journal transactions are not
445  * committed to disk before the RPC is replied back to the client.
446  * This will typically improve client performance when only a small number
447  * of clients are writing, since the client(s) can have more write RPCs
448  * in flight. However, it also means that the client has to handle recovery
449  * on bulk RPCs, and will have to keep more dirty pages in cache before they
450  * are committed on the OST.
451  *
452  * \param[in] m         seq_file handle
453  * \param[in] data      unused for single entry
454  *
455  * \retval              0 on success
456  * \retval              negative value on error
457  */
458 static int ofd_syncjournal_seq_show(struct seq_file *m, void *data)
459 {
460         struct obd_device       *obd = m->private;
461         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
462
463         seq_printf(m, "%u\n", ofd->ofd_syncjournal);
464         return 0;
465 }
466
467 /**
468  * Set journal mode to synchronous or asynchronous.
469  *
470  * \param[in] file      proc file
471  * \param[in] buffer    string which represents mode
472  *                      1: synchronous mode
473  *                      0: asynchronous mode
474  * \param[in] count     \a buffer length
475  * \param[in] off       unused for single entry
476  *
477  * \retval              \a count on success
478  * \retval              negative number on error
479  */
480 static ssize_t
481 ofd_syncjournal_seq_write(struct file *file, const char __user *buffer,
482                           size_t count, loff_t *off)
483 {
484         struct seq_file *m = file->private_data;
485         struct obd_device *obd = m->private;
486         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
487         __s64 val;
488         int rc;
489
490         rc = lprocfs_str_to_s64(buffer, count, &val);
491         if (rc)
492                 return rc;
493
494         if (val < 0)
495                 return -EINVAL;
496
497         spin_lock(&ofd->ofd_flags_lock);
498         ofd->ofd_syncjournal = !!val;
499         ofd_slc_set(ofd);
500         spin_unlock(&ofd->ofd_flags_lock);
501
502         return count;
503 }
504 LPROC_SEQ_FOPS(ofd_syncjournal);
505
506 /* This must be longer than the longest string below */
507 #define SYNC_STATES_MAXLEN 16
508
509 static int ofd_brw_size_seq_show(struct seq_file *m, void *data)
510 {
511         struct obd_device       *obd = m->private;
512         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
513
514         seq_printf(m, "%u\n", ofd->ofd_brw_size / ONE_MB_BRW_SIZE);
515         return 0;
516 }
517
518 static ssize_t
519 ofd_brw_size_seq_write(struct file *file, const char __user *buffer,
520                        size_t count, loff_t *off)
521 {
522         struct seq_file *m = file->private_data;
523         struct obd_device *obd = m->private;
524         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
525         __s64 val;
526         int rc;
527
528         rc = lprocfs_str_with_units_to_s64(buffer, count, &val, 'M');
529         if (rc)
530                 return rc;
531
532         if (val <= 0)
533                 return -EINVAL;
534
535         if (val > DT_MAX_BRW_SIZE ||
536             val < (1 << ofd->ofd_lut.lut_tgd.tgd_blockbits))
537                 return -ERANGE;
538
539         spin_lock(&ofd->ofd_flags_lock);
540         ofd->ofd_brw_size = val;
541         spin_unlock(&ofd->ofd_flags_lock);
542
543         return count;
544 }
545 LPROC_SEQ_FOPS(ofd_brw_size);
546
547 static char *sync_on_cancel_states[] = {"never",
548                                         "blocking",
549                                         "always" };
550
551 /**
552  * Show OFD policy for handling dirty data under a lock being cancelled.
553  *
554  * \param[in] m         seq_file handle
555  * \param[in] data      unused for single entry
556  *
557  * \retval              0 on success
558  * \retval              negative value on error
559  */
560 static int ofd_sync_lock_cancel_seq_show(struct seq_file *m, void *data)
561 {
562         struct obd_device       *obd = m->private;
563         struct lu_target        *tgt = obd->u.obt.obt_lut;
564
565         seq_printf(m, "%s\n",
566                    sync_on_cancel_states[tgt->lut_sync_lock_cancel]);
567         return 0;
568 }
569
570 /**
571  * Change OFD policy for handling dirty data under a lock being cancelled.
572  *
573  * This variable defines what action OFD takes upon lock cancel
574  * There are three possible modes:
575  * 1) never - never do sync upon lock cancel. This can lead to data
576  *    inconsistencies if both the OST and client crash while writing a file
577  *    that is also concurrently being read by another client. In these cases,
578  *    this may allow the file data to "rewind" to an earlier state.
579  * 2) blocking - do sync only if there is blocking lock, e.g. if another
580  *    client is trying to access this same object
581  * 3) always - do sync always
582  *
583  * \param[in] file      proc file
584  * \param[in] buffer    string which represents policy
585  * \param[in] count     \a buffer length
586  * \param[in] off       unused for single entry
587  *
588  * \retval              \a count on success
589  * \retval              negative number on error
590  */
591 static ssize_t
592 ofd_sync_lock_cancel_seq_write(struct file *file, const char __user *buffer,
593                                size_t count, loff_t *off)
594 {
595         struct seq_file *m = file->private_data;
596         struct obd_device *obd = m->private;
597         struct lu_target *tgt = obd->u.obt.obt_lut;
598         char kernbuf[SYNC_STATES_MAXLEN];
599         __s64 val = -1;
600         int i;
601
602         if (count == 0 || count >= sizeof(kernbuf))
603                 return -EINVAL;
604
605         if (copy_from_user(kernbuf, buffer, count))
606                 return -EFAULT;
607         kernbuf[count] = 0;
608
609         if (kernbuf[count - 1] == '\n')
610                 kernbuf[count - 1] = 0;
611
612         for (i = 0 ; i < NUM_SYNC_ON_CANCEL_STATES; i++) {
613                 if (strcmp(kernbuf, sync_on_cancel_states[i]) == 0) {
614                         val = i;
615                         break;
616                 }
617         }
618
619         /* Legacy numeric codes */
620         if (val == -1) {
621                 int rc = lprocfs_str_to_s64(buffer, count, &val);
622                 if (rc)
623                         return rc;
624         }
625
626         if (val < 0 || val > 2)
627                 return -EINVAL;
628
629         spin_lock(&tgt->lut_flags_lock);
630         tgt->lut_sync_lock_cancel = val;
631         spin_unlock(&tgt->lut_flags_lock);
632         return count;
633 }
634 LPROC_SEQ_FOPS(ofd_sync_lock_cancel);
635
636 /**
637  * Show if grants compatibility mode is disabled.
638  *
639  * When tgd_grant_compat_disable is set, we don't grant any space to clients
640  * not supporting OBD_CONNECT_GRANT_PARAM. Otherwise, space granted to such
641  * a client is inflated since it consumes PAGE_SIZE of grant space per
642  * block, (i.e. typically 4kB units), but underlaying file system might have
643  * block size bigger than page size, e.g. ZFS. See LU-2049 for details.
644  *
645  * \param[in] m         seq_file handle
646  * \param[in] data      unused for single entry
647  *
648  * \retval              0 on success
649  * \retval              negative value on error
650  */
651 static int ofd_grant_compat_disable_seq_show(struct seq_file *m, void *data)
652 {
653         struct obd_device *obd = m->private;
654         struct tg_grants_data *tgd = &obd->u.obt.obt_lut->lut_tgd;
655
656         seq_printf(m, "%u\n", tgd->tgd_grant_compat_disable);
657         return 0;
658 }
659
660 /**
661  * Change grant compatibility mode.
662  *
663  * Setting tgd_grant_compat_disable prohibit any space granting to clients
664  * not supporting OBD_CONNECT_GRANT_PARAM. See details above.
665  *
666  * \param[in] file      proc file
667  * \param[in] buffer    string which represents mode
668  *                      1: disable compatibility mode
669  *                      0: enable compatibility mode
670  * \param[in] count     \a buffer length
671  * \param[in] off       unused for single entry
672  *
673  * \retval              \a count on success
674  * \retval              negative number on error
675  */
676 static ssize_t
677 ofd_grant_compat_disable_seq_write(struct file *file,
678                                    const char __user *buffer,
679                                    size_t count, loff_t *off)
680 {
681         struct seq_file *m = file->private_data;
682         struct obd_device *obd = m->private;
683         struct tg_grants_data *tgd = &obd->u.obt.obt_lut->lut_tgd;
684         __s64 val;
685         int rc;
686
687         rc = lprocfs_str_to_s64(buffer, count, &val);
688         if (rc)
689                 return rc;
690
691         if (val < 0)
692                 return -EINVAL;
693
694         tgd->tgd_grant_compat_disable = !!val;
695
696         return count;
697 }
698 LPROC_SEQ_FOPS(ofd_grant_compat_disable);
699
700 /**
701  * Show the limit of soft sync RPCs.
702  *
703  * This value defines how many IO RPCs with OBD_BRW_SOFT_SYNC flag
704  * are allowed before sync update will be triggered.
705  *
706  * \param[in] m         seq_file handle
707  * \param[in] data      unused for single entry
708  *
709  * \retval              0 on success
710  * \retval              negative value on error
711  */
712 static int ofd_soft_sync_limit_seq_show(struct seq_file *m, void *data)
713 {
714         struct obd_device       *obd = m->private;
715         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
716
717         return lprocfs_uint_seq_show(m, &ofd->ofd_soft_sync_limit);
718 }
719
720 /**
721  * Change the limit of soft sync RPCs.
722  *
723  * Define how many IO RPCs with OBD_BRW_SOFT_SYNC flag
724  * allowed before sync update will be done.
725  *
726  * This limit is global across all exports.
727  *
728  * \param[in] file      proc file
729  * \param[in] buffer    string which represents limit
730  * \param[in] count     \a buffer length
731  * \param[in] off       unused for single entry
732  *
733  * \retval              \a count on success
734  * \retval              negative number on error
735  */
736 static ssize_t
737 ofd_soft_sync_limit_seq_write(struct file *file, const char __user *buffer,
738                               size_t count, loff_t *off)
739 {
740         struct seq_file   *m = file->private_data;
741         struct obd_device *obd = m->private;
742         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
743
744         return lprocfs_uint_seq_write(file, buffer, count,
745                                       (loff_t *) &ofd->ofd_soft_sync_limit);
746 }
747 LPROC_SEQ_FOPS(ofd_soft_sync_limit);
748
749 /**
750  * Show the LFSCK speed limit.
751  *
752  * The maximum number of items scanned per second.
753  *
754  * \param[in] m         seq_file handle
755  * \param[in] data      unused for single entry
756  *
757  * \retval              0 on success
758  * \retval              negative value on error
759  */
760 static int ofd_lfsck_speed_limit_seq_show(struct seq_file *m, void *data)
761 {
762         struct obd_device       *obd = m->private;
763         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
764
765         return lfsck_get_speed(m, ofd->ofd_osd);
766 }
767
768 /**
769  * Change the LFSCK speed limit.
770  *
771  * Limit number of items that may be scanned per second.
772  *
773  * \param[in] file      proc file
774  * \param[in] buffer    string which represents limit
775  * \param[in] count     \a buffer length
776  * \param[in] off       unused for single entry
777  *
778  * \retval              \a count on success
779  * \retval              negative number on error
780  */
781 static ssize_t
782 ofd_lfsck_speed_limit_seq_write(struct file *file, const char __user *buffer,
783                                 size_t count, loff_t *off)
784 {
785         struct seq_file *m = file->private_data;
786         struct obd_device *obd = m->private;
787         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
788         __s64 val;
789         int rc;
790
791         rc = lprocfs_str_to_s64(buffer, count, &val);
792         if (rc != 0)
793                 return rc;
794
795         if (val < 0)
796                 return -ERANGE;
797
798         rc = lfsck_set_speed(ofd->ofd_osd, val);
799
800         return rc != 0 ? rc : count;
801 }
802 LPROC_SEQ_FOPS(ofd_lfsck_speed_limit);
803
804 /**
805  * Show LFSCK layout verification stats from the most recent LFSCK run.
806  *
807  * \param[in] m         seq_file handle
808  * \param[in] data      unused for single entry
809  *
810  * \retval              0 on success
811  * \retval              negative value on error
812  */
813 static int ofd_lfsck_layout_seq_show(struct seq_file *m, void *data)
814 {
815         struct obd_device *obd = m->private;
816         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
817
818         return lfsck_dump(m, ofd->ofd_osd, LFSCK_TYPE_LAYOUT);
819 }
820 LPROC_SEQ_FOPS_RO(ofd_lfsck_layout);
821
822 /**
823  * Show if LFSCK performed parent FID verification.
824  *
825  * \param[in] m         seq_file handle
826  * \param[in] data      unused for single entry
827  *
828  * \retval              0 on success
829  * \retval              negative value on error
830  */
831 static int ofd_lfsck_verify_pfid_seq_show(struct seq_file *m, void *data)
832 {
833         struct obd_device *obd = m->private;
834         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
835
836         seq_printf(m, "switch: %s\ndetected: %llu\nrepaired: %llu\n",
837                    ofd->ofd_lfsck_verify_pfid ? "on" : "off",
838                    ofd->ofd_inconsistency_self_detected,
839                    ofd->ofd_inconsistency_self_repaired);
840         return 0;
841 }
842
843 /**
844  * Set the LFSCK behavior to verify parent FID correctness.
845  *
846  * If flag ofd_lfsck_verify_pfid is set then LFSCK does parent FID
847  * verification during read/write operations.
848  *
849  * \param[in] file      proc file
850  * \param[in] buffer    string which represents behavior
851  *                      1: verify parent FID
852  *                      0: don't verify parent FID
853  * \param[in] count     \a buffer length
854  * \param[in] off       unused for single entry
855  *
856  * \retval              \a count on success
857  * \retval              negative number on error
858  */
859 static ssize_t
860 ofd_lfsck_verify_pfid_seq_write(struct file *file, const char __user *buffer,
861                                 size_t count, loff_t *off)
862 {
863         struct seq_file *m = file->private_data;
864         struct obd_device *obd = m->private;
865         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
866         __s64 val;
867         int rc;
868
869         rc = lprocfs_str_to_s64(buffer, count, &val);
870         if (rc != 0)
871                 return rc;
872
873         ofd->ofd_lfsck_verify_pfid = !!val;
874         if (!ofd->ofd_lfsck_verify_pfid) {
875                 ofd->ofd_inconsistency_self_detected = 0;
876                 ofd->ofd_inconsistency_self_repaired = 0;
877         }
878
879         return count;
880 }
881 LPROC_SEQ_FOPS(ofd_lfsck_verify_pfid);
882
883 static int ofd_site_stats_seq_show(struct seq_file *m, void *data)
884 {
885         struct obd_device *obd = m->private;
886
887         return lu_site_stats_seq_print(obd->obd_lu_dev->ld_site, m);
888 }
889 LPROC_SEQ_FOPS_RO(ofd_site_stats);
890
891 LPROC_SEQ_FOPS_RO_TYPE(ofd, uuid);
892 LPROC_SEQ_FOPS_RO_TYPE(ofd, blksize);
893 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytestotal);
894 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesfree);
895 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesavail);
896 LPROC_SEQ_FOPS_RO_TYPE(ofd, filestotal);
897 LPROC_SEQ_FOPS_RO_TYPE(ofd, filesfree);
898
899 LPROC_SEQ_FOPS_RO_TYPE(ofd, recovery_status);
900 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_soft);
901 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_hard);
902 LPROC_SEQ_FOPS_WO_TYPE(ofd, evict_client);
903 LPROC_SEQ_FOPS_RO_TYPE(ofd, num_exports);
904 LPROC_SEQ_FOPS_RO_TYPE(ofd, target_instance);
905 LPROC_SEQ_FOPS_RW_TYPE(ofd, ir_factor);
906 LPROC_SEQ_FOPS_RW_TYPE(ofd, checksum_dump);
907 LPROC_SEQ_FOPS_RW_TYPE(ofd, job_interval);
908
909 struct lprocfs_vars lprocfs_ofd_obd_vars[] = {
910         { .name =       "uuid",
911           .fops =       &ofd_uuid_fops                  },
912         { .name =       "blocksize",
913           .fops =       &ofd_blksize_fops               },
914         { .name =       "kbytestotal",
915           .fops =       &ofd_kbytestotal_fops           },
916         { .name =       "kbytesfree",
917           .fops =       &ofd_kbytesfree_fops            },
918         { .name =       "kbytesavail",
919           .fops =       &ofd_kbytesavail_fops           },
920         { .name =       "filestotal",
921           .fops =       &ofd_filestotal_fops            },
922         { .name =       "filesfree",
923           .fops =       &ofd_filesfree_fops             },
924         { .name =       "seqs_allocated",
925           .fops =       &ofd_seqs_fops                  },
926         { .name =       "fstype",
927           .fops =       &ofd_fstype_fops                },
928         { .name =       "last_id",
929           .fops =       &ofd_last_id_fops               },
930         { .name =       "tot_dirty",
931           .fops =       &ofd_tot_dirty_fops             },
932         { .name =       "tot_pending",
933           .fops =       &ofd_tot_pending_fops           },
934         { .name =       "tot_granted",
935           .fops =       &ofd_tot_granted_fops           },
936         { .name =       "grant_precreate",
937           .fops =       &ofd_grant_precreate_fops       },
938         { .name =       "precreate_batch",
939           .fops =       &ofd_precreate_batch_fops       },
940         { .name =       "recovery_status",
941           .fops =       &ofd_recovery_status_fops       },
942         { .name =       "recovery_time_soft",
943           .fops =       &ofd_recovery_time_soft_fops    },
944         { .name =       "recovery_time_hard",
945           .fops =       &ofd_recovery_time_hard_fops    },
946         { .name =       "evict_client",
947           .fops =       &ofd_evict_client_fops          },
948         { .name =       "num_exports",
949           .fops =       &ofd_num_exports_fops           },
950         { .name =       "degraded",
951           .fops =       &ofd_degraded_fops              },
952         { .name =       "sync_journal",
953           .fops =       &ofd_syncjournal_fops           },
954         { .name =       "brw_size",
955           .fops =       &ofd_brw_size_fops              },
956         { .name =       "sync_on_lock_cancel",
957           .fops =       &ofd_sync_lock_cancel_fops      },
958         { .name =       "instance",
959           .fops =       &ofd_target_instance_fops       },
960         { .name =       "ir_factor",
961           .fops =       &ofd_ir_factor_fops             },
962         { .name =       "checksum_dump",
963           .fops =       &ofd_checksum_dump_fops         },
964         { .name =       "grant_compat_disable",
965           .fops =       &ofd_grant_compat_disable_fops  },
966         { .name =       "client_cache_count",
967           .fops =       &ofd_fmd_max_num_fops           },
968         { .name =       "client_cache_seconds",
969           .fops =       &ofd_fmd_max_age_fops           },
970         { .name =       "job_cleanup_interval",
971           .fops =       &ofd_job_interval_fops          },
972         { .name =       "soft_sync_limit",
973           .fops =       &ofd_soft_sync_limit_fops       },
974         { .name =       "lfsck_speed_limit",
975           .fops =       &ofd_lfsck_speed_limit_fops     },
976         { .name =       "lfsck_layout",
977           .fops =       &ofd_lfsck_layout_fops          },
978         { .name =       "lfsck_verify_pfid",
979           .fops =       &ofd_lfsck_verify_pfid_fops     },
980         { .name =       "site_stats",
981           .fops =       &ofd_site_stats_fops            },
982         { NULL }
983 };
984
985 /**
986  * Initialize OFD statistics counters
987  *
988  * param[in] stats      statistics counters
989  */
990 void ofd_stats_counter_init(struct lprocfs_stats *stats)
991 {
992         LASSERT(stats && stats->ls_num >= LPROC_OFD_STATS_LAST);
993
994         lprocfs_counter_init(stats, LPROC_OFD_STATS_READ,
995                              LPROCFS_CNTR_AVGMINMAX, "read_bytes", "bytes");
996         lprocfs_counter_init(stats, LPROC_OFD_STATS_WRITE,
997                              LPROCFS_CNTR_AVGMINMAX, "write_bytes", "bytes");
998         lprocfs_counter_init(stats, LPROC_OFD_STATS_GETATTR,
999                              0, "getattr", "reqs");
1000         lprocfs_counter_init(stats, LPROC_OFD_STATS_SETATTR,
1001                              0, "setattr", "reqs");
1002         lprocfs_counter_init(stats, LPROC_OFD_STATS_PUNCH,
1003                              0, "punch", "reqs");
1004         lprocfs_counter_init(stats, LPROC_OFD_STATS_SYNC,
1005                              0, "sync", "reqs");
1006         lprocfs_counter_init(stats, LPROC_OFD_STATS_DESTROY,
1007                              0, "destroy", "reqs");
1008         lprocfs_counter_init(stats, LPROC_OFD_STATS_CREATE,
1009                              0, "create", "reqs");
1010         lprocfs_counter_init(stats, LPROC_OFD_STATS_STATFS,
1011                              0, "statfs", "reqs");
1012         lprocfs_counter_init(stats, LPROC_OFD_STATS_GET_INFO,
1013                              0, "get_info", "reqs");
1014         lprocfs_counter_init(stats, LPROC_OFD_STATS_SET_INFO,
1015                              0, "set_info", "reqs");
1016         lprocfs_counter_init(stats, LPROC_OFD_STATS_QUOTACTL,
1017                              0, "quotactl", "reqs");
1018 }
1019
1020 #endif /* CONFIG_PROC_FS */