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