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