Whamcloud - gitweb
LU-2446 build: Update Whamcloud copyright messages for Intel
[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.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/ofd/lproc_ofd.c
37  */
38
39 #define DEBUG_SUBSYSTEM S_CLASS
40
41 #include <obd.h>
42 #include <lprocfs_status.h>
43 #include <linux/seq_file.h>
44
45 #include "ofd_internal.h"
46
47 #ifdef LPROCFS
48
49 static int lprocfs_ofd_rd_groups(char *page, char **start, off_t off,
50                                  int count, int *eof, void *data)
51 {
52         struct obd_device *obd = (struct obd_device *)data;
53         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
54
55         *eof = 1;
56         return snprintf(page, count, "%u\n", ofd->ofd_max_group);
57 }
58
59 static int lprocfs_ofd_rd_tot_dirty(char *page, char **start, off_t off,
60                                     int count, int *eof, void *data)
61 {
62         struct obd_device *obd = (struct obd_device *)data;
63         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
64
65         LASSERT(obd != NULL);
66         *eof = 1;
67         return snprintf(page, count, LPU64"\n", ofd->ofd_tot_dirty);
68 }
69
70 static int lprocfs_ofd_rd_tot_granted(char *page, char **start, off_t off,
71                                       int count, int *eof, void *data)
72 {
73         struct obd_device *obd = (struct obd_device *)data;
74         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
75
76         LASSERT(obd != NULL);
77         *eof = 1;
78         return snprintf(page, count, LPU64"\n", ofd->ofd_tot_granted);
79 }
80
81 static int lprocfs_ofd_rd_tot_pending(char *page, char **start, off_t off,
82                                       int count, int *eof, void *data)
83 {
84         struct obd_device *obd = (struct obd_device *)data;
85         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
86
87         LASSERT(obd != NULL);
88         *eof = 1;
89         return snprintf(page, count, LPU64"\n", ofd->ofd_tot_pending);
90 }
91
92 static int lprocfs_ofd_rd_grant_precreate(char *page, char **start, off_t off,
93                                           int count, int *eof, void *data)
94 {
95         struct obd_device *obd = (struct obd_device *)data;
96
97         LASSERT(obd != NULL);
98         *eof = 1;
99         return snprintf(page, count, "%ld\n",
100                         obd->obd_self_export->exp_filter_data.fed_grant);
101 }
102
103 static int lprocfs_ofd_rd_grant_ratio(char *page, char **start, off_t off,
104                                       int count, int *eof, void *data)
105 {
106         struct obd_device *obd = (struct obd_device *)data;
107         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
108
109         LASSERT(obd != NULL);
110         *eof = 1;
111         return snprintf(page, count, "%d%%\n",
112                         (int) ofd_grant_reserved(ofd, 100));
113 }
114
115 static int lprocfs_ofd_wr_grant_ratio(struct file *file, const char *buffer,
116                                       unsigned long count, void *data)
117 {
118         struct obd_device       *obd = (struct obd_device *)data;
119         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
120         int                      val;
121         int                      rc;
122
123         rc = lprocfs_write_helper(buffer, count, &val);
124         if (rc)
125                 return rc;
126
127         if (val > 100 || val < 0)
128                 return -EINVAL;
129
130         if (val == 0)
131                 CWARN("%s: disabling grant error margin\n", obd->obd_name);
132         if (val > 50)
133                 CWARN("%s: setting grant error margin >50%%, be warned that "
134                       "a huge part of the free space is now reserved for "
135                       "grants\n", obd->obd_name);
136
137         spin_lock(&ofd->ofd_grant_lock);
138         ofd->ofd_grant_ratio = ofd_grant_ratio_conv(val);
139         spin_unlock(&ofd->ofd_grant_lock);
140         return count;
141 }
142
143 static int lprocfs_ofd_rd_precreate_batch(char *page, char **start, off_t off,
144                                           int count, int *eof, void *data)
145 {
146         struct obd_device *obd = (struct obd_device *)data;
147         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
148
149         LASSERT(obd != NULL);
150         *eof = 1;
151         return snprintf(page, count, "%d\n", ofd->ofd_precreate_batch);
152 }
153
154 static int lprocfs_ofd_wr_precreate_batch(struct file *file, const char *buffer,
155                                           unsigned long count, void *data)
156 {
157         struct obd_device *obd = (struct obd_device *)data;
158         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
159         int val;
160         int rc;
161
162         rc = lprocfs_write_helper(buffer, count, &val);
163         if (rc)
164                 return rc;
165
166         if (val < 1)
167                 return -EINVAL;
168
169         spin_lock(&ofd->ofd_objid_lock);
170         ofd->ofd_precreate_batch = val;
171         spin_unlock(&ofd->ofd_objid_lock);
172         return count;
173 }
174
175 static int lprocfs_ofd_rd_last_id(char *page, char **start, off_t off,
176                                   int count, int *eof, void *data)
177 {
178         struct obd_device       *obd = data;
179         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
180         int                      retval = 0, rc, i;
181
182         if (obd == NULL)
183                 return 0;
184
185         for (i = FID_SEQ_OST_MDT0; i <= ofd->ofd_max_group; i++) {
186                 rc = snprintf(page, count, LPU64"\n", ofd_last_id(ofd, i));
187                 if (rc < 0) {
188                         retval = rc;
189                         break;
190                 }
191                 page += rc;
192                 count -= rc;
193                 retval += rc;
194         }
195         return retval;
196 }
197
198 int lprocfs_ofd_rd_fmd_max_num(char *page, char **start, off_t off,
199                                int count, int *eof, void *data)
200 {
201         struct obd_device       *obd = data;
202         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
203         int                      rc;
204
205         rc = snprintf(page, count, "%u\n", ofd->ofd_fmd_max_num);
206         return rc;
207 }
208
209 int lprocfs_ofd_wr_fmd_max_num(struct file *file, const char *buffer,
210                                unsigned long count, void *data)
211 {
212         struct obd_device       *obd = data;
213         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
214         int                      val;
215         int                      rc;
216
217         rc = lprocfs_write_helper(buffer, count, &val);
218         if (rc)
219                 return rc;
220
221         if (val > 65536 || val < 1)
222                 return -EINVAL;
223
224         ofd->ofd_fmd_max_num = val;
225         return count;
226 }
227
228 int lprocfs_ofd_rd_fmd_max_age(char *page, char **start, off_t off,
229                                int count, int *eof, void *data)
230 {
231         struct obd_device       *obd = data;
232         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
233         int                      rc;
234
235         rc = snprintf(page, count, "%ld\n", ofd->ofd_fmd_max_age / CFS_HZ);
236         return rc;
237 }
238
239 int lprocfs_ofd_wr_fmd_max_age(struct file *file, const char *buffer,
240                                unsigned long count, void *data)
241 {
242         struct obd_device       *obd = data;
243         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
244         int                      val;
245         int                      rc;
246
247         rc = lprocfs_write_helper(buffer, count, &val);
248         if (rc)
249                 return rc;
250
251         if (val > 65536 || val < 1)
252                 return -EINVAL;
253
254         ofd->ofd_fmd_max_age = val * CFS_HZ;
255         return count;
256 }
257
258 static int lprocfs_ofd_rd_capa(char *page, char **start, off_t off,
259                                int count, int *eof, void *data)
260 {
261         struct obd_device       *obd = data;
262         int                      rc;
263
264         rc = snprintf(page, count, "capability on: %s\n",
265                       obd->u.filter.fo_fl_oss_capa ? "oss" : "");
266         return rc;
267 }
268
269 static int lprocfs_ofd_wr_capa(struct file *file, const char *buffer,
270                                unsigned long count, void *data)
271 {
272         struct obd_device       *obd = data;
273         int                      val, rc;
274
275         rc = lprocfs_write_helper(buffer, count, &val);
276         if (rc)
277                 return rc;
278
279         if (val & ~0x1) {
280                 CERROR("invalid capability mode, only 0/1 are accepted.\n"
281                        " 1: enable oss fid capability\n"
282                        " 0: disable oss fid capability\n");
283                 return -EINVAL;
284         }
285
286         obd->u.filter.fo_fl_oss_capa = val;
287         LCONSOLE_INFO("OSS %s %s fid capability.\n", obd->obd_name,
288                       val ? "enabled" : "disabled");
289         return count;
290 }
291
292 static int lprocfs_ofd_rd_capa_count(char *page, char **start, off_t off,
293                                      int count, int *eof, void *data)
294 {
295         return snprintf(page, count, "%d %d\n",
296                         capa_count[CAPA_SITE_CLIENT],
297                         capa_count[CAPA_SITE_SERVER]);
298 }
299
300 int lprocfs_ofd_rd_degraded(char *page, char **start, off_t off,
301                             int count, int *eof, void *data)
302 {
303         struct obd_device *obd = data;
304         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
305
306         return snprintf(page, count, "%u\n", ofd->ofd_raid_degraded);
307 }
308
309 int lprocfs_ofd_wr_degraded(struct file *file, const char *buffer,
310                             unsigned long count, void *data)
311 {
312         struct obd_device       *obd = data;
313         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
314         int                      val, rc;
315
316         rc = lprocfs_write_helper(buffer, count, &val);
317         if (rc)
318                 return rc;
319
320         spin_lock(&ofd->ofd_flags_lock);
321         ofd->ofd_raid_degraded = !!val;
322         spin_unlock(&ofd->ofd_flags_lock);
323
324         return count;
325 }
326
327 int lprocfs_ofd_rd_fstype(char *page, char **start, off_t off, int count,
328                           int *eof, void *data)
329 {
330         struct obd_device *obd = data;
331         struct ofd_device *ofd = ofd_dev(obd->obd_lu_dev);
332         struct lu_device  *d;
333
334         LASSERT(ofd->ofd_osd);
335         d = &ofd->ofd_osd->dd_lu_dev;
336         LASSERT(d->ld_type);
337         return snprintf(page, count, "%s\n", d->ld_type->ldt_name);
338 }
339
340 int lprocfs_ofd_rd_syncjournal(char *page, char **start, off_t off,
341                                int count, int *eof, void *data)
342 {
343         struct obd_device       *obd = data;
344         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
345         int                      rc;
346
347         rc = snprintf(page, count, "%u\n", ofd->ofd_syncjournal);
348         return rc;
349 }
350
351 int lprocfs_ofd_wr_syncjournal(struct file *file, const char *buffer,
352                                unsigned long count, void *data)
353 {
354         struct obd_device       *obd = data;
355         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
356         int                      val;
357         int                      rc;
358
359         rc = lprocfs_write_helper(buffer, count, &val);
360         if (rc)
361                 return rc;
362
363         if (val < 0)
364                 return -EINVAL;
365
366         spin_lock(&ofd->ofd_flags_lock);
367         ofd->ofd_syncjournal = !!val;
368         ofd_slc_set(ofd);
369         spin_unlock(&ofd->ofd_flags_lock);
370
371         return count;
372 }
373
374 static char *sync_on_cancel_states[] = {"never",
375                                         "blocking",
376                                         "always" };
377
378 int lprocfs_ofd_rd_sync_lock_cancel(char *page, char **start, off_t off,
379                                     int count, int *eof, void *data)
380 {
381         struct obd_device       *obd = data;
382         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
383         int                      rc;
384
385         rc = snprintf(page, count, "%s\n",
386                       sync_on_cancel_states[ofd->ofd_sync_lock_cancel]);
387         return rc;
388 }
389
390 int lprocfs_ofd_wr_sync_lock_cancel(struct file *file, const char *buffer,
391                                     unsigned long count, void *data)
392 {
393         struct obd_device       *obd = data;
394         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
395         int                      val = -1;
396         int                      i;
397
398         for (i = 0 ; i < NUM_SYNC_ON_CANCEL_STATES; i++) {
399                 if (memcmp(buffer, sync_on_cancel_states[i],
400                            strlen(sync_on_cancel_states[i])) == 0) {
401                         val = i;
402                         break;
403                 }
404         }
405         if (val == -1) {
406                 int rc;
407
408                 rc = lprocfs_write_helper(buffer, count, &val);
409                 if (rc)
410                         return rc;
411         }
412
413         if (val < 0 || val > 2)
414                 return -EINVAL;
415
416         spin_lock(&ofd->ofd_flags_lock);
417         ofd->ofd_sync_lock_cancel = val;
418         spin_unlock(&ofd->ofd_flags_lock);
419         return count;
420 }
421
422 int lprocfs_ofd_rd_grant_compat_disable(char *page, char **start, off_t off,
423                                         int count, int *eof, void *data)
424 {
425         struct obd_device       *obd = data;
426         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
427         int                      rc;
428
429         rc = snprintf(page, count, "%u\n", ofd->ofd_grant_compat_disable);
430         return rc;
431 }
432
433 int lprocfs_ofd_wr_grant_compat_disable(struct file *file, const char *buffer,
434                                         unsigned long count, void *data)
435 {
436         struct obd_device       *obd = data;
437         struct ofd_device       *ofd = ofd_dev(obd->obd_lu_dev);
438         int                      val;
439         int                      rc;
440
441         rc = lprocfs_write_helper(buffer, count, &val);
442         if (rc)
443                 return rc;
444
445         if (val < 0)
446                 return -EINVAL;
447
448         spin_lock(&ofd->ofd_flags_lock);
449         ofd->ofd_grant_compat_disable = !!val;
450         spin_unlock(&ofd->ofd_flags_lock);
451
452         return count;
453 }
454
455 static struct lprocfs_vars lprocfs_ofd_obd_vars[] = {
456         { "uuid",                lprocfs_rd_uuid, 0, 0 },
457         { "blocksize",           lprocfs_rd_blksize, 0, 0 },
458         { "kbytestotal",         lprocfs_rd_kbytestotal, 0, 0 },
459         { "kbytesfree",          lprocfs_rd_kbytesfree, 0, 0 },
460         { "kbytesavail",         lprocfs_rd_kbytesavail, 0, 0 },
461         { "filestotal",          lprocfs_rd_filestotal, 0, 0 },
462         { "filesfree",           lprocfs_rd_filesfree, 0, 0 },
463         { "filegroups",          lprocfs_ofd_rd_groups, 0, 0 },
464         { "fstype",              lprocfs_ofd_rd_fstype, 0, 0 },
465         { "last_id",             lprocfs_ofd_rd_last_id, 0, 0 },
466         { "tot_dirty",           lprocfs_ofd_rd_tot_dirty,   0, 0 },
467         { "tot_pending",         lprocfs_ofd_rd_tot_pending, 0, 0 },
468         { "tot_granted",         lprocfs_ofd_rd_tot_granted, 0, 0 },
469         { "grant_precreate",     lprocfs_ofd_rd_grant_precreate, 0, 0 },
470         { "grant_ratio",         lprocfs_ofd_rd_grant_ratio,
471                                  lprocfs_ofd_wr_grant_ratio, 0, 0 },
472         { "precreate_batch",     lprocfs_ofd_rd_precreate_batch,
473                                  lprocfs_ofd_wr_precreate_batch, 0 },
474         { "recovery_status",     lprocfs_obd_rd_recovery_status, 0, 0 },
475         { "recovery_time_soft",  lprocfs_obd_rd_recovery_time_soft,
476                                  lprocfs_obd_wr_recovery_time_soft, 0},
477         { "recovery_time_hard",  lprocfs_obd_rd_recovery_time_hard,
478                                  lprocfs_obd_wr_recovery_time_hard, 0},
479         { "evict_client",        0, lprocfs_wr_evict_client, 0,
480                                  &lprocfs_evict_client_fops},
481         { "num_exports",         lprocfs_rd_num_exports,   0, 0 },
482         { "degraded",            lprocfs_ofd_rd_degraded,
483                                  lprocfs_ofd_wr_degraded, 0},
484         { "sync_journal",        lprocfs_ofd_rd_syncjournal,
485                                  lprocfs_ofd_wr_syncjournal, 0 },
486         { "sync_on_lock_cancel", lprocfs_ofd_rd_sync_lock_cancel,
487                                  lprocfs_ofd_wr_sync_lock_cancel, 0 },
488         { "instance",            lprocfs_target_rd_instance, 0 },
489         { "ir_factor",           lprocfs_obd_rd_ir_factor,
490                                  lprocfs_obd_wr_ir_factor, 0},
491         { "grant_compat_disable", lprocfs_ofd_rd_grant_compat_disable,
492                                   lprocfs_ofd_wr_grant_compat_disable, 0 },
493         { "client_cache_count",  lprocfs_ofd_rd_fmd_max_num,
494                                  lprocfs_ofd_wr_fmd_max_num, 0 },
495         { "client_cache_seconds", lprocfs_ofd_rd_fmd_max_age,
496                                   lprocfs_ofd_wr_fmd_max_age, 0 },
497         { "capa",                lprocfs_ofd_rd_capa,
498                                  lprocfs_ofd_wr_capa, 0 },
499         { "capa_count",          lprocfs_ofd_rd_capa_count, 0, 0 },
500         { "job_cleanup_interval", lprocfs_rd_job_interval,
501                                   lprocfs_wr_job_interval, 0},
502         { 0 }
503 };
504
505 static struct lprocfs_vars lprocfs_ofd_module_vars[] = {
506         { "num_refs",     lprocfs_rd_numrefs,   0, 0 },
507         { 0 }
508 };
509
510 #define pct(a,b) (b ? a * 100 / b : 0)
511
512 static void display_brw_stats(struct seq_file *seq, char *name, char *units,
513                               struct obd_histogram *read,
514                               struct obd_histogram *write, int log2)
515 {
516         unsigned long   read_tot, write_tot, r, w, read_cum = 0, write_cum = 0;
517         int             i;
518
519         seq_printf(seq, "\n%26s read      |     write\n", " ");
520         seq_printf(seq, "%-22s %-5s %% cum %% |  %-5s %% cum %%\n",
521                    name, units, units);
522
523         read_tot = lprocfs_oh_sum(read);
524         write_tot = lprocfs_oh_sum(write);
525         for (i = 0; i < OBD_HIST_MAX; i++) {
526                 r = read->oh_buckets[i];
527                 w = write->oh_buckets[i];
528                 read_cum += r;
529                 write_cum += w;
530                 if (read_cum == 0 && write_cum == 0)
531                         continue;
532
533                 if (!log2)
534                         seq_printf(seq, "%u", i);
535                 else if (i < 10)
536                         seq_printf(seq, "%u", 1 << i);
537                 else if (i < 20)
538                         seq_printf(seq, "%uK", 1 << (i - 10));
539                 else
540                         seq_printf(seq, "%uM", 1 << (i - 20));
541
542                 seq_printf(seq, ":\t\t%10lu %3lu %3lu   | %4lu %3lu %3lu\n",
543                            r, pct(r, read_tot), pct(read_cum, read_tot),
544                            w, pct(w, write_tot), pct(write_cum, write_tot));
545
546                 if (read_cum == read_tot && write_cum == write_tot)
547                         break;
548         }
549 }
550
551 static void brw_stats_show(struct seq_file *seq, struct brw_stats *brw_stats)
552 {
553         struct timeval  now;
554         char            title[24];
555
556         /* this sampling races with updates */
557         cfs_gettimeofday(&now);
558         seq_printf(seq, "snapshot_time:         %lu.%lu (secs.usecs)\n",
559                    now.tv_sec, now.tv_usec);
560
561         display_brw_stats(seq, "pages per bulk r/w", "rpcs",
562                           &brw_stats->hist[BRW_R_PAGES],
563                           &brw_stats->hist[BRW_W_PAGES], 1);
564
565         display_brw_stats(seq, "discontiguous pages", "rpcs",
566                           &brw_stats->hist[BRW_R_DISCONT_PAGES],
567                           &brw_stats->hist[BRW_W_DISCONT_PAGES], 0);
568
569         display_brw_stats(seq, "discontiguous blocks", "rpcs",
570                           &brw_stats->hist[BRW_R_DISCONT_BLOCKS],
571                           &brw_stats->hist[BRW_W_DISCONT_BLOCKS], 0);
572
573         display_brw_stats(seq, "disk fragmented I/Os", "ios",
574                           &brw_stats->hist[BRW_R_DIO_FRAGS],
575                           &brw_stats->hist[BRW_W_DIO_FRAGS], 0);
576
577         display_brw_stats(seq, "disk I/Os in flight", "ios",
578                           &brw_stats->hist[BRW_R_RPC_HIST],
579                           &brw_stats->hist[BRW_W_RPC_HIST], 0);
580
581         sprintf(title, "I/O time (1/%ds)", CFS_HZ);
582         display_brw_stats(seq, title, "ios",
583                           &brw_stats->hist[BRW_R_IO_TIME],
584                           &brw_stats->hist[BRW_W_IO_TIME], 1);
585
586         display_brw_stats(seq, "disk I/O size", "ios",
587                           &brw_stats->hist[BRW_R_DISK_IOSIZE],
588                           &brw_stats->hist[BRW_W_DISK_IOSIZE], 1);
589 }
590
591 #undef pct
592
593 static int ofd_brw_stats_seq_show(struct seq_file *seq, void *v)
594 {
595         struct obd_device *dev = seq->private;
596         struct filter_obd *ofd = &dev->u.filter;
597
598         brw_stats_show(seq, &ofd->fo_filter_stats);
599
600         return 0;
601 }
602
603 static ssize_t ofd_brw_stats_seq_write(struct file *file, const char *buf,
604                                        size_t len, loff_t *off)
605 {
606         struct seq_file         *seq = file->private_data;
607         struct obd_device       *dev = seq->private;
608         struct filter_obd       *ofd = &dev->u.filter;
609         int                      i;
610
611         for (i = 0; i < BRW_LAST; i++)
612                 lprocfs_oh_clear(&ofd->fo_filter_stats.hist[i]);
613
614         return len;
615 }
616
617 LPROC_SEQ_FOPS(ofd_brw_stats);
618
619 int lproc_ofd_attach_seqstat(struct obd_device *dev)
620 {
621         return lprocfs_obd_seq_create(dev, "brw_stats", 0444,
622                                       &ofd_brw_stats_fops, dev);
623 }
624
625 void lprocfs_ofd_init_vars(struct lprocfs_static_vars *lvars)
626 {
627         lvars->module_vars  = lprocfs_ofd_module_vars;
628         lvars->obd_vars     = lprocfs_ofd_obd_vars;
629 }
630
631 static int ofd_per_nid_stats_seq_show(struct seq_file *seq, void *v)
632 {
633         nid_stat_t *stat = seq->private;
634
635         if (stat->nid_brw_stats)
636                 brw_stats_show(seq, stat->nid_brw_stats);
637
638         return 0;
639 }
640
641 static ssize_t ofd_per_nid_stats_seq_write(struct file *file, const char *buf,
642                                            size_t len, loff_t *off)
643 {
644         struct seq_file *seq = file->private_data;
645         nid_stat_t      *stat = seq->private;
646         int              i;
647
648         if (stat->nid_brw_stats)
649                 for (i = 0; i < BRW_LAST; i++)
650                         lprocfs_oh_clear(&stat->nid_brw_stats->hist[i]);
651
652         return len;
653 }
654
655 LPROC_SEQ_FOPS(ofd_per_nid_stats);
656
657 void ofd_stats_counter_init(struct lprocfs_stats *stats)
658 {
659         LASSERT(stats && stats->ls_num == LPROC_OFD_STATS_LAST);
660         lprocfs_counter_init(stats, LPROC_OFD_STATS_READ,
661                              LPROCFS_CNTR_AVGMINMAX, "read", "bytes");
662         lprocfs_counter_init(stats, LPROC_OFD_STATS_WRITE,
663                              LPROCFS_CNTR_AVGMINMAX, "write", "bytes");
664         lprocfs_counter_init(stats, LPROC_OFD_STATS_SETATTR,
665                              0, "setattr", "reqs");
666         lprocfs_counter_init(stats, LPROC_OFD_STATS_PUNCH,
667                              0, "punch", "reqs");
668         lprocfs_counter_init(stats, LPROC_OFD_STATS_SYNC,
669                              0, "sync", "reqs");
670 }
671 #endif /* LPROCFS */