Whamcloud - gitweb
LU-3285 mdt: use generic grant code at MDT
[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 total number of grants for precreate.
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_grant_precreate_seq_show(struct seq_file *m, void *data)
82 {
83         struct obd_device *obd = m->private;
84
85         LASSERT(obd != NULL);
86         seq_printf(m, "%ld\n",
87                    obd->obd_self_export->exp_target_data.ted_grant);
88         return 0;
89 }
90 LPROC_SEQ_FOPS_RO(ofd_grant_precreate);
91
92 /**
93  * Show number of precreates allowed in a single transaction.
94  *
95  * \param[in] m         seq_file handle
96  * \param[in] data      unused for single entry
97  *
98  * \retval              0 on success
99  * \retval              negative value on error
100  */
101 static int ofd_precreate_batch_seq_show(struct seq_file *m, void *data)
102 {
103         struct obd_device *obd = m->private;
104         struct ofd_device *ofd;
105
106         LASSERT(obd != NULL);
107         ofd = ofd_dev(obd->obd_lu_dev);
108         seq_printf(m, "%d\n", ofd->ofd_precreate_batch);
109         return 0;
110 }
111
112 /**
113  * Change number of precreates allowed in a single transaction.
114  *
115  * \param[in] file      proc file
116  * \param[in] buffer    string which represents maximum number
117  * \param[in] count     \a buffer length
118  * \param[in] off       unused for single entry
119  *
120  * \retval              \a count on success
121  * \retval              negative number on error
122  */
123 static ssize_t
124 ofd_precreate_batch_seq_write(struct file *file, const char __user *buffer,
125                               size_t count, loff_t *off)
126 {
127         struct seq_file *m = file->private_data;
128         struct obd_device *obd = m->private;
129         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
130         __s64 val;
131         int rc;
132
133         rc = lprocfs_str_to_s64(buffer, count, &val);
134         if (rc)
135                 return rc;
136
137         if (val < 1 || val > INT_MAX)
138                 return -EINVAL;
139
140         spin_lock(&ofd->ofd_batch_lock);
141         ofd->ofd_precreate_batch = val;
142         spin_unlock(&ofd->ofd_batch_lock);
143         return count;
144 }
145 LPROC_SEQ_FOPS(ofd_precreate_batch);
146
147 /**
148  * Show the last used ID for each FID sequence used by OFD.
149  *
150  * \param[in] m         seq_file handle
151  * \param[in] data      unused for single entry
152  *
153  * \retval              0 on success
154  * \retval              negative value on error
155  */
156 static int ofd_last_id_seq_show(struct seq_file *m, void *data)
157 {
158         struct obd_device       *obd = m->private;
159         struct ofd_device       *ofd;
160         struct ofd_seq          *oseq = NULL;
161
162         if (obd == NULL)
163                 return 0;
164
165         ofd = ofd_dev(obd->obd_lu_dev);
166
167         read_lock(&ofd->ofd_seq_list_lock);
168         list_for_each_entry(oseq, &ofd->ofd_seq_list, os_list) {
169                 __u64 seq;
170
171                 seq = ostid_seq(&oseq->os_oi) == 0 ?
172                       fid_idif_seq(ostid_id(&oseq->os_oi),
173                                    ofd->ofd_lut.lut_lsd.lsd_osd_index) :
174                       ostid_seq(&oseq->os_oi);
175                 seq_printf(m, DOSTID"\n", seq, ostid_id(&oseq->os_oi));
176         }
177         read_unlock(&ofd->ofd_seq_list_lock);
178         return 0;
179 }
180 LPROC_SEQ_FOPS_RO(ofd_last_id);
181
182 /**
183  * Show maximum number of Filter Modification Data (FMD) maintained by OFD.
184  *
185  * \param[in] m         seq_file handle
186  * \param[in] data      unused for single entry
187  *
188  * \retval              0 on success
189  * \retval              negative value on error
190  */
191 static int ofd_fmd_max_num_seq_show(struct seq_file *m, void *data)
192 {
193         struct obd_device *obd = m->private;
194         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
195
196         seq_printf(m, "%u\n", ofd->ofd_fmd_max_num);
197         return 0;
198 }
199
200 /**
201  * Change number of FMDs maintained by OFD.
202  *
203  * This defines how large the list of FMDs can be.
204  *
205  * \param[in] file      proc file
206  * \param[in] buffer    string which represents maximum number
207  * \param[in] count     \a buffer length
208  * \param[in] off       unused for single entry
209  *
210  * \retval              \a count on success
211  * \retval              negative number on error
212  */
213 static ssize_t
214 ofd_fmd_max_num_seq_write(struct file *file, const char __user *buffer,
215                           size_t count, loff_t *off)
216 {
217         struct seq_file *m = file->private_data;
218         struct obd_device *obd = m->private;
219         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
220         __s64 val;
221         int rc;
222
223         rc = lprocfs_str_to_s64(buffer, count, &val);
224         if (rc)
225                 return rc;
226
227         if (val > 65536 || val < 1)
228                 return -EINVAL;
229
230         ofd->ofd_fmd_max_num = val;
231         return count;
232 }
233 LPROC_SEQ_FOPS(ofd_fmd_max_num);
234
235 /**
236  * Show the maximum age of FMD data in seconds.
237  *
238  * Though it is shown in seconds, it is stored internally in units
239  * of jiffies for efficiency.
240  *
241  * \param[in] m         seq_file handle
242  * \param[in] data      unused for single entry
243  *
244  * \retval              0 on success
245  * \retval              negative value on error
246  */
247 static int ofd_fmd_max_age_seq_show(struct seq_file *m, void *data)
248 {
249         struct obd_device *obd = m->private;
250         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
251
252         seq_printf(m, "%ld\n", jiffies_to_msecs(ofd->ofd_fmd_max_age) /
253                    MSEC_PER_SEC);
254         return 0;
255 }
256
257 /**
258  * Set the maximum age of FMD data in seconds.
259  *
260  * This defines how long FMD data stays in the FMD list.
261  * It is stored internally in units of jiffies for efficiency.
262  *
263  * \param[in] file      proc file
264  * \param[in] buffer    string which represents maximum number
265  * \param[in] count     \a buffer length
266  * \param[in] off       unused for single entry
267  *
268  * \retval              \a count on success
269  * \retval              negative number on error
270  */
271 static ssize_t
272 ofd_fmd_max_age_seq_write(struct file *file, const char __user *buffer,
273                           size_t count, loff_t *off)
274 {
275         struct seq_file         *m = file->private_data;
276         struct obd_device       *obd = m->private;
277         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
278         __s64                    val;
279         int                      rc;
280
281         rc = lprocfs_str_to_s64(buffer, count, &val);
282         if (rc)
283                 return rc;
284
285         if (val > 65536 || val < 1)
286                 return -EINVAL;
287
288         ofd->ofd_fmd_max_age = msecs_to_jiffies(val * MSEC_PER_SEC);
289         return count;
290 }
291 LPROC_SEQ_FOPS(ofd_fmd_max_age);
292
293 /**
294  * Show if the OFD is in degraded mode.
295  *
296  * Degraded means OFD has a failed drive or is undergoing RAID rebuild.
297  * The MDS will try to avoid using this OST for new object allocations
298  * to reduce the impact to global IO performance when clients writing to
299  * this OST are slowed down.  It also reduces the contention on the OST
300  * RAID device, allowing it to rebuild more quickly.
301  *
302  * \param[in] m         seq_file handle
303  * \param[in] data      unused for single entry
304  *
305  * \retval              0 on success
306  * \retval              negative value on error
307  */
308 static int ofd_degraded_seq_show(struct seq_file *m, void *data)
309 {
310         struct obd_device *obd = m->private;
311         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
312
313         seq_printf(m, "%u\n", ofd->ofd_raid_degraded);
314         return 0;
315 }
316
317 /**
318  * Set OFD to degraded mode.
319  *
320  * This is used to interface to userspace administrative tools for
321  * the underlying RAID storage, so that they can mark an OST
322  * as having degraded performance.
323  *
324  * \param[in] file      proc file
325  * \param[in] buffer    string which represents mode
326  *                      1: set degraded mode
327  *                      0: unset degraded mode
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_degraded_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         int rc;
342         __s64 val;
343
344         rc = lprocfs_str_to_s64(buffer, count, &val);
345         if (rc)
346                 return rc;
347
348         spin_lock(&ofd->ofd_flags_lock);
349         ofd->ofd_raid_degraded = !!val;
350         spin_unlock(&ofd->ofd_flags_lock);
351         return count;
352 }
353 LPROC_SEQ_FOPS(ofd_degraded);
354
355 /**
356  * Show OFD filesystem type.
357  *
358  * \param[in] m         seq_file handle
359  * \param[in] data      unused for single entry
360  *
361  * \retval              0 on success
362  * \retval              negative value on error
363  */
364 static int ofd_fstype_seq_show(struct seq_file *m, void *data)
365 {
366         struct obd_device *obd = m->private;
367         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
368         struct lu_device  *d;
369
370         LASSERT(ofd->ofd_osd);
371         d = &ofd->ofd_osd->dd_lu_dev;
372         LASSERT(d->ld_type);
373         seq_printf(m, "%s\n", d->ld_type->ldt_name);
374         return 0;
375 }
376 LPROC_SEQ_FOPS_RO(ofd_fstype);
377
378 /**
379  * Show journal handling mode: synchronous or asynchronous.
380  *
381  * When running in asynchronous mode the journal transactions are not
382  * committed to disk before the RPC is replied back to the client.
383  * This will typically improve client performance when only a small number
384  * of clients are writing, since the client(s) can have more write RPCs
385  * in flight. However, it also means that the client has to handle recovery
386  * on bulk RPCs, and will have to keep more dirty pages in cache before they
387  * are committed on the OST.
388  *
389  * \param[in] m         seq_file handle
390  * \param[in] data      unused for single entry
391  *
392  * \retval              0 on success
393  * \retval              negative value on error
394  */
395 static int ofd_syncjournal_seq_show(struct seq_file *m, void *data)
396 {
397         struct obd_device       *obd = m->private;
398         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
399
400         seq_printf(m, "%u\n", ofd->ofd_syncjournal);
401         return 0;
402 }
403
404 /**
405  * Set journal mode to synchronous or asynchronous.
406  *
407  * \param[in] file      proc file
408  * \param[in] buffer    string which represents mode
409  *                      1: synchronous mode
410  *                      0: asynchronous mode
411  * \param[in] count     \a buffer length
412  * \param[in] off       unused for single entry
413  *
414  * \retval              \a count on success
415  * \retval              negative number on error
416  */
417 static ssize_t
418 ofd_syncjournal_seq_write(struct file *file, const char __user *buffer,
419                           size_t count, loff_t *off)
420 {
421         struct seq_file *m = file->private_data;
422         struct obd_device *obd = m->private;
423         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
424         __s64 val;
425         int rc;
426
427         rc = lprocfs_str_to_s64(buffer, count, &val);
428         if (rc)
429                 return rc;
430
431         if (val < 0)
432                 return -EINVAL;
433
434         spin_lock(&ofd->ofd_flags_lock);
435         ofd->ofd_syncjournal = !!val;
436         ofd_slc_set(ofd);
437         spin_unlock(&ofd->ofd_flags_lock);
438
439         return count;
440 }
441 LPROC_SEQ_FOPS(ofd_syncjournal);
442
443 /* This must be longer than the longest string below */
444 #define SYNC_STATES_MAXLEN 16
445
446 static int ofd_brw_size_seq_show(struct seq_file *m, void *data)
447 {
448         struct obd_device       *obd = m->private;
449         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
450
451         seq_printf(m, "%u\n", ofd->ofd_brw_size / ONE_MB_BRW_SIZE);
452         return 0;
453 }
454
455 static ssize_t
456 ofd_brw_size_seq_write(struct file *file, const char __user *buffer,
457                        size_t count, loff_t *off)
458 {
459         struct seq_file *m = file->private_data;
460         struct obd_device *obd = m->private;
461         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
462         __s64 val;
463         int rc;
464
465         rc = lprocfs_str_with_units_to_s64(buffer, count, &val, 'M');
466         if (rc)
467                 return rc;
468
469         if (val <= 0)
470                 return -EINVAL;
471
472         if (val > DT_MAX_BRW_SIZE ||
473             val < (1 << ofd->ofd_lut.lut_tgd.tgd_blockbits))
474                 return -ERANGE;
475
476         spin_lock(&ofd->ofd_flags_lock);
477         ofd->ofd_brw_size = val;
478         spin_unlock(&ofd->ofd_flags_lock);
479
480         return count;
481 }
482 LPROC_SEQ_FOPS(ofd_brw_size);
483
484 static char *sync_on_cancel_states[] = {"never",
485                                         "blocking",
486                                         "always" };
487
488 /**
489  * Show OFD policy for handling dirty data under a lock being cancelled.
490  *
491  * \param[in] m         seq_file handle
492  * \param[in] data      unused for single entry
493  *
494  * \retval              0 on success
495  * \retval              negative value on error
496  */
497 static int ofd_sync_lock_cancel_seq_show(struct seq_file *m, void *data)
498 {
499         struct obd_device       *obd = m->private;
500         struct lu_target        *tgt = obd->u.obt.obt_lut;
501
502         seq_printf(m, "%s\n",
503                    sync_on_cancel_states[tgt->lut_sync_lock_cancel]);
504         return 0;
505 }
506
507 /**
508  * Change OFD policy for handling dirty data under a lock being cancelled.
509  *
510  * This variable defines what action OFD takes upon lock cancel
511  * There are three possible modes:
512  * 1) never - never do sync upon lock cancel. This can lead to data
513  *    inconsistencies if both the OST and client crash while writing a file
514  *    that is also concurrently being read by another client. In these cases,
515  *    this may allow the file data to "rewind" to an earlier state.
516  * 2) blocking - do sync only if there is blocking lock, e.g. if another
517  *    client is trying to access this same object
518  * 3) always - do sync always
519  *
520  * \param[in] file      proc file
521  * \param[in] buffer    string which represents policy
522  * \param[in] count     \a buffer length
523  * \param[in] off       unused for single entry
524  *
525  * \retval              \a count on success
526  * \retval              negative number on error
527  */
528 static ssize_t
529 ofd_sync_lock_cancel_seq_write(struct file *file, const char __user *buffer,
530                                size_t count, loff_t *off)
531 {
532         struct seq_file *m = file->private_data;
533         struct obd_device *obd = m->private;
534         struct lu_target *tgt = obd->u.obt.obt_lut;
535         char kernbuf[SYNC_STATES_MAXLEN];
536         __s64 val = -1;
537         int i;
538
539         if (count == 0 || count >= sizeof(kernbuf))
540                 return -EINVAL;
541
542         if (copy_from_user(kernbuf, buffer, count))
543                 return -EFAULT;
544         kernbuf[count] = 0;
545
546         if (kernbuf[count - 1] == '\n')
547                 kernbuf[count - 1] = 0;
548
549         for (i = 0 ; i < NUM_SYNC_ON_CANCEL_STATES; i++) {
550                 if (strcmp(kernbuf, sync_on_cancel_states[i]) == 0) {
551                         val = i;
552                         break;
553                 }
554         }
555
556         /* Legacy numeric codes */
557         if (val == -1) {
558                 int rc = lprocfs_str_to_s64(buffer, count, &val);
559                 if (rc)
560                         return rc;
561         }
562
563         if (val < 0 || val > 2)
564                 return -EINVAL;
565
566         spin_lock(&tgt->lut_flags_lock);
567         tgt->lut_sync_lock_cancel = val;
568         spin_unlock(&tgt->lut_flags_lock);
569         return count;
570 }
571 LPROC_SEQ_FOPS(ofd_sync_lock_cancel);
572
573 /**
574  * Show the limit of soft sync RPCs.
575  *
576  * This value defines how many IO RPCs with OBD_BRW_SOFT_SYNC flag
577  * are allowed before sync update will be triggered.
578  *
579  * \param[in] m         seq_file handle
580  * \param[in] data      unused for single entry
581  *
582  * \retval              0 on success
583  * \retval              negative value on error
584  */
585 static int ofd_soft_sync_limit_seq_show(struct seq_file *m, void *data)
586 {
587         struct obd_device       *obd = m->private;
588         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
589
590         return lprocfs_uint_seq_show(m, &ofd->ofd_soft_sync_limit);
591 }
592
593 /**
594  * Change the limit of soft sync RPCs.
595  *
596  * Define how many IO RPCs with OBD_BRW_SOFT_SYNC flag
597  * allowed before sync update will be done.
598  *
599  * This limit is global across all exports.
600  *
601  * \param[in] file      proc file
602  * \param[in] buffer    string which represents limit
603  * \param[in] count     \a buffer length
604  * \param[in] off       unused for single entry
605  *
606  * \retval              \a count on success
607  * \retval              negative number on error
608  */
609 static ssize_t
610 ofd_soft_sync_limit_seq_write(struct file *file, const char __user *buffer,
611                               size_t count, loff_t *off)
612 {
613         struct seq_file   *m = file->private_data;
614         struct obd_device *obd = m->private;
615         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
616
617         return lprocfs_uint_seq_write(file, buffer, count,
618                                       (loff_t *) &ofd->ofd_soft_sync_limit);
619 }
620 LPROC_SEQ_FOPS(ofd_soft_sync_limit);
621
622 /**
623  * Show the LFSCK speed limit.
624  *
625  * The maximum number of items scanned per second.
626  *
627  * \param[in] m         seq_file handle
628  * \param[in] data      unused for single entry
629  *
630  * \retval              0 on success
631  * \retval              negative value on error
632  */
633 static int ofd_lfsck_speed_limit_seq_show(struct seq_file *m, void *data)
634 {
635         struct obd_device       *obd = m->private;
636         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
637
638         return lfsck_get_speed(m, ofd->ofd_osd);
639 }
640
641 /**
642  * Change the LFSCK speed limit.
643  *
644  * Limit number of items that may be scanned per second.
645  *
646  * \param[in] file      proc file
647  * \param[in] buffer    string which represents limit
648  * \param[in] count     \a buffer length
649  * \param[in] off       unused for single entry
650  *
651  * \retval              \a count on success
652  * \retval              negative number on error
653  */
654 static ssize_t
655 ofd_lfsck_speed_limit_seq_write(struct file *file, const char __user *buffer,
656                                 size_t count, loff_t *off)
657 {
658         struct seq_file *m = file->private_data;
659         struct obd_device *obd = m->private;
660         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
661         __s64 val;
662         int rc;
663
664         rc = lprocfs_str_to_s64(buffer, count, &val);
665         if (rc != 0)
666                 return rc;
667
668         if (val < 0)
669                 return -ERANGE;
670
671         rc = lfsck_set_speed(ofd->ofd_osd, val);
672
673         return rc != 0 ? rc : count;
674 }
675 LPROC_SEQ_FOPS(ofd_lfsck_speed_limit);
676
677 /**
678  * Show LFSCK layout verification stats from the most recent LFSCK run.
679  *
680  * \param[in] m         seq_file handle
681  * \param[in] data      unused for single entry
682  *
683  * \retval              0 on success
684  * \retval              negative value on error
685  */
686 static int ofd_lfsck_layout_seq_show(struct seq_file *m, void *data)
687 {
688         struct obd_device *obd = m->private;
689         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
690
691         return lfsck_dump(m, ofd->ofd_osd, LFSCK_TYPE_LAYOUT);
692 }
693 LPROC_SEQ_FOPS_RO(ofd_lfsck_layout);
694
695 /**
696  * Show if LFSCK performed parent FID verification.
697  *
698  * \param[in] m         seq_file handle
699  * \param[in] data      unused for single entry
700  *
701  * \retval              0 on success
702  * \retval              negative value on error
703  */
704 static int ofd_lfsck_verify_pfid_seq_show(struct seq_file *m, void *data)
705 {
706         struct obd_device *obd = m->private;
707         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
708
709         seq_printf(m, "switch: %s\ndetected: %llu\nrepaired: %llu\n",
710                    ofd->ofd_lfsck_verify_pfid ? "on" : "off",
711                    ofd->ofd_inconsistency_self_detected,
712                    ofd->ofd_inconsistency_self_repaired);
713         return 0;
714 }
715
716 /**
717  * Set the LFSCK behavior to verify parent FID correctness.
718  *
719  * If flag ofd_lfsck_verify_pfid is set then LFSCK does parent FID
720  * verification during read/write operations.
721  *
722  * \param[in] file      proc file
723  * \param[in] buffer    string which represents behavior
724  *                      1: verify parent FID
725  *                      0: don't verify parent FID
726  * \param[in] count     \a buffer length
727  * \param[in] off       unused for single entry
728  *
729  * \retval              \a count on success
730  * \retval              negative number on error
731  */
732 static ssize_t
733 ofd_lfsck_verify_pfid_seq_write(struct file *file, const char __user *buffer,
734                                 size_t count, loff_t *off)
735 {
736         struct seq_file *m = file->private_data;
737         struct obd_device *obd = m->private;
738         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
739         __s64 val;
740         int rc;
741
742         rc = lprocfs_str_to_s64(buffer, count, &val);
743         if (rc != 0)
744                 return rc;
745
746         ofd->ofd_lfsck_verify_pfid = !!val;
747         if (!ofd->ofd_lfsck_verify_pfid) {
748                 ofd->ofd_inconsistency_self_detected = 0;
749                 ofd->ofd_inconsistency_self_repaired = 0;
750         }
751
752         return count;
753 }
754 LPROC_SEQ_FOPS(ofd_lfsck_verify_pfid);
755
756 static int ofd_site_stats_seq_show(struct seq_file *m, void *data)
757 {
758         struct obd_device *obd = m->private;
759
760         return lu_site_stats_seq_print(obd->obd_lu_dev->ld_site, m);
761 }
762 LPROC_SEQ_FOPS_RO(ofd_site_stats);
763
764 LPROC_SEQ_FOPS_RO_TYPE(ofd, recovery_status);
765 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_soft);
766 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_hard);
767 LPROC_SEQ_FOPS_WR_ONLY(ofd, evict_client);
768 LPROC_SEQ_FOPS_RO_TYPE(ofd, num_exports);
769 LPROC_SEQ_FOPS_RO_TYPE(ofd, target_instance);
770 LPROC_SEQ_FOPS_RW_TYPE(ofd, ir_factor);
771 LPROC_SEQ_FOPS_RW_TYPE(ofd, checksum_dump);
772 LPROC_SEQ_FOPS_RW_TYPE(ofd, job_interval);
773
774 LPROC_SEQ_FOPS_RO(tgt_tot_dirty);
775 LPROC_SEQ_FOPS_RO(tgt_tot_granted);
776 LPROC_SEQ_FOPS_RO(tgt_tot_pending);
777 LPROC_SEQ_FOPS(tgt_grant_compat_disable);
778
779 struct lprocfs_vars lprocfs_ofd_obd_vars[] = {
780         { .name =       "seqs_allocated",
781           .fops =       &ofd_seqs_fops                  },
782         { .name =       "fstype",
783           .fops =       &ofd_fstype_fops                },
784         { .name =       "last_id",
785           .fops =       &ofd_last_id_fops               },
786         { .name =       "tot_dirty",
787           .fops =       &tgt_tot_dirty_fops             },
788         { .name =       "tot_pending",
789           .fops =       &tgt_tot_pending_fops           },
790         { .name =       "tot_granted",
791           .fops =       &tgt_tot_granted_fops           },
792         { .name =       "grant_precreate",
793           .fops =       &ofd_grant_precreate_fops       },
794         { .name =       "precreate_batch",
795           .fops =       &ofd_precreate_batch_fops       },
796         { .name =       "recovery_status",
797           .fops =       &ofd_recovery_status_fops       },
798         { .name =       "recovery_time_soft",
799           .fops =       &ofd_recovery_time_soft_fops    },
800         { .name =       "recovery_time_hard",
801           .fops =       &ofd_recovery_time_hard_fops    },
802         { .name =       "evict_client",
803           .fops =       &ofd_evict_client_fops          },
804         { .name =       "num_exports",
805           .fops =       &ofd_num_exports_fops           },
806         { .name =       "degraded",
807           .fops =       &ofd_degraded_fops              },
808         { .name =       "sync_journal",
809           .fops =       &ofd_syncjournal_fops           },
810         { .name =       "brw_size",
811           .fops =       &ofd_brw_size_fops              },
812         { .name =       "sync_on_lock_cancel",
813           .fops =       &ofd_sync_lock_cancel_fops      },
814         { .name =       "instance",
815           .fops =       &ofd_target_instance_fops       },
816         { .name =       "ir_factor",
817           .fops =       &ofd_ir_factor_fops             },
818         { .name =       "checksum_dump",
819           .fops =       &ofd_checksum_dump_fops         },
820         { .name =       "grant_compat_disable",
821           .fops =       &tgt_grant_compat_disable_fops  },
822         { .name =       "client_cache_count",
823           .fops =       &ofd_fmd_max_num_fops           },
824         { .name =       "client_cache_seconds",
825           .fops =       &ofd_fmd_max_age_fops           },
826         { .name =       "job_cleanup_interval",
827           .fops =       &ofd_job_interval_fops          },
828         { .name =       "soft_sync_limit",
829           .fops =       &ofd_soft_sync_limit_fops       },
830         { .name =       "lfsck_speed_limit",
831           .fops =       &ofd_lfsck_speed_limit_fops     },
832         { .name =       "lfsck_layout",
833           .fops =       &ofd_lfsck_layout_fops          },
834         { .name =       "lfsck_verify_pfid",
835           .fops =       &ofd_lfsck_verify_pfid_fops     },
836         { .name =       "site_stats",
837           .fops =       &ofd_site_stats_fops            },
838         { NULL }
839 };
840
841 /**
842  * Initialize OFD statistics counters
843  *
844  * param[in] stats      statistics counters
845  */
846 void ofd_stats_counter_init(struct lprocfs_stats *stats)
847 {
848         LASSERT(stats && stats->ls_num >= LPROC_OFD_STATS_LAST);
849
850         lprocfs_counter_init(stats, LPROC_OFD_STATS_READ,
851                              LPROCFS_CNTR_AVGMINMAX, "read_bytes", "bytes");
852         lprocfs_counter_init(stats, LPROC_OFD_STATS_WRITE,
853                              LPROCFS_CNTR_AVGMINMAX, "write_bytes", "bytes");
854         lprocfs_counter_init(stats, LPROC_OFD_STATS_GETATTR,
855                              0, "getattr", "reqs");
856         lprocfs_counter_init(stats, LPROC_OFD_STATS_SETATTR,
857                              0, "setattr", "reqs");
858         lprocfs_counter_init(stats, LPROC_OFD_STATS_PUNCH,
859                              0, "punch", "reqs");
860         lprocfs_counter_init(stats, LPROC_OFD_STATS_SYNC,
861                              0, "sync", "reqs");
862         lprocfs_counter_init(stats, LPROC_OFD_STATS_DESTROY,
863                              0, "destroy", "reqs");
864         lprocfs_counter_init(stats, LPROC_OFD_STATS_CREATE,
865                              0, "create", "reqs");
866         lprocfs_counter_init(stats, LPROC_OFD_STATS_STATFS,
867                              0, "statfs", "reqs");
868         lprocfs_counter_init(stats, LPROC_OFD_STATS_GET_INFO,
869                              0, "get_info", "reqs");
870         lprocfs_counter_init(stats, LPROC_OFD_STATS_SET_INFO,
871                              0, "set_info", "reqs");
872         lprocfs_counter_init(stats, LPROC_OFD_STATS_QUOTACTL,
873                              0, "quotactl", "reqs");
874 }
875
876 #endif /* CONFIG_PROC_FS */