Whamcloud - gitweb
LU-6215 lprocfs: handle seq_printf api change
[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, 2014 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 ofd_device *ofd;
85
86         LASSERT(obd != NULL);
87         ofd = ofd_dev(obd->obd_lu_dev);
88         seq_printf(m, LPU64"\n", ofd->ofd_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 ofd_device *ofd;
106
107         LASSERT(obd != NULL);
108         ofd = ofd_dev(obd->obd_lu_dev);
109         seq_printf(m, LPU64"\n", ofd->ofd_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 ofd_device *ofd;
127
128         LASSERT(obd != NULL);
129         ofd = ofd_dev(obd->obd_lu_dev);
130         seq_printf(m, LPU64"\n", ofd->ofd_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_filter_data.fed_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         int val;
194         int rc;
195
196         rc = lprocfs_write_helper(buffer, count, &val);
197         if (rc)
198                 return rc;
199
200         if (val < 1)
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         int                      val;
284         int                      rc;
285
286         rc = lprocfs_write_helper(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         int                      val;
342         int                      rc;
343
344         rc = lprocfs_write_helper(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                      val, rc;
405
406         rc = lprocfs_write_helper(buffer, count, &val);
407         if (rc)
408                 return rc;
409
410         spin_lock(&ofd->ofd_flags_lock);
411         ofd->ofd_raid_degraded = !!val;
412         spin_unlock(&ofd->ofd_flags_lock);
413         return count;
414 }
415 LPROC_SEQ_FOPS(ofd_degraded);
416
417 /**
418  * Show OFD filesystem type.
419  *
420  * \param[in] m         seq_file handle
421  * \param[in] data      unused for single entry
422  *
423  * \retval              0 on success
424  * \retval              negative value on error
425  */
426 static int ofd_fstype_seq_show(struct seq_file *m, void *data)
427 {
428         struct obd_device *obd = m->private;
429         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
430         struct lu_device  *d;
431
432         LASSERT(ofd->ofd_osd);
433         d = &ofd->ofd_osd->dd_lu_dev;
434         LASSERT(d->ld_type);
435         seq_printf(m, "%s\n", d->ld_type->ldt_name);
436         return 0;
437 }
438 LPROC_SEQ_FOPS_RO(ofd_fstype);
439
440 /**
441  * Show journal handling mode: synchronous or asynchronous.
442  *
443  * When running in asynchronous mode the journal transactions are not
444  * committed to disk before the RPC is replied back to the client.
445  * This will typically improve client performance when only a small number
446  * of clients are writing, since the client(s) can have more write RPCs
447  * in flight. However, it also means that the client has to handle recovery
448  * on bulk RPCs, and will have to keep more dirty pages in cache before they
449  * are committed on the OST.
450  *
451  * \param[in] m         seq_file handle
452  * \param[in] data      unused for single entry
453  *
454  * \retval              0 on success
455  * \retval              negative value on error
456  */
457 static int ofd_syncjournal_seq_show(struct seq_file *m, void *data)
458 {
459         struct obd_device       *obd = m->private;
460         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
461
462         seq_printf(m, "%u\n", ofd->ofd_syncjournal);
463         return 0;
464 }
465
466 /**
467  * Set journal mode to synchronous or asynchronous.
468  *
469  * \param[in] file      proc file
470  * \param[in] buffer    string which represents mode
471  *                      1: synchronous mode
472  *                      0: asynchronous mode
473  * \param[in] count     \a buffer length
474  * \param[in] off       unused for single entry
475  *
476  * \retval              \a count on success
477  * \retval              negative number on error
478  */
479 static ssize_t
480 ofd_syncjournal_seq_write(struct file *file, const char __user *buffer,
481                           size_t count, loff_t *off)
482 {
483         struct seq_file         *m = file->private_data;
484         struct obd_device       *obd = m->private;
485         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
486         int                      val;
487         int                      rc;
488
489         rc = lprocfs_write_helper(buffer, count, &val);
490         if (rc)
491                 return rc;
492
493         if (val < 0)
494                 return -EINVAL;
495
496         spin_lock(&ofd->ofd_flags_lock);
497         ofd->ofd_syncjournal = !!val;
498         ofd_slc_set(ofd);
499         spin_unlock(&ofd->ofd_flags_lock);
500
501         return count;
502 }
503 LPROC_SEQ_FOPS(ofd_syncjournal);
504
505 /* This must be longer than the longest string below */
506 #define SYNC_STATES_MAXLEN 16
507 static char *sync_on_cancel_states[] = {"never",
508                                         "blocking",
509                                         "always" };
510
511 /**
512  * Show OFD policy for handling dirty data under a lock being cancelled.
513  *
514  * \param[in] m         seq_file handle
515  * \param[in] data      unused for single entry
516  *
517  * \retval              0 on success
518  * \retval              negative value on error
519  */
520 static int ofd_sync_lock_cancel_seq_show(struct seq_file *m, void *data)
521 {
522         struct obd_device       *obd = m->private;
523         struct lu_target        *tgt = obd->u.obt.obt_lut;
524
525         seq_printf(m, "%s\n",
526                    sync_on_cancel_states[tgt->lut_sync_lock_cancel]);
527         return 0;
528 }
529
530 /**
531  * Change OFD policy for handling dirty data under a lock being cancelled.
532  *
533  * This variable defines what action OFD takes upon lock cancel
534  * There are three possible modes:
535  * 1) never - never do sync upon lock cancel. This can lead to data
536  *    inconsistencies if both the OST and client crash while writing a file
537  *    that is also concurrently being read by another client. In these cases,
538  *    this may allow the file data to "rewind" to an earlier state.
539  * 2) blocking - do sync only if there is blocking lock, e.g. if another
540  *    client is trying to access this same object
541  * 3) always - do sync always
542  *
543  * \param[in] file      proc file
544  * \param[in] buffer    string which represents policy
545  * \param[in] count     \a buffer length
546  * \param[in] off       unused for single entry
547  *
548  * \retval              \a count on success
549  * \retval              negative number on error
550  */
551 static ssize_t
552 ofd_sync_lock_cancel_seq_write(struct file *file, const char __user *buffer,
553                                size_t count, loff_t *off)
554 {
555         struct seq_file         *m = file->private_data;
556         struct obd_device       *obd = m->private;
557         struct lu_target        *tgt = obd->u.obt.obt_lut;
558         char                     kernbuf[SYNC_STATES_MAXLEN];
559         int                      val = -1;
560         int                      i;
561
562         if (count == 0 || count >= sizeof(kernbuf))
563                 return -EINVAL;
564
565         if (copy_from_user(kernbuf, buffer, count))
566                 return -EFAULT;
567         kernbuf[count] = 0;
568
569         if (kernbuf[count - 1] == '\n')
570                 kernbuf[count - 1] = 0;
571
572         for (i = 0 ; i < NUM_SYNC_ON_CANCEL_STATES; i++) {
573                 if (strcmp(kernbuf, sync_on_cancel_states[i]) == 0) {
574                         val = i;
575                         break;
576                 }
577         }
578
579         /* Legacy numeric codes */
580         if (val == -1) {
581                 int rc;
582
583                 /* Safe to use userspace buffer as lprocfs_write_helper will
584                  * use copy from user for parsing */
585                 rc = lprocfs_write_helper(buffer, count, &val);
586                 if (rc)
587                         return rc;
588         }
589
590         if (val < 0 || val > 2)
591                 return -EINVAL;
592
593         spin_lock(&tgt->lut_flags_lock);
594         tgt->lut_sync_lock_cancel = val;
595         spin_unlock(&tgt->lut_flags_lock);
596         return count;
597 }
598 LPROC_SEQ_FOPS(ofd_sync_lock_cancel);
599
600 /**
601  * Show if grants compatibility mode is disabled.
602  *
603  * When ofd_grant_compat_disable is set, we don't grant any space to clients
604  * not supporting OBD_CONNECT_GRANT_PARAM. Otherwise, space granted to such
605  * a client is inflated since it consumes PAGE_CACHE_SIZE of grant space per
606  * block, (i.e. typically 4kB units), but underlaying file system might have
607  * block size bigger than page size, e.g. ZFS. See LU-2049 for details.
608  *
609  * \param[in] m         seq_file handle
610  * \param[in] data      unused for single entry
611  *
612  * \retval              0 on success
613  * \retval              negative value on error
614  */
615 static int ofd_grant_compat_disable_seq_show(struct seq_file *m, void *data)
616 {
617         struct obd_device *obd = m->private;
618         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
619
620         seq_printf(m, "%u\n", ofd->ofd_grant_compat_disable);
621         return 0;
622 }
623
624 /**
625  * Change grant compatibility mode.
626  *
627  * Setting ofd_grant_compat_disable prohibit any space granting to clients
628  * not supporting OBD_CONNECT_GRANT_PARAM. See details above.
629  *
630  * \param[in] file      proc file
631  * \param[in] buffer    string which represents mode
632  *                      1: disable compatibility mode
633  *                      0: enable compatibility mode
634  * \param[in] count     \a buffer length
635  * \param[in] off       unused for single entry
636  *
637  * \retval              \a count on success
638  * \retval              negative number on error
639  */
640 static ssize_t
641 ofd_grant_compat_disable_seq_write(struct file *file,
642                                    const char __user *buffer,
643                                    size_t count, loff_t *off)
644 {
645         struct seq_file         *m = file->private_data;
646         struct obd_device       *obd = m->private;
647         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
648         int                      val;
649         int                      rc;
650
651         rc = lprocfs_write_helper(buffer, count, &val);
652         if (rc)
653                 return rc;
654
655         if (val < 0)
656                 return -EINVAL;
657
658         spin_lock(&ofd->ofd_flags_lock);
659         ofd->ofd_grant_compat_disable = !!val;
660         spin_unlock(&ofd->ofd_flags_lock);
661
662         return count;
663 }
664 LPROC_SEQ_FOPS(ofd_grant_compat_disable);
665
666 /**
667  * Show the limit of soft sync RPCs.
668  *
669  * This value defines how many IO RPCs with OBD_BRW_SOFT_SYNC flag
670  * are allowed before sync update will be triggered.
671  *
672  * \param[in] m         seq_file handle
673  * \param[in] data      unused for single entry
674  *
675  * \retval              0 on success
676  * \retval              negative value on error
677  */
678 static int ofd_soft_sync_limit_seq_show(struct seq_file *m, void *data)
679 {
680         struct obd_device       *obd = m->private;
681         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
682
683         return lprocfs_uint_seq_show(m, &ofd->ofd_soft_sync_limit);
684 }
685
686 /**
687  * Change the limit of soft sync RPCs.
688  *
689  * Define how many IO RPCs with OBD_BRW_SOFT_SYNC flag
690  * allowed before sync update will be done.
691  *
692  * This limit is global across all exports.
693  *
694  * \param[in] file      proc file
695  * \param[in] buffer    string which represents limit
696  * \param[in] count     \a buffer length
697  * \param[in] off       unused for single entry
698  *
699  * \retval              \a count on success
700  * \retval              negative number on error
701  */
702 static ssize_t
703 ofd_soft_sync_limit_seq_write(struct file *file, const char __user *buffer,
704                               size_t count, loff_t *off)
705 {
706         struct seq_file   *m = file->private_data;
707         struct obd_device *obd = m->private;
708         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
709
710         return lprocfs_uint_seq_write(file, buffer, count,
711                                       (loff_t *) &ofd->ofd_soft_sync_limit);
712 }
713 LPROC_SEQ_FOPS(ofd_soft_sync_limit);
714
715 /**
716  * Show the LFSCK speed limit.
717  *
718  * The maximum number of items scanned per second.
719  *
720  * \param[in] m         seq_file handle
721  * \param[in] data      unused for single entry
722  *
723  * \retval              0 on success
724  * \retval              negative value on error
725  */
726 static int ofd_lfsck_speed_limit_seq_show(struct seq_file *m, void *data)
727 {
728         struct obd_device       *obd = m->private;
729         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
730
731         return lfsck_get_speed(m, ofd->ofd_osd);
732 }
733
734 /**
735  * Change the LFSCK speed limit.
736  *
737  * Limit number of items that may be scanned per second.
738  *
739  * \param[in] file      proc file
740  * \param[in] buffer    string which represents limit
741  * \param[in] count     \a buffer length
742  * \param[in] off       unused for single entry
743  *
744  * \retval              \a count on success
745  * \retval              negative number on error
746  */
747 static ssize_t
748 ofd_lfsck_speed_limit_seq_write(struct file *file, const char __user *buffer,
749                                 size_t count, loff_t *off)
750 {
751         struct seq_file         *m = file->private_data;
752         struct obd_device       *obd = m->private;
753         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
754         __u32                    val;
755         int                      rc;
756
757         rc = lprocfs_write_helper(buffer, count, &val);
758         if (rc != 0)
759                 return rc;
760
761         rc = lfsck_set_speed(ofd->ofd_osd, val);
762
763         return rc != 0 ? rc : count;
764 }
765 LPROC_SEQ_FOPS(ofd_lfsck_speed_limit);
766
767 /**
768  * Show LFSCK layout verification stats from the most recent LFSCK run.
769  *
770  * \param[in] m         seq_file handle
771  * \param[in] data      unused for single entry
772  *
773  * \retval              0 on success
774  * \retval              negative value on error
775  */
776 static int ofd_lfsck_layout_seq_show(struct seq_file *m, void *data)
777 {
778         struct obd_device *obd = m->private;
779         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
780
781         return lfsck_dump(m, ofd->ofd_osd, LFSCK_TYPE_LAYOUT);
782 }
783 LPROC_SEQ_FOPS_RO(ofd_lfsck_layout);
784
785 /**
786  * Show if LFSCK performed parent FID verification.
787  *
788  * \param[in] m         seq_file handle
789  * \param[in] data      unused for single entry
790  *
791  * \retval              0 on success
792  * \retval              negative value on error
793  */
794 static int ofd_lfsck_verify_pfid_seq_show(struct seq_file *m, void *data)
795 {
796         struct obd_device *obd = m->private;
797         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
798
799         seq_printf(m, "switch: %s\ndetected: "LPU64"\nrepaired: "LPU64"\n",
800                    ofd->ofd_lfsck_verify_pfid ? "on" : "off",
801                    ofd->ofd_inconsistency_self_detected,
802                    ofd->ofd_inconsistency_self_repaired);
803         return 0;
804 }
805
806 /**
807  * Set the LFSCK behavior to verify parent FID correctness.
808  *
809  * If flag ofd_lfsck_verify_pfid is set then LFSCK does parent FID
810  * verification during read/write operations.
811  *
812  * \param[in] file      proc file
813  * \param[in] buffer    string which represents behavior
814  *                      1: verify parent FID
815  *                      0: don't verify parent FID
816  * \param[in] count     \a buffer length
817  * \param[in] off       unused for single entry
818  *
819  * \retval              \a count on success
820  * \retval              negative number on error
821  */
822 static ssize_t
823 ofd_lfsck_verify_pfid_seq_write(struct file *file, const char __user *buffer,
824                                 size_t count, loff_t *off)
825 {
826         struct seq_file         *m = file->private_data;
827         struct obd_device       *obd = m->private;
828         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
829         __u32                    val;
830         int                      rc;
831
832         rc = lprocfs_write_helper(buffer, count, &val);
833         if (rc != 0)
834                 return rc;
835
836         ofd->ofd_lfsck_verify_pfid = !!val;
837
838         return count;
839 }
840 LPROC_SEQ_FOPS(ofd_lfsck_verify_pfid);
841
842 LPROC_SEQ_FOPS_RO_TYPE(ofd, uuid);
843 LPROC_SEQ_FOPS_RO_TYPE(ofd, blksize);
844 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytestotal);
845 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesfree);
846 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesavail);
847 LPROC_SEQ_FOPS_RO_TYPE(ofd, filestotal);
848 LPROC_SEQ_FOPS_RO_TYPE(ofd, filesfree);
849
850 LPROC_SEQ_FOPS_RO_TYPE(ofd, recovery_status);
851 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_soft);
852 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_hard);
853 LPROC_SEQ_FOPS_WO_TYPE(ofd, evict_client);
854 LPROC_SEQ_FOPS_RO_TYPE(ofd, num_exports);
855 LPROC_SEQ_FOPS_RO_TYPE(ofd, target_instance);
856 LPROC_SEQ_FOPS_RW_TYPE(ofd, ir_factor);
857 LPROC_SEQ_FOPS_RW_TYPE(ofd, job_interval);
858
859 struct lprocfs_vars lprocfs_ofd_obd_vars[] = {
860         { .name =       "uuid",
861           .fops =       &ofd_uuid_fops                  },
862         { .name =       "blocksize",
863           .fops =       &ofd_blksize_fops               },
864         { .name =       "kbytestotal",
865           .fops =       &ofd_kbytestotal_fops           },
866         { .name =       "kbytesfree",
867           .fops =       &ofd_kbytesfree_fops            },
868         { .name =       "kbytesavail",
869           .fops =       &ofd_kbytesavail_fops           },
870         { .name =       "filestotal",
871           .fops =       &ofd_filestotal_fops            },
872         { .name =       "filesfree",
873           .fops =       &ofd_filesfree_fops             },
874         { .name =       "seqs_allocated",
875           .fops =       &ofd_seqs_fops                  },
876         { .name =       "fstype",
877           .fops =       &ofd_fstype_fops                },
878         { .name =       "last_id",
879           .fops =       &ofd_last_id_fops               },
880         { .name =       "tot_dirty",
881           .fops =       &ofd_tot_dirty_fops             },
882         { .name =       "tot_pending",
883           .fops =       &ofd_tot_pending_fops           },
884         { .name =       "tot_granted",
885           .fops =       &ofd_tot_granted_fops           },
886         { .name =       "grant_precreate",
887           .fops =       &ofd_grant_precreate_fops       },
888         { .name =       "precreate_batch",
889           .fops =       &ofd_precreate_batch_fops       },
890         { .name =       "recovery_status",
891           .fops =       &ofd_recovery_status_fops       },
892         { .name =       "recovery_time_soft",
893           .fops =       &ofd_recovery_time_soft_fops    },
894         { .name =       "recovery_time_hard",
895           .fops =       &ofd_recovery_time_hard_fops    },
896         { .name =       "evict_client",
897           .fops =       &ofd_evict_client_fops          },
898         { .name =       "num_exports",
899           .fops =       &ofd_num_exports_fops           },
900         { .name =       "degraded",
901           .fops =       &ofd_degraded_fops              },
902         { .name =       "sync_journal",
903           .fops =       &ofd_syncjournal_fops           },
904         { .name =       "sync_on_lock_cancel",
905           .fops =       &ofd_sync_lock_cancel_fops      },
906         { .name =       "instance",
907           .fops =       &ofd_target_instance_fops       },
908         { .name =       "ir_factor",
909           .fops =       &ofd_ir_factor_fops             },
910         { .name =       "grant_compat_disable",
911           .fops =       &ofd_grant_compat_disable_fops  },
912         { .name =       "client_cache_count",
913           .fops =       &ofd_fmd_max_num_fops           },
914         { .name =       "client_cache_seconds",
915           .fops =       &ofd_fmd_max_age_fops           },
916         { .name =       "job_cleanup_interval",
917           .fops =       &ofd_job_interval_fops          },
918         { .name =       "soft_sync_limit",
919           .fops =       &ofd_soft_sync_limit_fops       },
920         { .name =       "lfsck_speed_limit",
921           .fops =       &ofd_lfsck_speed_limit_fops     },
922         { .name =       "lfsck_layout",
923           .fops =       &ofd_lfsck_layout_fops          },
924         { .name =       "lfsck_verify_pfid",
925           .fops =       &ofd_lfsck_verify_pfid_fops     },
926         { NULL }
927 };
928
929 /**
930  * Initialize OFD statistics counters
931  *
932  * param[in] stats      statistics counters
933  */
934 void ofd_stats_counter_init(struct lprocfs_stats *stats)
935 {
936         LASSERT(stats && stats->ls_num >= LPROC_OFD_STATS_LAST);
937
938         lprocfs_counter_init(stats, LPROC_OFD_STATS_READ,
939                              LPROCFS_CNTR_AVGMINMAX, "read_bytes", "bytes");
940         lprocfs_counter_init(stats, LPROC_OFD_STATS_WRITE,
941                              LPROCFS_CNTR_AVGMINMAX, "write_bytes", "bytes");
942         lprocfs_counter_init(stats, LPROC_OFD_STATS_GETATTR,
943                              0, "getattr", "reqs");
944         lprocfs_counter_init(stats, LPROC_OFD_STATS_SETATTR,
945                              0, "setattr", "reqs");
946         lprocfs_counter_init(stats, LPROC_OFD_STATS_PUNCH,
947                              0, "punch", "reqs");
948         lprocfs_counter_init(stats, LPROC_OFD_STATS_SYNC,
949                              0, "sync", "reqs");
950         lprocfs_counter_init(stats, LPROC_OFD_STATS_DESTROY,
951                              0, "destroy", "reqs");
952         lprocfs_counter_init(stats, LPROC_OFD_STATS_CREATE,
953                              0, "create", "reqs");
954         lprocfs_counter_init(stats, LPROC_OFD_STATS_STATFS,
955                              0, "statfs", "reqs");
956         lprocfs_counter_init(stats, LPROC_OFD_STATS_GET_INFO,
957                              0, "get_info", "reqs");
958         lprocfs_counter_init(stats, LPROC_OFD_STATS_SET_INFO,
959                              0, "set_info", "reqs");
960         lprocfs_counter_init(stats, LPROC_OFD_STATS_QUOTACTL,
961                              0, "quotactl", "reqs");
962 }
963
964 #endif /* CONFIG_PROC_FS */