Whamcloud - gitweb
LU-9325 obd: replace lprocfs_str_to_s64
[fs/lustre-release.git] / lustre / osp / lproc_osp.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) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, 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/osp/lproc_osp.c
33  *
34  * Lustre OST Proxy Device (OSP), procfs functions
35  *
36  * Author: Alex Zhuravlev <alexey.zhuravlev@intel.com>
37  */
38
39 #define DEBUG_SUBSYSTEM S_CLASS
40
41 #include "osp_internal.h"
42
43 #ifdef CONFIG_PROC_FS
44 /**
45  * Show OSP active status
46  *
47  * \param[in] m         seq_file handle
48  * \param[in] data      unused for single entry
49  * \retval              0 on success
50  * \retval              negative number on error
51  */
52 static int osp_active_seq_show(struct seq_file *m, void *data)
53 {
54         struct obd_device       *dev = m->private;
55
56         LPROCFS_CLIMP_CHECK(dev);
57         seq_printf(m, "%d\n", !dev->u.cli.cl_import->imp_deactive);
58         LPROCFS_CLIMP_EXIT(dev);
59         return 0;
60 }
61
62 /**
63  * Activate/Deactivate OSP
64  *
65  * \param[in] file      proc file
66  * \param[in] buffer    string, which is "1" or "0" to activate/deactivate OSP
67  * \param[in] count     \a buffer length
68  * \param[in] off       unused for single entry
69  * \retval              \a count on success
70  * \retval              negative number on error
71  */
72 static ssize_t
73 osp_active_seq_write(struct file *file, const char __user *buffer,
74                         size_t count, loff_t *off)
75 {
76         struct seq_file *m = file->private_data;
77         struct obd_device *dev = m->private;
78         bool val;
79         int rc;
80
81         rc = kstrtobool_from_user(buffer, count, &val);
82         if (rc)
83                 return rc;
84
85         LPROCFS_CLIMP_CHECK(dev);
86         /* opposite senses */
87         if (dev->u.cli.cl_import->imp_deactive == val)
88                 rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
89         else
90                 CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n",
91                        val);
92
93         LPROCFS_CLIMP_EXIT(dev);
94         return count;
95 }
96 LPROC_SEQ_FOPS(osp_active);
97
98 /**
99  * Show number of RPCs in flight
100  *
101  * \param[in] m         seq_file handle
102  * \param[in] data      unused for single entry
103  * \retval              0 on success
104  * \retval              negative number on error
105  */
106 static int osp_sync_rpcs_in_flight_seq_show(struct seq_file *m, void *data)
107 {
108         struct obd_device       *dev = m->private;
109         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
110
111         if (osp == NULL)
112                 return -EINVAL;
113
114         seq_printf(m, "%u\n", atomic_read(&osp->opd_sync_rpcs_in_flight));
115         return 0;
116 }
117 LPROC_SEQ_FOPS_RO(osp_sync_rpcs_in_flight);
118
119 /**
120  * Show number of RPCs in processing (including uncommitted by OST)
121  *
122  * \param[in] m         seq_file handle
123  * \param[in] data      unused for single entry
124  * \retval              0 on success
125  * \retval              negative number on error
126  */
127 static int osp_sync_rpcs_in_progress_seq_show(struct seq_file *m, void *data)
128 {
129         struct obd_device       *dev = m->private;
130         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
131
132         if (osp == NULL)
133                 return -EINVAL;
134
135         seq_printf(m, "%u\n", atomic_read(&osp->opd_sync_rpcs_in_progress));
136         return 0;
137 }
138 LPROC_SEQ_FOPS_RO(osp_sync_rpcs_in_progress);
139
140 /**
141  * Show number of changes to sync
142  *
143  * \param[in] m         seq_file handle
144  * \param[in] data      unused for single entry
145  * \retval              0 on success
146  * \retval              negative number on error
147  */
148 static int osp_sync_changes_seq_show(struct seq_file *m, void *data)
149 {
150         struct obd_device       *dev = m->private;
151         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
152
153         if (osp == NULL)
154                 return -EINVAL;
155
156         seq_printf(m, "%u\n", atomic_read(&osp->opd_sync_changes));
157         return 0;
158 }
159
160 /**
161  * Sync changes
162  *
163  * \param[in] file      proc file
164  * \param[in] buffer    unused because any input will do
165  * \param[in] count     \a buffer length
166  * \param[in] off       unused for single entry
167  * \retval              \a count on success
168  * \retval              negative number on error
169  */
170 static ssize_t osp_sync_changes_seq_write(struct file *file,
171                                          const char __user *buffer,
172                                          size_t count, loff_t *off)
173 {
174         struct seq_file         *m      = file->private_data;
175         struct obd_device       *dev    = m->private;
176         struct osp_device       *osp    = lu2osp_dev(dev->obd_lu_dev);
177         struct lu_env            env;
178         int                      rc;
179
180         rc = lu_env_init(&env, LCT_LOCAL);
181         if (rc != 0)
182                 return rc;
183
184         rc = dt_sync(&env, &osp->opd_dt_dev);
185         lu_env_fini(&env);
186
187         return rc == 0 ? count : rc;
188 }
189 LPROC_SEQ_FOPS(osp_sync_changes);
190
191 /**
192  * Show maximum number of RPCs in flight allowed
193  *
194  * \param[in] m         seq_file handle
195  * \param[in] data      unused for single entry
196  * \retval              0 on success
197  * \retval              negative number on error
198  */
199 static int osp_max_rpcs_in_flight_seq_show(struct seq_file *m, void *data)
200 {
201         struct obd_device       *dev = m->private;
202         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
203
204         if (osp == NULL)
205                 return -EINVAL;
206
207         seq_printf(m, "%u\n", osp->opd_sync_max_rpcs_in_flight);
208         return 0;
209 }
210
211 /**
212  * Change maximum number of RPCs in flight allowed
213  *
214  * \param[in] file      proc file
215  * \param[in] buffer    string which represents maximum number
216  * \param[in] count     \a buffer length
217  * \param[in] off       unused for single entry
218  * \retval              \a count on success
219  * \retval              negative number on error
220  */
221 static ssize_t
222 osp_max_rpcs_in_flight_seq_write(struct file *file, const char __user *buffer,
223                                 size_t count, loff_t *off)
224 {
225         struct seq_file *m = file->private_data;
226         struct obd_device *dev = m->private;
227         struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
228         unsigned int val;
229         int rc;
230
231         if (osp == NULL)
232                 return -EINVAL;
233
234         rc = kstrtouint_from_user(buffer, count, 0, &val);
235         if (rc)
236                 return rc;
237
238         if (val == 0)
239                 return -ERANGE;
240
241         osp->opd_sync_max_rpcs_in_flight = val;
242         return count;
243 }
244 LPROC_SEQ_FOPS(osp_max_rpcs_in_flight);
245
246 /**
247  * Show maximum number of RPCs in processing allowed
248  *
249  * \param[in] m         seq_file handle
250  * \param[in] data      unused
251  * \retval              0 on success
252  * \retval              negative number on error
253  */
254 static int osp_max_rpcs_in_progress_seq_show(struct seq_file *m, void *data)
255 {
256         struct obd_device       *dev = m->private;
257         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
258
259         if (osp == NULL)
260                 return -EINVAL;
261
262         seq_printf(m, "%u\n", osp->opd_sync_max_rpcs_in_progress);
263         return 0;
264 }
265
266 /**
267  * Change maximum number of RPCs in processing allowed
268  *
269  * \param[in] file      proc file
270  * \param[in] buffer    string which represents maximum number
271  * \param[in] count     \a buffer length
272  * \param[in] off       unused for single entry
273  * \retval              \a count on success
274  * \retval              negative number on error
275  */
276 static ssize_t
277 osp_max_rpcs_in_progress_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 *dev = m->private;
282         struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
283         unsigned int val;
284         int rc;
285
286         if (osp == NULL)
287                 return -EINVAL;
288
289         rc = kstrtouint_from_user(buffer, count, 0, &val);
290         if (rc)
291                 return rc;
292
293         if (val == 0)
294                 return -ERANGE;
295
296         osp->opd_sync_max_rpcs_in_progress = val;
297
298         return count;
299 }
300 LPROC_SEQ_FOPS(osp_max_rpcs_in_progress);
301
302 /**
303  * Show number of objects to precreate next time
304  *
305  * \param[in] m         seq_file handle
306  * \param[in] data      unused for single entry
307  * \retval              0 on success
308  * \retval              negative number on error
309  */
310 static int osp_create_count_seq_show(struct seq_file *m, void *data)
311 {
312         struct obd_device *obd = m->private;
313         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
314
315         if (osp == NULL || osp->opd_pre == NULL)
316                 return 0;
317
318         seq_printf(m, "%d\n", osp->opd_pre_create_count);
319         return 0;
320 }
321
322 /**
323  * Change number of objects to precreate next time
324  *
325  * \param[in] file      proc file
326  * \param[in] buffer    string which represents number of objects to precreate
327  * \param[in] count     \a buffer length
328  * \param[in] off       unused for single entry
329  * \retval              \a count on success
330  * \retval              negative number on error
331  */
332 static ssize_t
333 osp_create_count_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 osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
339         unsigned int val;
340         int rc, i;
341
342         if (osp == NULL || osp->opd_pre == NULL)
343                 return 0;
344
345         rc = kstrtouint_from_user(buffer, count, 0, &val);
346         if (rc)
347                 return rc;
348
349         /* The MDT ALWAYS needs to limit the precreate count to
350          * OST_MAX_PRECREATE, and the constant cannot be changed
351          * because it is a value shared between the OSP and OST
352          * that is the maximum possible number of objects that will
353          * ever be handled by MDT->OST recovery processing.
354          *
355          * If the OST ever gets a request to delete more orphans,
356          * this implies that something has gone badly on the MDT
357          * and the OST will refuse to delete so much data from the
358          * filesystem as a safety measure. */
359         if (val < OST_MIN_PRECREATE || val > OST_MAX_PRECREATE)
360                 return -ERANGE;
361         if (val > osp->opd_pre_max_create_count)
362                 return -ERANGE;
363
364         for (i = 1; (i << 1) <= val; i <<= 1)
365                 ;
366         osp->opd_pre_create_count = i;
367
368         return count;
369 }
370 LPROC_SEQ_FOPS(osp_create_count);
371
372 /**
373  * Show maximum number of objects to precreate
374  *
375  * \param[in] m         seq_file handle
376  * \param[in] data      unused for single entry
377  * \retval              0 on success
378  * \retval              negative number on error
379  */
380 static int osp_max_create_count_seq_show(struct seq_file *m, void *data)
381 {
382         struct obd_device *obd = m->private;
383         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
384
385         if (osp == NULL || osp->opd_pre == NULL)
386                 return 0;
387
388         seq_printf(m, "%d\n", osp->opd_pre_max_create_count);
389         return 0;
390 }
391
392 /**
393  * Change maximum number of objects to precreate
394  *
395  * \param[in] file      proc file
396  * \param[in] buffer    string which represents maximum number
397  * \param[in] count     \a buffer length
398  * \param[in] off       unused for single entry
399  * \retval              \a count on success
400  * \retval              negative number on error
401  */
402 static ssize_t
403 osp_max_create_count_seq_write(struct file *file, const char __user *buffer,
404                                 size_t count, loff_t *off)
405 {
406         struct seq_file *m = file->private_data;
407         struct obd_device *obd = m->private;
408         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
409         unsigned int val;
410         int rc;
411
412         if (osp == NULL || osp->opd_pre == NULL)
413                 return 0;
414
415         rc = kstrtouint_from_user(buffer, count, 0, &val);
416         if (rc)
417                 return rc;
418
419         if (val < 0 || val > INT_MAX)
420                 return -ERANGE;
421         if (val > OST_MAX_PRECREATE)
422                 return -ERANGE;
423
424         if (osp->opd_pre_create_count > val)
425                 osp->opd_pre_create_count = val;
426
427         osp->opd_pre_max_create_count = val;
428
429         return count;
430 }
431 LPROC_SEQ_FOPS(osp_max_create_count);
432
433 /**
434  * Show last id to assign in creation
435  *
436  * \param[in] m         seq_file handle
437  * \param[in] data      unused for single entry
438  * \retval              0 on success
439  * \retval              negative number on error
440  */
441 static int osp_prealloc_next_id_seq_show(struct seq_file *m, void *data)
442 {
443         struct obd_device *obd = m->private;
444         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
445         struct lu_fid *fid;
446         __u64 id;
447
448         if (osp == NULL || osp->opd_pre == NULL)
449                 return 0;
450
451         fid = &osp->opd_pre_used_fid;
452         if (fid_is_idif(fid)) {
453                 id = fid_idif_id(fid_seq(fid), fid_oid(fid), fid_ver(fid));
454                 id++;
455         } else {
456                 id = unlikely(fid_oid(fid) == LUSTRE_DATA_SEQ_MAX_WIDTH) ?
457                         1 : fid_oid(fid) + 1;
458         }
459
460         seq_printf(m, "%llu\n", id);
461         return 0;
462 }
463 LPROC_SEQ_FOPS_RO(osp_prealloc_next_id);
464
465 /**
466  * Show last created id OST reported
467  *
468  * \param[in] m         seq_file handle
469  * \param[in] data      unused for single entry
470  * \retval              0 on success
471  * \retval              negative number on error
472  */
473 static int osp_prealloc_last_id_seq_show(struct seq_file *m, void *data)
474 {
475         struct obd_device *obd = m->private;
476         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
477         struct lu_fid *fid;
478         __u64 id;
479
480         if (osp == NULL || osp->opd_pre == NULL)
481                 return 0;
482         fid = &osp->opd_pre_last_created_fid;
483         id = fid_is_idif(fid) ?
484                          fid_idif_id(fid_seq(fid), fid_oid(fid), fid_ver(fid)) :
485                          fid_oid(fid);
486
487         seq_printf(m, "%llu\n", id);
488         return 0;
489 }
490 LPROC_SEQ_FOPS_RO(osp_prealloc_last_id);
491
492 /**
493  * Show next FID sequence to precreate
494  *
495  * \param[in] m         seq_file handle
496  * \param[in] data      unused for single entry
497  * \retval              0 on success
498  * \retval              negative number on error
499  */
500 static int osp_prealloc_next_seq_seq_show(struct seq_file *m, void *data)
501 {
502         struct obd_device *obd = m->private;
503         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
504         struct lu_fid *fid;
505
506         if (osp == NULL || osp->opd_pre == NULL)
507                 return 0;
508
509         fid = &osp->opd_pre_used_fid;
510         seq_printf(m, "%#llx\n", fid_is_idif(fid) ?
511                    fid_seq(fid) & (~0xffff) : fid_seq(fid));
512
513         return 0;
514 }
515 LPROC_SEQ_FOPS_RO(osp_prealloc_next_seq);
516
517 /**
518  * Show last created FID sequence OST reported
519  *
520  * \param[in] m         seq_file handle
521  * \param[in] data      unused for single entry
522  * \retval              0 on success
523  * \retval              negative number on error
524  */
525 static int osp_prealloc_last_seq_seq_show(struct seq_file *m, void *data)
526 {
527         struct obd_device *obd = m->private;
528         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
529         struct lu_fid *fid;
530
531         if (osp == NULL || osp->opd_pre == NULL)
532                 return 0;
533
534         fid = &osp->opd_pre_last_created_fid;
535         seq_printf(m, "%#llx\n", fid_is_idif(fid) ?
536                    fid_seq(fid) & (~0xffff) : fid_seq(fid));
537
538         return 0;
539 }
540 LPROC_SEQ_FOPS_RO(osp_prealloc_last_seq);
541
542 /**
543  * Show the number of ids reserved by declare
544  *
545  * \param[in] m         seq_file handle
546  * \param[in] data      unused for single entry
547  * \retval              0 on success
548  * \retval              negative number on error
549  */
550 static int osp_prealloc_reserved_seq_show(struct seq_file *m, void *data)
551 {
552         struct obd_device *obd = m->private;
553         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
554
555         if (osp == NULL || osp->opd_pre == NULL)
556                 return 0;
557
558         seq_printf(m, "%llu\n", osp->opd_pre_reserved);
559         return 0;
560 }
561 LPROC_SEQ_FOPS_RO(osp_prealloc_reserved);
562
563 /**
564  * Show interval (in seconds) to update statfs data
565  *
566  * \param[in] m         seq_file handle
567  * \param[in] data      unused for single entry
568  * \retval              0 on success
569  * \retval              negative number on error
570  */
571 static int osp_maxage_seq_show(struct seq_file *m, void *data)
572 {
573         struct obd_device       *dev = m->private;
574         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
575
576         if (osp == NULL)
577                 return -EINVAL;
578
579         seq_printf(m, "%lld\n", osp->opd_statfs_maxage);
580         return 0;
581 }
582
583 /**
584  * Change interval to update statfs data
585  *
586  * \param[in] file      proc file
587  * \param[in] buffer    string which represents statfs interval (in seconds)
588  * \param[in] count     \a buffer length
589  * \param[in] off       unused for single entry
590  * \retval              \a count on success
591  * \retval              negative number on error
592  */
593 static ssize_t
594 osp_maxage_seq_write(struct file *file, const char __user *buffer,
595                         size_t count, loff_t *off)
596 {
597         struct seq_file *m = file->private_data;
598         struct obd_device *dev = m->private;
599         struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
600         unsigned int val;
601         int rc;
602
603         if (osp == NULL)
604                 return -EINVAL;
605
606         rc = kstrtouint_from_user(buffer, count, 0, &val);
607         if (rc)
608                 return rc;
609
610         if (val == 0)
611                 return -ERANGE;
612
613         osp->opd_statfs_maxage = val;
614
615         return count;
616 }
617 LPROC_SEQ_FOPS(osp_maxage);
618
619 /**
620  * Show current precreation status: output 0 means success, otherwise negative
621  * number is printed
622  *
623  * \param[in] m         seq_file handle
624  * \param[in] data      unused for single entry
625  * \retval              0 on success
626  * \retval              negative number on error
627  */
628 static int osp_pre_status_seq_show(struct seq_file *m, void *data)
629 {
630         struct obd_device       *dev = m->private;
631         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
632
633         if (osp == NULL || osp->opd_pre == NULL)
634                 return -EINVAL;
635
636         seq_printf(m, "%d\n", osp->opd_pre_status);
637         return 0;
638 }
639 LPROC_SEQ_FOPS_RO(osp_pre_status);
640
641 /**
642  * Show the number of RPCs in processing (including uncommitted by OST) plus
643  * changes to sync, i.e. this is the total number of changes OST needs to apply
644  * and commit.
645  *
646  * This counter is used to determine if OST has space returned. A zero value
647  * indicates that OST storage space consumed by destroyed objects has been freed
648  * on disk, the associated llog records have been cleared, and no synchronous
649  * RPC are being processed.
650  *
651  * \param[in] m         seq_file handle
652  * \param[in] data      unused for single entry
653  * \retval              0 on success
654  * \retval              negative number on error
655  */
656 static int osp_destroys_in_flight_seq_show(struct seq_file *m, void *data)
657 {
658         struct obd_device *dev = m->private;
659         struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
660
661         if (osp == NULL)
662                 return -EINVAL;
663
664         seq_printf(m, "%u\n",
665                    atomic_read(&osp->opd_sync_rpcs_in_progress) +
666                    atomic_read(&osp->opd_sync_changes));
667         return 0;
668 }
669 LPROC_SEQ_FOPS_RO(osp_destroys_in_flight);
670
671 /**
672  * Show changes synced from previous mount
673  *
674  * \param[in] m         seq_file handle
675  * \param[in] data      unused for single entry
676  * \retval              0 on success
677  * \retval              negative number on error
678  */
679 static int osp_old_sync_processed_seq_show(struct seq_file *m, void *data)
680 {
681         struct obd_device       *dev = m->private;
682         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
683
684         if (osp == NULL)
685                 return -EINVAL;
686
687         seq_printf(m, "%d\n", osp->opd_sync_prev_done);
688         return 0;
689 }
690 LPROC_SEQ_FOPS_RO(osp_old_sync_processed);
691
692 /**
693  * Show maximum number of RPCs in flight
694  *
695  * \param[in] m         seq_file handle
696  * \param[in] data      unused for single entry
697  * \retval              0 on success
698  * \retval              negative number on error
699  */
700 static int
701 osp_lfsck_max_rpcs_in_flight_seq_show(struct seq_file *m, void *data)
702 {
703         struct obd_device *dev = m->private;
704         __u32 max;
705
706         max = obd_get_max_rpcs_in_flight(&dev->u.cli);
707         seq_printf(m, "%u\n", max);
708         return 0;
709 }
710
711 /**
712  * Change maximum number of RPCs in flight
713  *
714  * \param[in] file      proc file
715  * \param[in] buffer    string which represents maximum number of RPCs in flight
716  * \param[in] count     \a buffer length
717  * \param[in] off       unused for single entry
718  * \retval              \a count on success
719  * \retval              negative number on error
720  */
721 static ssize_t
722 osp_lfsck_max_rpcs_in_flight_seq_write(struct file *file,
723                                        const char __user *buffer,
724                                        size_t count, loff_t *off)
725 {
726         struct seq_file   *m = file->private_data;
727         struct obd_device *dev = m->private;
728         unsigned int val;
729         int rc;
730
731         rc = kstrtouint_from_user(buffer, count, 0, &val);
732         if (!rc)
733                 rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
734         else
735                 count = rc;
736
737         return count;
738 }
739 LPROC_SEQ_FOPS(osp_lfsck_max_rpcs_in_flight);
740
741 LPROC_SEQ_FOPS_WR_ONLY(osp, ping);
742 LPROC_SEQ_FOPS_RO_TYPE(osp, connect_flags);
743 LPROC_SEQ_FOPS_RO_TYPE(osp, server_uuid);
744 LPROC_SEQ_FOPS_RO_TYPE(osp, conn_uuid);
745
746 LPROC_SEQ_FOPS_RO_TYPE(osp, timeouts);
747
748 LPROC_SEQ_FOPS_RW_TYPE(osp, import);
749 LPROC_SEQ_FOPS_RO_TYPE(osp, state);
750
751 /**
752  * Show high watermark (in megabytes). If available free space at OST is grater
753  * than high watermark and object allocation for OST is disabled, enable it.
754  *
755  * \param[in] m         seq_file handle
756  * \param[in] data      unused for single entry
757  * \retval              0 on success
758  * \retval              negative number on error
759  */
760 static int osp_reserved_mb_high_seq_show(struct seq_file *m, void *data)
761 {
762         struct obd_device       *dev = m->private;
763         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
764
765         if (osp == NULL)
766                 return -EINVAL;
767
768         seq_printf(m, "%u\n", osp->opd_reserved_mb_high);
769         return 0;
770 }
771
772 /**
773  * Change high watermark
774  *
775  * \param[in] file      proc file
776  * \param[in] buffer    string which represents new value (in megabytes)
777  * \param[in] count     \a buffer length
778  * \param[in] off       unused for single entry
779  * \retval              \a count on success
780  * \retval              negative number on error
781  */
782 static ssize_t
783 osp_reserved_mb_high_seq_write(struct file *file, const char __user *buffer,
784                         size_t count, loff_t *off)
785 {
786         struct seq_file         *m = file->private_data;
787         struct obd_device       *dev = m->private;
788         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
789         __s64                   val;
790         int                     rc;
791
792         if (osp == NULL)
793                 return -EINVAL;
794
795         rc = lprocfs_str_with_units_to_s64(buffer, count, &val, 'M');
796         if (rc)
797                 return rc;
798         val >>= 20;
799         if (val < 1)
800                 return -ERANGE;
801
802         spin_lock(&osp->opd_pre_lock);
803         osp->opd_reserved_mb_high = val;
804         if (val <= osp->opd_reserved_mb_low)
805                 osp->opd_reserved_mb_low = val - 1;
806         spin_unlock(&osp->opd_pre_lock);
807
808         return count;
809 }
810 LPROC_SEQ_FOPS(osp_reserved_mb_high);
811
812 /**
813  * Show low watermark (in megabytes). If available free space at OST is less
814  * than low watermark, object allocation for OST is disabled.
815  *
816  * \param[in] m         seq_file handle
817  * \param[in] data      unused for single entry
818  * \retval              0 on success
819  * \retval              negative number on error
820  */
821 static int osp_reserved_mb_low_seq_show(struct seq_file *m, void *data)
822 {
823         struct obd_device       *dev = m->private;
824         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
825
826         if (osp == NULL)
827                 return -EINVAL;
828
829         seq_printf(m, "%u\n", osp->opd_reserved_mb_low);
830         return 0;
831 }
832
833 /**
834  * Change low watermark
835  *
836  * \param[in] file      proc file
837  * \param[in] buffer    string which represents new value (in megabytes)
838  * \param[in] count     \a buffer length
839  * \param[in] off       unused for single entry
840  * \retval              \a count on success
841  * \retval              negative number on error
842  */
843 static ssize_t
844 osp_reserved_mb_low_seq_write(struct file *file, const char __user *buffer,
845                         size_t count, loff_t *off)
846 {
847         struct seq_file         *m = file->private_data;
848         struct obd_device       *dev = m->private;
849         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
850         __s64                   val;
851         int                     rc;
852
853         if (osp == NULL)
854                 return -EINVAL;
855
856         rc = lprocfs_str_with_units_to_s64(buffer, count, &val, 'M');
857         if (rc)
858                 return rc;
859         val >>= 20;
860
861         spin_lock(&osp->opd_pre_lock);
862         osp->opd_reserved_mb_low = val;
863         if (val >= osp->opd_reserved_mb_high)
864                 osp->opd_reserved_mb_high = val + 1;
865         spin_unlock(&osp->opd_pre_lock);
866
867         return count;
868 }
869 LPROC_SEQ_FOPS(osp_reserved_mb_low);
870
871 static ssize_t
872 lprocfs_force_sync_seq_write(struct file *file, const char __user *buffer,
873                              size_t count, loff_t *off)
874 {
875         struct seq_file   *m = file->private_data;
876         struct obd_device *dev = m->private;
877         struct dt_device  *dt = lu2dt_dev(dev->obd_lu_dev);
878         struct lu_env      env;
879         int                rc;
880
881         rc = lu_env_init(&env, LCT_LOCAL);
882         if (rc)
883                 return rc;
884         rc = dt_sync(&env, dt);
885         lu_env_fini(&env);
886
887         return rc == 0 ? count : rc;
888 }
889 LPROC_SEQ_FOPS_WR_ONLY(osp, force_sync);
890
891 static struct lprocfs_vars lprocfs_osp_obd_vars[] = {
892         { .name =       "ping",
893           .fops =       &osp_ping_fops,
894           .proc_mode =  0222                            },
895         { .name =       "connect_flags",
896           .fops =       &osp_connect_flags_fops         },
897         { .name =       "ost_server_uuid",
898           .fops =       &osp_server_uuid_fops           },
899         { .name =       "ost_conn_uuid",
900           .fops =       &osp_conn_uuid_fops             },
901         { .name =       "active",
902           .fops =       &osp_active_fops                },
903         { .name =       "max_rpcs_in_flight",
904           .fops =       &osp_max_rpcs_in_flight_fops    },
905         { .name =       "max_rpcs_in_progress",
906           .fops =       &osp_max_rpcs_in_progress_fops  },
907         { .name =       "create_count",
908           .fops =       &osp_create_count_fops          },
909         { .name =       "max_create_count",
910           .fops =       &osp_max_create_count_fops      },
911         { .name =       "prealloc_next_id",
912           .fops =       &osp_prealloc_next_id_fops      },
913         { .name =       "prealloc_next_seq",
914           .fops =       &osp_prealloc_next_seq_fops     },
915         { .name =       "prealloc_last_id",
916           .fops =       &osp_prealloc_last_id_fops      },
917         { .name =       "prealloc_last_seq",
918           .fops =       &osp_prealloc_last_seq_fops     },
919         { .name =       "prealloc_reserved",
920           .fops =       &osp_prealloc_reserved_fops     },
921         { .name =       "timeouts",
922           .fops =       &osp_timeouts_fops              },
923         { .name =       "import",
924           .fops =       &osp_import_fops                },
925         { .name =       "state",
926           .fops =       &osp_state_fops                 },
927         { .name =       "maxage",
928           .fops =       &osp_maxage_fops                },
929         { .name =       "prealloc_status",
930           .fops =       &osp_pre_status_fops            },
931         { .name =       "sync_changes",
932           .fops =       &osp_sync_changes_fops          },
933         { .name =       "sync_in_flight",
934           .fops =       &osp_sync_rpcs_in_flight_fops   },
935         { .name =       "sync_in_progress",
936           .fops =       &osp_sync_rpcs_in_progress_fops },
937         { .name =       "old_sync_processed",
938           .fops =       &osp_old_sync_processed_fops    },
939         { .name =       "reserved_mb_high",
940           .fops =       &osp_reserved_mb_high_fops      },
941         { .name =       "reserved_mb_low",
942           .fops =       &osp_reserved_mb_low_fops       },
943         { .name =       "force_sync",
944           .fops =       &osp_force_sync_fops    },
945
946         /* for compatibility reasons */
947         { .name =       "destroys_in_flight",
948           .fops =       &osp_destroys_in_flight_fops            },
949         { .name =       "lfsck_max_rpcs_in_flight",
950           .fops =       &osp_lfsck_max_rpcs_in_flight_fops      },
951         { NULL }
952 };
953
954 static struct lprocfs_vars lprocfs_osp_md_vars[] = {
955         { .name =       "ping",
956           .fops =       &osp_ping_fops,
957           .proc_mode =  0222                            },
958         { .name =       "connect_flags",
959           .fops =       &osp_connect_flags_fops         },
960         { .name =       "mdt_server_uuid",
961           .fops =       &osp_server_uuid_fops           },
962         { .name =       "mdt_conn_uuid",
963           .fops =       &osp_conn_uuid_fops             },
964         { .name =       "active",
965           .fops =       &osp_active_fops                },
966         { .name =       "max_rpcs_in_flight",
967           .fops =       &osp_max_rpcs_in_flight_fops    },
968         { .name =       "max_rpcs_in_progress",
969           .fops =       &osp_max_rpcs_in_progress_fops  },
970         { .name =       "timeouts",
971           .fops =       &osp_timeouts_fops              },
972         { .name =       "import",
973           .fops =       &osp_import_fops                },
974         { .name =       "state",
975           .fops =       &osp_state_fops                 },
976         { .name =       "maxage",
977           .fops =       &osp_maxage_fops                },
978         { .name =       "prealloc_status",
979           .fops =       &osp_pre_status_fops            },
980
981         /* for compatibility reasons */
982         { .name =       "destroys_in_flight",
983           .fops =       &osp_destroys_in_flight_fops            },
984         { .name =       "lfsck_max_rpcs_in_flight",
985           .fops =       &osp_lfsck_max_rpcs_in_flight_fops      },
986         { NULL }
987 };
988
989 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_blksize);
990 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytestotal);
991 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytesfree);
992 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytesavail);
993 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_filestotal);
994 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_filesfree);
995
996 static struct lprocfs_vars lprocfs_osp_osd_vars[] = {
997         { .name =       "blocksize",
998           .fops =       &osp_dt_blksize_fops            },
999         { .name =       "kbytestotal",
1000           .fops =       &osp_dt_kbytestotal_fops        },
1001         { .name =       "kbytesfree",
1002           .fops =       &osp_dt_kbytesfree_fops         },
1003         { .name =       "kbytesavail",
1004           .fops =       &osp_dt_kbytesavail_fops        },
1005         { .name =       "filestotal",
1006           .fops =       &osp_dt_filestotal_fops         },
1007         { .name =       "filesfree",
1008           .fops =       &osp_dt_filesfree_fops          },
1009         { NULL }
1010 };
1011
1012 /**
1013  * Initialize OSP lprocfs
1014  *
1015  * param[in] osp        OSP device
1016  */
1017 void osp_lprocfs_init(struct osp_device *osp)
1018 {
1019         struct obd_device       *obd = osp->opd_obd;
1020         struct proc_dir_entry   *osc_proc_dir = NULL;
1021         struct obd_type         *type;
1022         int                      rc;
1023
1024         if (osp->opd_connect_mdt)
1025                 obd->obd_vars = lprocfs_osp_md_vars;
1026         else
1027                 obd->obd_vars = lprocfs_osp_obd_vars;
1028         if (lprocfs_obd_setup(obd, true) != 0)
1029                 return;
1030
1031         rc = lprocfs_add_vars(obd->obd_proc_entry, lprocfs_osp_osd_vars,
1032                               &osp->opd_dt_dev);
1033         if (rc) {
1034                 CERROR("%s: can't register in lprocfs, rc %d\n",
1035                        obd->obd_name, rc);
1036                 return;
1037         }
1038
1039         sptlrpc_lprocfs_cliobd_attach(obd);
1040         ptlrpc_lprocfs_register_obd(obd);
1041
1042         if (osp->opd_connect_mdt || !strstr(obd->obd_name, "osc"))
1043                 return;
1044
1045         /* If the real OSC is present which is the case for setups
1046          * with both server and clients on the same node then use
1047          * the OSC's proc root */
1048         type = class_search_type(LUSTRE_OSC_NAME);
1049         if (type != NULL && type->typ_procroot != NULL)
1050                 osc_proc_dir = type->typ_procroot;
1051         else
1052                 osc_proc_dir = obd->obd_type->typ_procsym;
1053
1054         if (osc_proc_dir == NULL)
1055                 return;
1056
1057         /* for compatibility we link old procfs's OSC entries to osp ones */
1058         osp->opd_symlink = lprocfs_add_symlink(obd->obd_name, osc_proc_dir,
1059                                                "../osp/%s", obd->obd_name);
1060         if (osp->opd_symlink == NULL)
1061                 CERROR("cannot create OSC symlink for /proc/fs/lustre/osp/%s\n",
1062                        obd->obd_name);
1063 }
1064
1065 #endif /* CONFIG_PROC_FS */
1066