Whamcloud - gitweb
46466a85af3f550b1e1cc3ad6f95380a3b0f3678
[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 LPROCFS
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 total amount of free space reserved for grants.
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_grant_ratio_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",
167                           (int) ofd_grant_reserved(ofd, 100));
168 }
169
170 /**
171  * Change amount of free space reserved for grants.
172  *
173  * \param[in] file      proc file
174  * \param[in] buffer    string which represents maximum number
175  * \param[in] count     \a buffer length
176  * \param[in] off       unused for single entry
177  *
178  * \retval              \a count on success
179  * \retval              negative number on error
180  */
181 static ssize_t
182 ofd_grant_ratio_seq_write(struct file *file, const char __user *buffer,
183                           size_t count, loff_t *off)
184 {
185         struct seq_file         *m = file->private_data;
186         struct obd_device       *obd = m->private;
187         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
188         int                      val;
189         int                      rc;
190
191         rc = lprocfs_write_helper(buffer, count, &val);
192         if (rc)
193                 return rc;
194
195         if (val > 100 || val < 0)
196                 return -EINVAL;
197
198         if (val == 0)
199                 CWARN("%s: disabling grant error margin\n", obd->obd_name);
200         if (val > 50)
201                 CWARN("%s: setting grant error margin >50%%, be warned that "
202                       "a huge part of the free space is now reserved for "
203                       "grants\n", obd->obd_name);
204
205         spin_lock(&ofd->ofd_grant_lock);
206         ofd->ofd_grant_ratio = ofd_grant_ratio_conv(val);
207         spin_unlock(&ofd->ofd_grant_lock);
208         return count;
209 }
210 LPROC_SEQ_FOPS(ofd_grant_ratio);
211
212 /**
213  * Show number of precreates allowed in a single transaction.
214  *
215  * \param[in] m         seq_file handle
216  * \param[in] data      unused for single entry
217  *
218  * \retval              0 on success
219  * \retval              negative value on error
220  */
221 static int ofd_precreate_batch_seq_show(struct seq_file *m, void *data)
222 {
223         struct obd_device *obd = m->private;
224         struct ofd_device *ofd;
225
226         LASSERT(obd != NULL);
227         ofd = ofd_dev(obd->obd_lu_dev);
228         return seq_printf(m, "%d\n", ofd->ofd_precreate_batch);
229 }
230
231 /**
232  * Change number of precreates allowed in a single transaction.
233  *
234  * \param[in] file      proc file
235  * \param[in] buffer    string which represents maximum number
236  * \param[in] count     \a buffer length
237  * \param[in] off       unused for single entry
238  *
239  * \retval              \a count on success
240  * \retval              negative number on error
241  */
242 static ssize_t
243 ofd_precreate_batch_seq_write(struct file *file, const char __user *buffer,
244                               size_t count, loff_t *off)
245 {
246         struct seq_file   *m = file->private_data;
247         struct obd_device *obd = m->private;
248         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
249         int val;
250         int rc;
251
252         rc = lprocfs_write_helper(buffer, count, &val);
253         if (rc)
254                 return rc;
255
256         if (val < 1)
257                 return -EINVAL;
258
259         spin_lock(&ofd->ofd_batch_lock);
260         ofd->ofd_precreate_batch = val;
261         spin_unlock(&ofd->ofd_batch_lock);
262         return count;
263 }
264 LPROC_SEQ_FOPS(ofd_precreate_batch);
265
266 /**
267  * Show the last used ID for each FID sequence used by OFD.
268  *
269  * \param[in] m         seq_file handle
270  * \param[in] data      unused for single entry
271  *
272  * \retval              0 on success
273  * \retval              negative value on error
274  */
275 static int ofd_last_id_seq_show(struct seq_file *m, void *data)
276 {
277         struct obd_device       *obd = m->private;
278         struct ofd_device       *ofd;
279         struct ofd_seq          *oseq = NULL;
280         int                     retval = 0, rc;
281
282         if (obd == NULL)
283                 return 0;
284
285         ofd = ofd_dev(obd->obd_lu_dev);
286
287         read_lock(&ofd->ofd_seq_list_lock);
288         list_for_each_entry(oseq, &ofd->ofd_seq_list, os_list) {
289                 __u64 seq;
290
291                 seq = ostid_seq(&oseq->os_oi) == 0 ?
292                       fid_idif_seq(ostid_id(&oseq->os_oi),
293                                    ofd->ofd_lut.lut_lsd.lsd_osd_index) :
294                       ostid_seq(&oseq->os_oi);
295                 rc = seq_printf(m, DOSTID"\n", seq, ostid_id(&oseq->os_oi));
296                 if (rc < 0) {
297                         retval = rc;
298                         break;
299                 }
300                 retval += rc;
301         }
302         read_unlock(&ofd->ofd_seq_list_lock);
303         return retval;
304 }
305 LPROC_SEQ_FOPS_RO(ofd_last_id);
306
307 /**
308  * Show maximum number of Filter Modification Data (FMD) maintained by OFD.
309  *
310  * \param[in] m         seq_file handle
311  * \param[in] data      unused for single entry
312  *
313  * \retval              0 on success
314  * \retval              negative value on error
315  */
316 static int ofd_fmd_max_num_seq_show(struct seq_file *m, void *data)
317 {
318         struct obd_device *obd = m->private;
319         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
320
321         return seq_printf(m, "%u\n", ofd->ofd_fmd_max_num);
322 }
323
324 /**
325  * Change number of FMDs maintained by OFD.
326  *
327  * This defines how large the list of FMDs can be.
328  *
329  * \param[in] file      proc file
330  * \param[in] buffer    string which represents maximum number
331  * \param[in] count     \a buffer length
332  * \param[in] off       unused for single entry
333  *
334  * \retval              \a count on success
335  * \retval              negative number on error
336  */
337 static ssize_t
338 ofd_fmd_max_num_seq_write(struct file *file, const char __user *buffer,
339                           size_t count, loff_t *off)
340 {
341         struct seq_file         *m = file->private_data;
342         struct obd_device       *obd = m->private;
343         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
344         int                      val;
345         int                      rc;
346
347         rc = lprocfs_write_helper(buffer, count, &val);
348         if (rc)
349                 return rc;
350
351         if (val > 65536 || val < 1)
352                 return -EINVAL;
353
354         ofd->ofd_fmd_max_num = val;
355         return count;
356 }
357 LPROC_SEQ_FOPS(ofd_fmd_max_num);
358
359 /**
360  * Show the maximum age of FMD data in seconds.
361  *
362  * Though it is shown in seconds, it is stored internally in units
363  * of jiffies for efficiency.
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_fmd_max_age_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         return seq_printf(m, "%ld\n", jiffies_to_msecs(ofd->ofd_fmd_max_age) /
377                                       MSEC_PER_SEC);
378 }
379
380 /**
381  * Set the maximum age of FMD data in seconds.
382  *
383  * This defines how long FMD data stays in the FMD list.
384  * It is stored internally in units of jiffies for efficiency.
385  *
386  * \param[in] file      proc file
387  * \param[in] buffer    string which represents maximum number
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_fmd_max_age_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;
402         int                      rc;
403
404         rc = lprocfs_write_helper(buffer, count, &val);
405         if (rc)
406                 return rc;
407
408         if (val > 65536 || val < 1)
409                 return -EINVAL;
410
411         ofd->ofd_fmd_max_age = msecs_to_jiffies(val * MSEC_PER_SEC);
412         return count;
413 }
414 LPROC_SEQ_FOPS(ofd_fmd_max_age);
415
416 /**
417  * Show if OSS FID capability is enabled or disabled
418  *
419  * \param[in] m         seq_file handle
420  * \param[in] data      unused for single entry
421  *
422  * \retval              0 on success
423  * \retval              negative value on error
424  */
425 static int ofd_capa_seq_show(struct seq_file *m, void *data)
426 {
427         struct obd_device       *obd = m->private;
428
429         return seq_printf(m, "capability on: %s\n",
430                           obd->u.filter.fo_fl_oss_capa ? "oss" : "");
431 }
432
433 /**
434  * Enable or disable OSS FID capability mode.
435  *
436  * \param[in] file      proc file
437  * \param[in] buffer    string which represents mode
438  *                      1: enable mode
439  *                      0: disable mode
440  * \param[in] count     \a buffer length
441  * \param[in] off       unused for single entry
442  *
443  * \retval              \a count on success
444  * \retval              negative number on error
445  */
446 static ssize_t
447 ofd_capa_seq_write(struct file *file, const char *__user buffer, size_t count,
448                    loff_t *off)
449 {
450         struct seq_file         *m = file->private_data;
451         struct obd_device       *obd = m->private;
452         int                      val, rc;
453
454         rc = lprocfs_write_helper(buffer, count, &val);
455         if (rc)
456                 return rc;
457
458         if (val & ~0x1) {
459                 CERROR("invalid capability mode, only 0/1 are accepted.\n"
460                        " 1: enable oss fid capability\n"
461                        " 0: disable oss fid capability\n");
462                 return -EINVAL;
463         }
464
465         obd->u.filter.fo_fl_oss_capa = val;
466         LCONSOLE_INFO("OSS %s %s fid capability.\n", obd->obd_name,
467                       val ? "enabled" : "disabled");
468         return count;
469 }
470 LPROC_SEQ_FOPS(ofd_capa);
471
472 /**
473  * Show capability count on client and server side.
474  *
475  * \param[in] m         seq_file handle
476  * \param[in] data      unused for single entry
477  *
478  * \retval              0 on success
479  * \retval              negative value on error
480  */
481 static int ofd_capa_count_seq_show(struct seq_file *m, void *data)
482 {
483         return seq_printf(m, "%d %d\n", capa_count[CAPA_SITE_CLIENT],
484                           capa_count[CAPA_SITE_SERVER]);
485 }
486 LPROC_SEQ_FOPS_RO(ofd_capa_count);
487
488 /**
489  * Show if the OFD is in degraded mode.
490  *
491  * Degraded means OFD has a failed drive or is undergoing RAID rebuild.
492  * The MDS will try to avoid using this OST for new object allocations
493  * to reduce the impact to global IO performance when clients writing to
494  * this OST are slowed down.  It also reduces the contention on the OST
495  * RAID device, allowing it to rebuild more quickly.
496  *
497  * \param[in] m         seq_file handle
498  * \param[in] data      unused for single entry
499  *
500  * \retval              0 on success
501  * \retval              negative value on error
502  */
503 static int ofd_degraded_seq_show(struct seq_file *m, void *data)
504 {
505         struct obd_device *obd = m->private;
506         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
507
508         return seq_printf(m, "%u\n", ofd->ofd_raid_degraded);
509 }
510
511 /**
512  * Set OFD to degraded mode.
513  *
514  * This is used to interface to userspace administrative tools for
515  * the underlying RAID storage, so that they can mark an OST
516  * as having degraded performance.
517  *
518  * \param[in] file      proc file
519  * \param[in] buffer    string which represents mode
520  *                      1: set degraded mode
521  *                      0: unset degraded mode
522  * \param[in] count     \a buffer length
523  * \param[in] off       unused for single entry
524  *
525  * \retval              \a count on success
526  * \retval              negative number on error
527  */
528 static ssize_t
529 ofd_degraded_seq_write(struct file *file, const char __user *buffer,
530                        size_t count, loff_t *off)
531 {
532         struct seq_file         *m = file->private_data;
533         struct obd_device       *obd = m->private;
534         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
535         int                      val, rc;
536
537         rc = lprocfs_write_helper(buffer, count, &val);
538         if (rc)
539                 return rc;
540
541         spin_lock(&ofd->ofd_flags_lock);
542         ofd->ofd_raid_degraded = !!val;
543         spin_unlock(&ofd->ofd_flags_lock);
544         return count;
545 }
546 LPROC_SEQ_FOPS(ofd_degraded);
547
548 /**
549  * Show OFD filesystem type.
550  *
551  * \param[in] m         seq_file handle
552  * \param[in] data      unused for single entry
553  *
554  * \retval              0 on success
555  * \retval              negative value on error
556  */
557 static int ofd_fstype_seq_show(struct seq_file *m, void *data)
558 {
559         struct obd_device *obd = m->private;
560         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
561         struct lu_device  *d;
562
563         LASSERT(ofd->ofd_osd);
564         d = &ofd->ofd_osd->dd_lu_dev;
565         LASSERT(d->ld_type);
566         return seq_printf(m, "%s\n", d->ld_type->ldt_name);
567 }
568 LPROC_SEQ_FOPS_RO(ofd_fstype);
569
570 /**
571  * Show journal handling mode: synchronous or asynchronous.
572  *
573  * When running in asynchronous mode the journal transactions are not
574  * committed to disk before the RPC is replied back to the client.
575  * This will typically improve client performance when only a small number
576  * of clients are writing, since the client(s) can have more write RPCs
577  * in flight. However, it also means that the client has to handle recovery
578  * on bulk RPCs, and will have to keep more dirty pages in cache before they
579  * are committed on the OST.
580  *
581  * \param[in] m         seq_file handle
582  * \param[in] data      unused for single entry
583  *
584  * \retval              0 on success
585  * \retval              negative value on error
586  */
587 static int ofd_syncjournal_seq_show(struct seq_file *m, void *data)
588 {
589         struct obd_device       *obd = m->private;
590         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
591
592         return seq_printf(m, "%u\n", ofd->ofd_syncjournal);
593 }
594
595 /**
596  * Set journal mode to synchronous or asynchronous.
597  *
598  * \param[in] file      proc file
599  * \param[in] buffer    string which represents mode
600  *                      1: synchronous mode
601  *                      0: asynchronous mode
602  * \param[in] count     \a buffer length
603  * \param[in] off       unused for single entry
604  *
605  * \retval              \a count on success
606  * \retval              negative number on error
607  */
608 static ssize_t
609 ofd_syncjournal_seq_write(struct file *file, const char __user *buffer,
610                           size_t count, loff_t *off)
611 {
612         struct seq_file         *m = file->private_data;
613         struct obd_device       *obd = m->private;
614         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
615         int                      val;
616         int                      rc;
617
618         rc = lprocfs_write_helper(buffer, count, &val);
619         if (rc)
620                 return rc;
621
622         if (val < 0)
623                 return -EINVAL;
624
625         spin_lock(&ofd->ofd_flags_lock);
626         ofd->ofd_syncjournal = !!val;
627         ofd_slc_set(ofd);
628         spin_unlock(&ofd->ofd_flags_lock);
629
630         return count;
631 }
632 LPROC_SEQ_FOPS(ofd_syncjournal);
633
634 /* This must be longer than the longest string below */
635 #define SYNC_STATES_MAXLEN 16
636 static char *sync_on_cancel_states[] = {"never",
637                                         "blocking",
638                                         "always" };
639
640 /**
641  * Show OFD policy for handling dirty data under a lock being cancelled.
642  *
643  * \param[in] m         seq_file handle
644  * \param[in] data      unused for single entry
645  *
646  * \retval              0 on success
647  * \retval              negative value on error
648  */
649 static int ofd_sync_lock_cancel_seq_show(struct seq_file *m, void *data)
650 {
651         struct obd_device       *obd = m->private;
652         struct lu_target        *tgt = obd->u.obt.obt_lut;
653
654         return seq_printf(m, "%s\n",
655                           sync_on_cancel_states[tgt->lut_sync_lock_cancel]);
656 }
657
658 /**
659  * Change OFD policy for handling dirty data under a lock being cancelled.
660  *
661  * This variable defines what action OFD takes upon lock cancel
662  * There are three possible modes:
663  * 1) never - never do sync upon lock cancel. This can lead to data
664  *    inconsistencies if both the OST and client crash while writing a file
665  *    that is also concurrently being read by another client. In these cases,
666  *    this may allow the file data to "rewind" to an earlier state.
667  * 2) blocking - do sync only if there is blocking lock, e.g. if another
668  *    client is trying to access this same object
669  * 3) always - do sync always
670  *
671  * \param[in] file      proc file
672  * \param[in] buffer    string which represents policy
673  * \param[in] count     \a buffer length
674  * \param[in] off       unused for single entry
675  *
676  * \retval              \a count on success
677  * \retval              negative number on error
678  */
679 static ssize_t
680 ofd_sync_lock_cancel_seq_write(struct file *file, const char __user *buffer,
681                                size_t count, loff_t *off)
682 {
683         struct seq_file         *m = file->private_data;
684         struct obd_device       *obd = m->private;
685         struct lu_target        *tgt = obd->u.obt.obt_lut;
686         char                     kernbuf[SYNC_STATES_MAXLEN];
687         int                      val = -1;
688         int                      i;
689
690         if (count == 0 || count >= sizeof(kernbuf))
691                 return -EINVAL;
692
693         if (copy_from_user(kernbuf, buffer, count))
694                 return -EFAULT;
695         kernbuf[count] = 0;
696
697         if (kernbuf[count - 1] == '\n')
698                 kernbuf[count - 1] = 0;
699
700         for (i = 0 ; i < NUM_SYNC_ON_CANCEL_STATES; i++) {
701                 if (strcmp(kernbuf, sync_on_cancel_states[i]) == 0) {
702                         val = i;
703                         break;
704                 }
705         }
706
707         /* Legacy numeric codes */
708         if (val == -1) {
709                 int rc;
710
711                 /* Safe to use userspace buffer as lprocfs_write_helper will
712                  * use copy from user for parsing */
713                 rc = lprocfs_write_helper(buffer, count, &val);
714                 if (rc)
715                         return rc;
716         }
717
718         if (val < 0 || val > 2)
719                 return -EINVAL;
720
721         spin_lock(&tgt->lut_flags_lock);
722         tgt->lut_sync_lock_cancel = val;
723         spin_unlock(&tgt->lut_flags_lock);
724         return count;
725 }
726 LPROC_SEQ_FOPS(ofd_sync_lock_cancel);
727
728 /**
729  * Show if grants compatibility mode is disabled.
730  *
731  * When ofd_grant_compat_disable is set, we don't grant any space to clients
732  * not supporting OBD_CONNECT_GRANT_PARAM. Otherwise, space granted to such
733  * a client is inflated since it consumes PAGE_CACHE_SIZE of grant space per
734  * block, (i.e. typically 4kB units), but underlaying file system might have
735  * block size bigger than page size, e.g. ZFS. See LU-2049 for details.
736  *
737  * \param[in] m         seq_file handle
738  * \param[in] data      unused for single entry
739  *
740  * \retval              0 on success
741  * \retval              negative value on error
742  */
743 static int ofd_grant_compat_disable_seq_show(struct seq_file *m, void *data)
744 {
745         struct obd_device *obd = m->private;
746         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
747
748         return seq_printf(m, "%u\n", ofd->ofd_grant_compat_disable);
749 }
750
751 /**
752  * Change grant compatibility mode.
753  *
754  * Setting ofd_grant_compat_disable prohibit any space granting to clients
755  * not supporting OBD_CONNECT_GRANT_PARAM. See details above.
756  *
757  * \param[in] file      proc file
758  * \param[in] buffer    string which represents mode
759  *                      1: disable compatibility mode
760  *                      0: enable compatibility mode
761  * \param[in] count     \a buffer length
762  * \param[in] off       unused for single entry
763  *
764  * \retval              \a count on success
765  * \retval              negative number on error
766  */
767 static ssize_t
768 ofd_grant_compat_disable_seq_write(struct file *file,
769                                    const char __user *buffer,
770                                    size_t count, loff_t *off)
771 {
772         struct seq_file         *m = file->private_data;
773         struct obd_device       *obd = m->private;
774         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
775         int                      val;
776         int                      rc;
777
778         rc = lprocfs_write_helper(buffer, count, &val);
779         if (rc)
780                 return rc;
781
782         if (val < 0)
783                 return -EINVAL;
784
785         spin_lock(&ofd->ofd_flags_lock);
786         ofd->ofd_grant_compat_disable = !!val;
787         spin_unlock(&ofd->ofd_flags_lock);
788
789         return count;
790 }
791 LPROC_SEQ_FOPS(ofd_grant_compat_disable);
792
793 /**
794  * Show the limit of soft sync RPCs.
795  *
796  * This value defines how many IO RPCs with OBD_BRW_SOFT_SYNC flag
797  * are allowed before sync update will be triggered.
798  *
799  * \param[in] m         seq_file handle
800  * \param[in] data      unused for single entry
801  *
802  * \retval              0 on success
803  * \retval              negative value on error
804  */
805 static int ofd_soft_sync_limit_seq_show(struct seq_file *m, void *data)
806 {
807         struct obd_device       *obd = m->private;
808         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
809
810         return lprocfs_uint_seq_show(m, &ofd->ofd_soft_sync_limit);
811 }
812
813 /**
814  * Change the limit of soft sync RPCs.
815  *
816  * Define how many IO RPCs with OBD_BRW_SOFT_SYNC flag
817  * allowed before sync update will be done.
818  *
819  * This limit is global across all exports.
820  *
821  * \param[in] file      proc file
822  * \param[in] buffer    string which represents limit
823  * \param[in] count     \a buffer length
824  * \param[in] off       unused for single entry
825  *
826  * \retval              \a count on success
827  * \retval              negative number on error
828  */
829 static ssize_t
830 ofd_soft_sync_limit_seq_write(struct file *file, const char __user *buffer,
831                               size_t count, loff_t *off)
832 {
833         struct seq_file   *m = file->private_data;
834         struct obd_device *obd = m->private;
835         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
836
837         return lprocfs_uint_seq_write(file, buffer, count,
838                                       (loff_t *) &ofd->ofd_soft_sync_limit);
839 }
840 LPROC_SEQ_FOPS(ofd_soft_sync_limit);
841
842 /**
843  * Show the LFSCK speed limit.
844  *
845  * The maximum number of items scanned per second.
846  *
847  * \param[in] m         seq_file handle
848  * \param[in] data      unused for single entry
849  *
850  * \retval              0 on success
851  * \retval              negative value on error
852  */
853 static int ofd_lfsck_speed_limit_seq_show(struct seq_file *m, void *data)
854 {
855         struct obd_device       *obd = m->private;
856         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
857
858         return lfsck_get_speed(m, ofd->ofd_osd);
859 }
860
861 /**
862  * Change the LFSCK speed limit.
863  *
864  * Limit number of items that may be scanned per second.
865  *
866  * \param[in] file      proc file
867  * \param[in] buffer    string which represents limit
868  * \param[in] count     \a buffer length
869  * \param[in] off       unused for single entry
870  *
871  * \retval              \a count on success
872  * \retval              negative number on error
873  */
874 static ssize_t
875 ofd_lfsck_speed_limit_seq_write(struct file *file, const char __user *buffer,
876                                 size_t count, loff_t *off)
877 {
878         struct seq_file         *m = file->private_data;
879         struct obd_device       *obd = m->private;
880         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
881         __u32                    val;
882         int                      rc;
883
884         rc = lprocfs_write_helper(buffer, count, &val);
885         if (rc != 0)
886                 return rc;
887
888         rc = lfsck_set_speed(ofd->ofd_osd, val);
889
890         return rc != 0 ? rc : count;
891 }
892 LPROC_SEQ_FOPS(ofd_lfsck_speed_limit);
893
894 /**
895  * Show LFSCK layout verification stats from the most recent LFSCK run.
896  *
897  * \param[in] m         seq_file handle
898  * \param[in] data      unused for single entry
899  *
900  * \retval              0 on success
901  * \retval              negative value on error
902  */
903 static int ofd_lfsck_layout_seq_show(struct seq_file *m, void *data)
904 {
905         struct obd_device *obd = m->private;
906         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
907
908         return lfsck_dump(m, ofd->ofd_osd, LFSCK_TYPE_LAYOUT);
909 }
910 LPROC_SEQ_FOPS_RO(ofd_lfsck_layout);
911
912 /**
913  * Show if LFSCK performed parent FID verification.
914  *
915  * \param[in] m         seq_file handle
916  * \param[in] data      unused for single entry
917  *
918  * \retval              0 on success
919  * \retval              negative value on error
920  */
921 static int ofd_lfsck_verify_pfid_seq_show(struct seq_file *m, void *data)
922 {
923         struct obd_device *obd = m->private;
924         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
925
926         return seq_printf(m,
927                           "switch: %s\ndetected: "LPU64"\nrepaired: "LPU64"\n",
928                           ofd->ofd_lfsck_verify_pfid ? "on" : "off",
929                           ofd->ofd_inconsistency_self_detected,
930                           ofd->ofd_inconsistency_self_repaired);
931 }
932
933 /**
934  * Set the LFSCK behavior to verify parent FID correctness.
935  *
936  * If flag ofd_lfsck_verify_pfid is set then LFSCK does parent FID
937  * verification during read/write operations.
938  *
939  * \param[in] file      proc file
940  * \param[in] buffer    string which represents behavior
941  *                      1: verify parent FID
942  *                      0: don't verify parent FID
943  * \param[in] count     \a buffer length
944  * \param[in] off       unused for single entry
945  *
946  * \retval              \a count on success
947  * \retval              negative number on error
948  */
949 static ssize_t
950 ofd_lfsck_verify_pfid_seq_write(struct file *file, const char __user *buffer,
951                                 size_t count, loff_t *off)
952 {
953         struct seq_file         *m = file->private_data;
954         struct obd_device       *obd = m->private;
955         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
956         __u32                    val;
957         int                      rc;
958
959         rc = lprocfs_write_helper(buffer, count, &val);
960         if (rc != 0)
961                 return rc;
962
963         ofd->ofd_lfsck_verify_pfid = !!val;
964
965         return count;
966 }
967 LPROC_SEQ_FOPS(ofd_lfsck_verify_pfid);
968
969 LPROC_SEQ_FOPS_RO_TYPE(ofd, uuid);
970 LPROC_SEQ_FOPS_RO_TYPE(ofd, blksize);
971 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytestotal);
972 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesfree);
973 LPROC_SEQ_FOPS_RO_TYPE(ofd, kbytesavail);
974 LPROC_SEQ_FOPS_RO_TYPE(ofd, filestotal);
975 LPROC_SEQ_FOPS_RO_TYPE(ofd, filesfree);
976
977 LPROC_SEQ_FOPS_RO_TYPE(ofd, recovery_status);
978 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_soft);
979 LPROC_SEQ_FOPS_RW_TYPE(ofd, recovery_time_hard);
980 LPROC_SEQ_FOPS_WO_TYPE(ofd, evict_client);
981 LPROC_SEQ_FOPS_RO_TYPE(ofd, num_exports);
982 LPROC_SEQ_FOPS_RO_TYPE(ofd, target_instance);
983 LPROC_SEQ_FOPS_RW_TYPE(ofd, ir_factor);
984 LPROC_SEQ_FOPS_RW_TYPE(ofd, job_interval);
985
986 struct lprocfs_seq_vars lprocfs_ofd_obd_vars[] = {
987         { .name =       "uuid",
988           .fops =       &ofd_uuid_fops                  },
989         { .name =       "blocksize",
990           .fops =       &ofd_blksize_fops               },
991         { .name =       "kbytestotal",
992           .fops =       &ofd_kbytestotal_fops           },
993         { .name =       "kbytesfree",
994           .fops =       &ofd_kbytesfree_fops            },
995         { .name =       "kbytesavail",
996           .fops =       &ofd_kbytesavail_fops           },
997         { .name =       "filestotal",
998           .fops =       &ofd_filestotal_fops            },
999         { .name =       "filesfree",
1000           .fops =       &ofd_filesfree_fops             },
1001         { .name =       "seqs_allocated",
1002           .fops =       &ofd_seqs_fops                  },
1003         { .name =       "fstype",
1004           .fops =       &ofd_fstype_fops                },
1005         { .name =       "last_id",
1006           .fops =       &ofd_last_id_fops               },
1007         { .name =       "tot_dirty",
1008           .fops =       &ofd_tot_dirty_fops             },
1009         { .name =       "tot_pending",
1010           .fops =       &ofd_tot_pending_fops           },
1011         { .name =       "tot_granted",
1012           .fops =       &ofd_tot_granted_fops           },
1013         { .name =       "grant_precreate",
1014           .fops =       &ofd_grant_precreate_fops       },
1015         { .name =       "grant_ratio",
1016           .fops =       &ofd_grant_ratio_fops           },
1017         { .name =       "precreate_batch",
1018           .fops =       &ofd_precreate_batch_fops       },
1019         { .name =       "recovery_status",
1020           .fops =       &ofd_recovery_status_fops       },
1021         { .name =       "recovery_time_soft",
1022           .fops =       &ofd_recovery_time_soft_fops    },
1023         { .name =       "recovery_time_hard",
1024           .fops =       &ofd_recovery_time_hard_fops    },
1025         { .name =       "evict_client",
1026           .fops =       &ofd_evict_client_fops          },
1027         { .name =       "num_exports",
1028           .fops =       &ofd_num_exports_fops           },
1029         { .name =       "degraded",
1030           .fops =       &ofd_degraded_fops              },
1031         { .name =       "sync_journal",
1032           .fops =       &ofd_syncjournal_fops           },
1033         { .name =       "sync_on_lock_cancel",
1034           .fops =       &ofd_sync_lock_cancel_fops      },
1035         { .name =       "instance",
1036           .fops =       &ofd_target_instance_fops       },
1037         { .name =       "ir_factor",
1038           .fops =       &ofd_ir_factor_fops             },
1039         { .name =       "grant_compat_disable",
1040           .fops =       &ofd_grant_compat_disable_fops  },
1041         { .name =       "client_cache_count",
1042           .fops =       &ofd_fmd_max_num_fops           },
1043         { .name =       "client_cache_seconds",
1044           .fops =       &ofd_fmd_max_age_fops           },
1045         { .name =       "capa",
1046           .fops =       &ofd_capa_fops                  },
1047         { .name =       "capa_count",
1048           .fops =       &ofd_capa_count_fops            },
1049         { .name =       "job_cleanup_interval",
1050           .fops =       &ofd_job_interval_fops          },
1051         { .name =       "soft_sync_limit",
1052           .fops =       &ofd_soft_sync_limit_fops       },
1053         { .name =       "lfsck_speed_limit",
1054           .fops =       &ofd_lfsck_speed_limit_fops     },
1055         { .name =       "lfsck_layout",
1056           .fops =       &ofd_lfsck_layout_fops          },
1057         { .name =       "lfsck_verify_pfid",
1058           .fops =       &ofd_lfsck_verify_pfid_fops     },
1059         { 0 }
1060 };
1061
1062 /**
1063  * Initialize OFD statistics counters
1064  *
1065  * param[in] stats      statistics counters
1066  */
1067 void ofd_stats_counter_init(struct lprocfs_stats *stats)
1068 {
1069         LASSERT(stats && stats->ls_num >= LPROC_OFD_STATS_LAST);
1070
1071         lprocfs_counter_init(stats, LPROC_OFD_STATS_READ,
1072                              LPROCFS_CNTR_AVGMINMAX, "read_bytes", "bytes");
1073         lprocfs_counter_init(stats, LPROC_OFD_STATS_WRITE,
1074                              LPROCFS_CNTR_AVGMINMAX, "write_bytes", "bytes");
1075         lprocfs_counter_init(stats, LPROC_OFD_STATS_GETATTR,
1076                              0, "getattr", "reqs");
1077         lprocfs_counter_init(stats, LPROC_OFD_STATS_SETATTR,
1078                              0, "setattr", "reqs");
1079         lprocfs_counter_init(stats, LPROC_OFD_STATS_PUNCH,
1080                              0, "punch", "reqs");
1081         lprocfs_counter_init(stats, LPROC_OFD_STATS_SYNC,
1082                              0, "sync", "reqs");
1083         lprocfs_counter_init(stats, LPROC_OFD_STATS_DESTROY,
1084                              0, "destroy", "reqs");
1085         lprocfs_counter_init(stats, LPROC_OFD_STATS_CREATE,
1086                              0, "create", "reqs");
1087         lprocfs_counter_init(stats, LPROC_OFD_STATS_STATFS,
1088                              0, "statfs", "reqs");
1089         lprocfs_counter_init(stats, LPROC_OFD_STATS_GET_INFO,
1090                              0, "get_info", "reqs");
1091         lprocfs_counter_init(stats, LPROC_OFD_STATS_SET_INFO,
1092                              0, "set_info", "reqs");
1093         lprocfs_counter_init(stats, LPROC_OFD_STATS_QUOTACTL,
1094                              0, "quotactl", "reqs");
1095 }
1096
1097 #endif /* LPROCFS */