Whamcloud - gitweb
LU-8054 lfsck: enhance lfsck notify API
[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 ofd_device *ofd;
85
86         LASSERT(obd != NULL);
87         ofd = ofd_dev(obd->obd_lu_dev);
88         seq_printf(m, "%llu\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, "%llu\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, "%llu\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         __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 || val < (1 << ofd->ofd_blockbits))
536                 return -ERANGE;
537
538         spin_lock(&ofd->ofd_flags_lock);
539         ofd->ofd_brw_size = val;
540         spin_unlock(&ofd->ofd_flags_lock);
541
542         return count;
543 }
544 LPROC_SEQ_FOPS(ofd_brw_size);
545
546 static char *sync_on_cancel_states[] = {"never",
547                                         "blocking",
548                                         "always" };
549
550 /**
551  * Show OFD policy for handling dirty data under a lock being cancelled.
552  *
553  * \param[in] m         seq_file handle
554  * \param[in] data      unused for single entry
555  *
556  * \retval              0 on success
557  * \retval              negative value on error
558  */
559 static int ofd_sync_lock_cancel_seq_show(struct seq_file *m, void *data)
560 {
561         struct obd_device       *obd = m->private;
562         struct lu_target        *tgt = obd->u.obt.obt_lut;
563
564         seq_printf(m, "%s\n",
565                    sync_on_cancel_states[tgt->lut_sync_lock_cancel]);
566         return 0;
567 }
568
569 /**
570  * Change OFD policy for handling dirty data under a lock being cancelled.
571  *
572  * This variable defines what action OFD takes upon lock cancel
573  * There are three possible modes:
574  * 1) never - never do sync upon lock cancel. This can lead to data
575  *    inconsistencies if both the OST and client crash while writing a file
576  *    that is also concurrently being read by another client. In these cases,
577  *    this may allow the file data to "rewind" to an earlier state.
578  * 2) blocking - do sync only if there is blocking lock, e.g. if another
579  *    client is trying to access this same object
580  * 3) always - do sync always
581  *
582  * \param[in] file      proc file
583  * \param[in] buffer    string which represents policy
584  * \param[in] count     \a buffer length
585  * \param[in] off       unused for single entry
586  *
587  * \retval              \a count on success
588  * \retval              negative number on error
589  */
590 static ssize_t
591 ofd_sync_lock_cancel_seq_write(struct file *file, const char __user *buffer,
592                                size_t count, loff_t *off)
593 {
594         struct seq_file *m = file->private_data;
595         struct obd_device *obd = m->private;
596         struct lu_target *tgt = obd->u.obt.obt_lut;
597         char kernbuf[SYNC_STATES_MAXLEN];
598         __s64 val = -1;
599         int i;
600
601         if (count == 0 || count >= sizeof(kernbuf))
602                 return -EINVAL;
603
604         if (copy_from_user(kernbuf, buffer, count))
605                 return -EFAULT;
606         kernbuf[count] = 0;
607
608         if (kernbuf[count - 1] == '\n')
609                 kernbuf[count - 1] = 0;
610
611         for (i = 0 ; i < NUM_SYNC_ON_CANCEL_STATES; i++) {
612                 if (strcmp(kernbuf, sync_on_cancel_states[i]) == 0) {
613                         val = i;
614                         break;
615                 }
616         }
617
618         /* Legacy numeric codes */
619         if (val == -1) {
620                 int rc = lprocfs_str_to_s64(buffer, count, &val);
621                 if (rc)
622                         return rc;
623         }
624
625         if (val < 0 || val > 2)
626                 return -EINVAL;
627
628         spin_lock(&tgt->lut_flags_lock);
629         tgt->lut_sync_lock_cancel = val;
630         spin_unlock(&tgt->lut_flags_lock);
631         return count;
632 }
633 LPROC_SEQ_FOPS(ofd_sync_lock_cancel);
634
635 /**
636  * Show if grants compatibility mode is disabled.
637  *
638  * When ofd_grant_compat_disable is set, we don't grant any space to clients
639  * not supporting OBD_CONNECT_GRANT_PARAM. Otherwise, space granted to such
640  * a client is inflated since it consumes PAGE_SIZE of grant space per
641  * block, (i.e. typically 4kB units), but underlaying file system might have
642  * block size bigger than page size, e.g. ZFS. See LU-2049 for details.
643  *
644  * \param[in] m         seq_file handle
645  * \param[in] data      unused for single entry
646  *
647  * \retval              0 on success
648  * \retval              negative value on error
649  */
650 static int ofd_grant_compat_disable_seq_show(struct seq_file *m, void *data)
651 {
652         struct obd_device *obd = m->private;
653         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
654
655         seq_printf(m, "%u\n", ofd->ofd_grant_compat_disable);
656         return 0;
657 }
658
659 /**
660  * Change grant compatibility mode.
661  *
662  * Setting ofd_grant_compat_disable prohibit any space granting to clients
663  * not supporting OBD_CONNECT_GRANT_PARAM. See details above.
664  *
665  * \param[in] file      proc file
666  * \param[in] buffer    string which represents mode
667  *                      1: disable compatibility mode
668  *                      0: enable compatibility mode
669  * \param[in] count     \a buffer length
670  * \param[in] off       unused for single entry
671  *
672  * \retval              \a count on success
673  * \retval              negative number on error
674  */
675 static ssize_t
676 ofd_grant_compat_disable_seq_write(struct file *file,
677                                    const char __user *buffer,
678                                    size_t count, loff_t *off)
679 {
680         struct seq_file *m = file->private_data;
681         struct obd_device *obd = m->private;
682         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
683         __s64 val;
684         int rc;
685
686         rc = lprocfs_str_to_s64(buffer, count, &val);
687         if (rc)
688                 return rc;
689
690         if (val < 0)
691                 return -EINVAL;
692
693         spin_lock(&ofd->ofd_flags_lock);
694         ofd->ofd_grant_compat_disable = !!val;
695         spin_unlock(&ofd->ofd_flags_lock);
696
697         return count;
698 }
699 LPROC_SEQ_FOPS(ofd_grant_compat_disable);
700
701 /**
702  * Show the limit of soft sync RPCs.
703  *
704  * This value defines how many IO RPCs with OBD_BRW_SOFT_SYNC flag
705  * are allowed before sync update will be triggered.
706  *
707  * \param[in] m         seq_file handle
708  * \param[in] data      unused for single entry
709  *
710  * \retval              0 on success
711  * \retval              negative value on error
712  */
713 static int ofd_soft_sync_limit_seq_show(struct seq_file *m, void *data)
714 {
715         struct obd_device       *obd = m->private;
716         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
717
718         return lprocfs_uint_seq_show(m, &ofd->ofd_soft_sync_limit);
719 }
720
721 /**
722  * Change the limit of soft sync RPCs.
723  *
724  * Define how many IO RPCs with OBD_BRW_SOFT_SYNC flag
725  * allowed before sync update will be done.
726  *
727  * This limit is global across all exports.
728  *
729  * \param[in] file      proc file
730  * \param[in] buffer    string which represents limit
731  * \param[in] count     \a buffer length
732  * \param[in] off       unused for single entry
733  *
734  * \retval              \a count on success
735  * \retval              negative number on error
736  */
737 static ssize_t
738 ofd_soft_sync_limit_seq_write(struct file *file, const char __user *buffer,
739                               size_t count, loff_t *off)
740 {
741         struct seq_file   *m = file->private_data;
742         struct obd_device *obd = m->private;
743         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
744
745         return lprocfs_uint_seq_write(file, buffer, count,
746                                       (loff_t *) &ofd->ofd_soft_sync_limit);
747 }
748 LPROC_SEQ_FOPS(ofd_soft_sync_limit);
749
750 /**
751  * Show the LFSCK speed limit.
752  *
753  * The maximum number of items scanned per second.
754  *
755  * \param[in] m         seq_file handle
756  * \param[in] data      unused for single entry
757  *
758  * \retval              0 on success
759  * \retval              negative value on error
760  */
761 static int ofd_lfsck_speed_limit_seq_show(struct seq_file *m, void *data)
762 {
763         struct obd_device       *obd = m->private;
764         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
765
766         return lfsck_get_speed(m, ofd->ofd_osd);
767 }
768
769 /**
770  * Change the LFSCK speed limit.
771  *
772  * Limit number of items that may be scanned per second.
773  *
774  * \param[in] file      proc file
775  * \param[in] buffer    string which represents limit
776  * \param[in] count     \a buffer length
777  * \param[in] off       unused for single entry
778  *
779  * \retval              \a count on success
780  * \retval              negative number on error
781  */
782 static ssize_t
783 ofd_lfsck_speed_limit_seq_write(struct file *file, const char __user *buffer,
784                                 size_t count, loff_t *off)
785 {
786         struct seq_file *m = file->private_data;
787         struct obd_device *obd = m->private;
788         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
789         __s64 val;
790         int rc;
791
792         rc = lprocfs_str_to_s64(buffer, count, &val);
793         if (rc != 0)
794                 return rc;
795
796         if (val < 0)
797                 return -ERANGE;
798
799         rc = lfsck_set_speed(ofd->ofd_osd, val);
800
801         return rc != 0 ? rc : count;
802 }
803 LPROC_SEQ_FOPS(ofd_lfsck_speed_limit);
804
805 /**
806  * Show LFSCK layout verification stats from the most recent LFSCK run.
807  *
808  * \param[in] m         seq_file handle
809  * \param[in] data      unused for single entry
810  *
811  * \retval              0 on success
812  * \retval              negative value on error
813  */
814 static int ofd_lfsck_layout_seq_show(struct seq_file *m, void *data)
815 {
816         struct obd_device *obd = m->private;
817         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
818
819         return lfsck_dump(m, ofd->ofd_osd, LFSCK_TYPE_LAYOUT);
820 }
821 LPROC_SEQ_FOPS_RO(ofd_lfsck_layout);
822
823 /**
824  * Show if LFSCK performed parent FID verification.
825  *
826  * \param[in] m         seq_file handle
827  * \param[in] data      unused for single entry
828  *
829  * \retval              0 on success
830  * \retval              negative value on error
831  */
832 static int ofd_lfsck_verify_pfid_seq_show(struct seq_file *m, void *data)
833 {
834         struct obd_device *obd = m->private;
835         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
836
837         seq_printf(m, "switch: %s\ndetected: %llu\nrepaired: %llu\n",
838                    ofd->ofd_lfsck_verify_pfid ? "on" : "off",
839                    ofd->ofd_inconsistency_self_detected,
840                    ofd->ofd_inconsistency_self_repaired);
841         return 0;
842 }
843
844 /**
845  * Set the LFSCK behavior to verify parent FID correctness.
846  *
847  * If flag ofd_lfsck_verify_pfid is set then LFSCK does parent FID
848  * verification during read/write operations.
849  *
850  * \param[in] file      proc file
851  * \param[in] buffer    string which represents behavior
852  *                      1: verify parent FID
853  *                      0: don't verify parent FID
854  * \param[in] count     \a buffer length
855  * \param[in] off       unused for single entry
856  *
857  * \retval              \a count on success
858  * \retval              negative number on error
859  */
860 static ssize_t
861 ofd_lfsck_verify_pfid_seq_write(struct file *file, const char __user *buffer,
862                                 size_t count, loff_t *off)
863 {
864         struct seq_file *m = file->private_data;
865         struct obd_device *obd = m->private;
866         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
867         __s64 val;
868         int rc;
869
870         rc = lprocfs_str_to_s64(buffer, count, &val);
871         if (rc != 0)
872                 return rc;
873
874         ofd->ofd_lfsck_verify_pfid = !!val;
875         if (!ofd->ofd_lfsck_verify_pfid) {
876                 ofd->ofd_inconsistency_self_detected = 0;
877                 ofd->ofd_inconsistency_self_repaired = 0;
878         }
879
880         return count;
881 }
882 LPROC_SEQ_FOPS(ofd_lfsck_verify_pfid);
883
884 static int ofd_site_stats_seq_show(struct seq_file *m, void *data)
885 {
886         struct obd_device *obd = m->private;
887
888         return lu_site_stats_seq_print(obd->obd_lu_dev->ld_site, m);
889 }
890 LPROC_SEQ_FOPS_RO(ofd_site_stats);
891
892 LPROC_SEQ_FOPS_RO_TYPE(ofd, uuid);
893 LPROC_SEQ_FOPS_RO_TYPE(ofd, blksize);
894 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytestotal);
895 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesfree);
896 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesavail);
897 LPROC_SEQ_FOPS_RO_TYPE(ofd, filestotal);
898 LPROC_SEQ_FOPS_RO_TYPE(ofd, filesfree);
899
900 LPROC_SEQ_FOPS_RO_TYPE(ofd, recovery_status);
901 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_soft);
902 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_hard);
903 LPROC_SEQ_FOPS_WO_TYPE(ofd, evict_client);
904 LPROC_SEQ_FOPS_RO_TYPE(ofd, num_exports);
905 LPROC_SEQ_FOPS_RO_TYPE(ofd, target_instance);
906 LPROC_SEQ_FOPS_RW_TYPE(ofd, ir_factor);
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 =       "grant_compat_disable",
963           .fops =       &ofd_grant_compat_disable_fops  },
964         { .name =       "client_cache_count",
965           .fops =       &ofd_fmd_max_num_fops           },
966         { .name =       "client_cache_seconds",
967           .fops =       &ofd_fmd_max_age_fops           },
968         { .name =       "job_cleanup_interval",
969           .fops =       &ofd_job_interval_fops          },
970         { .name =       "soft_sync_limit",
971           .fops =       &ofd_soft_sync_limit_fops       },
972         { .name =       "lfsck_speed_limit",
973           .fops =       &ofd_lfsck_speed_limit_fops     },
974         { .name =       "lfsck_layout",
975           .fops =       &ofd_lfsck_layout_fops          },
976         { .name =       "lfsck_verify_pfid",
977           .fops =       &ofd_lfsck_verify_pfid_fops     },
978         { .name =       "site_stats",
979           .fops =       &ofd_site_stats_fops            },
980         { NULL }
981 };
982
983 /**
984  * Initialize OFD statistics counters
985  *
986  * param[in] stats      statistics counters
987  */
988 void ofd_stats_counter_init(struct lprocfs_stats *stats)
989 {
990         LASSERT(stats && stats->ls_num >= LPROC_OFD_STATS_LAST);
991
992         lprocfs_counter_init(stats, LPROC_OFD_STATS_READ,
993                              LPROCFS_CNTR_AVGMINMAX, "read_bytes", "bytes");
994         lprocfs_counter_init(stats, LPROC_OFD_STATS_WRITE,
995                              LPROCFS_CNTR_AVGMINMAX, "write_bytes", "bytes");
996         lprocfs_counter_init(stats, LPROC_OFD_STATS_GETATTR,
997                              0, "getattr", "reqs");
998         lprocfs_counter_init(stats, LPROC_OFD_STATS_SETATTR,
999                              0, "setattr", "reqs");
1000         lprocfs_counter_init(stats, LPROC_OFD_STATS_PUNCH,
1001                              0, "punch", "reqs");
1002         lprocfs_counter_init(stats, LPROC_OFD_STATS_SYNC,
1003                              0, "sync", "reqs");
1004         lprocfs_counter_init(stats, LPROC_OFD_STATS_DESTROY,
1005                              0, "destroy", "reqs");
1006         lprocfs_counter_init(stats, LPROC_OFD_STATS_CREATE,
1007                              0, "create", "reqs");
1008         lprocfs_counter_init(stats, LPROC_OFD_STATS_STATFS,
1009                              0, "statfs", "reqs");
1010         lprocfs_counter_init(stats, LPROC_OFD_STATS_GET_INFO,
1011                              0, "get_info", "reqs");
1012         lprocfs_counter_init(stats, LPROC_OFD_STATS_SET_INFO,
1013                              0, "set_info", "reqs");
1014         lprocfs_counter_init(stats, LPROC_OFD_STATS_QUOTACTL,
1015                              0, "quotactl", "reqs");
1016 }
1017
1018 #endif /* CONFIG_PROC_FS */