linux/drivers/staging/lustre/lustre/include/lprocfs_status.h
<<
>>
Prefs
   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) 2011, 2015, 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/include/lprocfs_status.h
  33 *
  34 * Top level header file for LProc SNMP
  35 *
  36 * Author: Hariharan Thantry thantry@users.sourceforge.net
  37 */
  38#ifndef _LPROCFS_SNMP_H
  39#define _LPROCFS_SNMP_H
  40
  41#include <linux/debugfs.h>
  42#include <linux/seq_file.h>
  43#include <linux/spinlock.h>
  44#include <linux/types.h>
  45
  46#include "lustre/lustre_idl.h"
  47
  48struct lprocfs_vars {
  49        const char              *name;
  50        struct file_operations  *fops;
  51        void                    *data;
  52        /**
  53         * sysfs file mode.
  54         */
  55        umode_t                 proc_mode;
  56};
  57
  58struct lprocfs_static_vars {
  59        struct lprocfs_vars *obd_vars;
  60        struct attribute_group *sysfs_vars;
  61};
  62
  63/* if we find more consumers this could be generalized */
  64#define OBD_HIST_MAX 32
  65struct obd_histogram {
  66        spinlock_t      oh_lock;
  67        unsigned long   oh_buckets[OBD_HIST_MAX];
  68};
  69
  70enum {
  71        BRW_R_PAGES = 0,
  72        BRW_W_PAGES,
  73        BRW_R_RPC_HIST,
  74        BRW_W_RPC_HIST,
  75        BRW_R_IO_TIME,
  76        BRW_W_IO_TIME,
  77        BRW_R_DISCONT_PAGES,
  78        BRW_W_DISCONT_PAGES,
  79        BRW_R_DISCONT_BLOCKS,
  80        BRW_W_DISCONT_BLOCKS,
  81        BRW_R_DISK_IOSIZE,
  82        BRW_W_DISK_IOSIZE,
  83        BRW_R_DIO_FRAGS,
  84        BRW_W_DIO_FRAGS,
  85        BRW_LAST,
  86};
  87
  88struct brw_stats {
  89        struct obd_histogram hist[BRW_LAST];
  90};
  91
  92enum {
  93        RENAME_SAMEDIR_SIZE = 0,
  94        RENAME_CROSSDIR_SRC_SIZE,
  95        RENAME_CROSSDIR_TGT_SIZE,
  96        RENAME_LAST,
  97};
  98
  99struct rename_stats {
 100        struct obd_histogram hist[RENAME_LAST];
 101};
 102
 103/* An lprocfs counter can be configured using the enum bit masks below.
 104 *
 105 * LPROCFS_CNTR_EXTERNALLOCK indicates that an external lock already
 106 * protects this counter from concurrent updates. If not specified,
 107 * lprocfs an internal per-counter lock variable. External locks are
 108 * not used to protect counter increments, but are used to protect
 109 * counter readout and resets.
 110 *
 111 * LPROCFS_CNTR_AVGMINMAX indicates a multi-valued counter samples,
 112 * (i.e. counter can be incremented by more than "1"). When specified,
 113 * the counter maintains min, max and sum in addition to a simple
 114 * invocation count. This allows averages to be be computed.
 115 * If not specified, the counter is an increment-by-1 counter.
 116 * min, max, sum, etc. are not maintained.
 117 *
 118 * LPROCFS_CNTR_STDDEV indicates that the counter should track sum of
 119 * squares (for multi-valued counter samples only). This allows
 120 * external computation of standard deviation, but involves a 64-bit
 121 * multiply per counter increment.
 122 */
 123
 124enum {
 125        LPROCFS_CNTR_EXTERNALLOCK = 0x0001,
 126        LPROCFS_CNTR_AVGMINMAX    = 0x0002,
 127        LPROCFS_CNTR_STDDEV       = 0x0004,
 128
 129        /* counter data type */
 130        LPROCFS_TYPE_REGS        = 0x0100,
 131        LPROCFS_TYPE_BYTES      = 0x0200,
 132        LPROCFS_TYPE_PAGES      = 0x0400,
 133        LPROCFS_TYPE_CYCLE      = 0x0800,
 134};
 135
 136#define LC_MIN_INIT ((~(__u64)0) >> 1)
 137
 138struct lprocfs_counter_header {
 139        unsigned int            lc_config;
 140        const char              *lc_name;   /* must be static */
 141        const char              *lc_units;  /* must be static */
 142};
 143
 144struct lprocfs_counter {
 145        __s64   lc_count;
 146        __s64   lc_min;
 147        __s64   lc_max;
 148        __s64   lc_sumsquare;
 149        /*
 150         * Every counter has lc_array_sum[0], while lc_array_sum[1] is only
 151         * for irq context counter, i.e. stats with
 152         * LPROCFS_STATS_FLAG_IRQ_SAFE flag, its counter need
 153         * lc_array_sum[1]
 154         */
 155        __s64   lc_array_sum[1];
 156};
 157
 158#define lc_sum          lc_array_sum[0]
 159#define lc_sum_irq      lc_array_sum[1]
 160
 161struct lprocfs_percpu {
 162#ifndef __GNUC__
 163        __s64                   pad;
 164#endif
 165        struct lprocfs_counter lp_cntr[0];
 166};
 167
 168enum lprocfs_stats_lock_ops {
 169        LPROCFS_GET_NUM_CPU     = 0x0001, /* number allocated per-CPU stats */
 170        LPROCFS_GET_SMP_ID      = 0x0002, /* current stat to be updated */
 171};
 172
 173enum lprocfs_stats_flags {
 174        LPROCFS_STATS_FLAG_NONE     = 0x0000, /* per cpu counter */
 175        LPROCFS_STATS_FLAG_NOPERCPU = 0x0001, /* stats have no percpu
 176                                               * area and need locking
 177                                               */
 178        LPROCFS_STATS_FLAG_IRQ_SAFE = 0x0002, /* alloc need irq safe */
 179};
 180
 181enum lprocfs_fields_flags {
 182        LPROCFS_FIELDS_FLAGS_CONFIG     = 0x0001,
 183        LPROCFS_FIELDS_FLAGS_SUM        = 0x0002,
 184        LPROCFS_FIELDS_FLAGS_MIN        = 0x0003,
 185        LPROCFS_FIELDS_FLAGS_MAX        = 0x0004,
 186        LPROCFS_FIELDS_FLAGS_AVG        = 0x0005,
 187        LPROCFS_FIELDS_FLAGS_SUMSQUARE  = 0x0006,
 188        LPROCFS_FIELDS_FLAGS_COUNT      = 0x0007,
 189};
 190
 191struct lprocfs_stats {
 192        /* # of counters */
 193        unsigned short                  ls_num;
 194        /* 1 + the biggest cpu # whose ls_percpu slot has been allocated */
 195        unsigned short                  ls_biggest_alloc_num;
 196        enum lprocfs_stats_flags        ls_flags;
 197        /* Lock used when there are no percpu stats areas; For percpu stats,
 198         * it is used to protect ls_biggest_alloc_num change
 199         */
 200        spinlock_t                      ls_lock;
 201
 202        /* has ls_num of counter headers */
 203        struct lprocfs_counter_header   *ls_cnt_header;
 204        struct lprocfs_percpu           *ls_percpu[0];
 205};
 206
 207#define OPC_RANGE(seg) (seg ## _LAST_OPC - seg ## _FIRST_OPC)
 208
 209/* Pack all opcodes down into a single monotonically increasing index */
 210static inline int opcode_offset(__u32 opc)
 211{
 212        if (opc < OST_LAST_OPC) {
 213                 /* OST opcode */
 214                return (opc - OST_FIRST_OPC);
 215        } else if (opc < MDS_LAST_OPC) {
 216                /* MDS opcode */
 217                return (opc - MDS_FIRST_OPC +
 218                        OPC_RANGE(OST));
 219        } else if (opc < LDLM_LAST_OPC) {
 220                /* LDLM Opcode */
 221                return (opc - LDLM_FIRST_OPC +
 222                        OPC_RANGE(MDS) +
 223                        OPC_RANGE(OST));
 224        } else if (opc < MGS_LAST_OPC) {
 225                /* MGS Opcode */
 226                return (opc - MGS_FIRST_OPC +
 227                        OPC_RANGE(LDLM) +
 228                        OPC_RANGE(MDS) +
 229                        OPC_RANGE(OST));
 230        } else if (opc < OBD_LAST_OPC) {
 231                /* OBD Ping */
 232                return (opc - OBD_FIRST_OPC +
 233                        OPC_RANGE(MGS) +
 234                        OPC_RANGE(LDLM) +
 235                        OPC_RANGE(MDS) +
 236                        OPC_RANGE(OST));
 237        } else if (opc < LLOG_LAST_OPC) {
 238                /* LLOG Opcode */
 239                return (opc - LLOG_FIRST_OPC +
 240                        OPC_RANGE(OBD) +
 241                        OPC_RANGE(MGS) +
 242                        OPC_RANGE(LDLM) +
 243                        OPC_RANGE(MDS) +
 244                        OPC_RANGE(OST));
 245        } else if (opc < QUOTA_LAST_OPC) {
 246                /* LQUOTA Opcode */
 247                return (opc - QUOTA_FIRST_OPC +
 248                        OPC_RANGE(LLOG) +
 249                        OPC_RANGE(OBD) +
 250                        OPC_RANGE(MGS) +
 251                        OPC_RANGE(LDLM) +
 252                        OPC_RANGE(MDS) +
 253                        OPC_RANGE(OST));
 254        } else if (opc < SEQ_LAST_OPC) {
 255                /* SEQ opcode */
 256                return (opc - SEQ_FIRST_OPC +
 257                        OPC_RANGE(QUOTA) +
 258                        OPC_RANGE(LLOG) +
 259                        OPC_RANGE(OBD) +
 260                        OPC_RANGE(MGS) +
 261                        OPC_RANGE(LDLM) +
 262                        OPC_RANGE(MDS) +
 263                        OPC_RANGE(OST));
 264        } else if (opc < SEC_LAST_OPC) {
 265                /* SEC opcode */
 266                return (opc - SEC_FIRST_OPC +
 267                        OPC_RANGE(SEQ) +
 268                        OPC_RANGE(QUOTA) +
 269                        OPC_RANGE(LLOG) +
 270                        OPC_RANGE(OBD) +
 271                        OPC_RANGE(MGS) +
 272                        OPC_RANGE(LDLM) +
 273                        OPC_RANGE(MDS) +
 274                        OPC_RANGE(OST));
 275        } else if (opc < FLD_LAST_OPC) {
 276                /* FLD opcode */
 277                return (opc - FLD_FIRST_OPC +
 278                        OPC_RANGE(SEC) +
 279                        OPC_RANGE(SEQ) +
 280                        OPC_RANGE(QUOTA) +
 281                        OPC_RANGE(LLOG) +
 282                        OPC_RANGE(OBD) +
 283                        OPC_RANGE(MGS) +
 284                        OPC_RANGE(LDLM) +
 285                        OPC_RANGE(MDS) +
 286                        OPC_RANGE(OST));
 287        } else {
 288                /* Unknown Opcode */
 289                return -1;
 290        }
 291}
 292
 293#define LUSTRE_MAX_OPCODES (OPC_RANGE(OST)  + \
 294                            OPC_RANGE(MDS)  + \
 295                            OPC_RANGE(LDLM) + \
 296                            OPC_RANGE(MGS)  + \
 297                            OPC_RANGE(OBD)  + \
 298                            OPC_RANGE(LLOG) + \
 299                            OPC_RANGE(SEC)  + \
 300                            OPC_RANGE(SEQ)  + \
 301                            OPC_RANGE(SEC)  + \
 302                            OPC_RANGE(FLD))
 303
 304#define EXTRA_MAX_OPCODES ((PTLRPC_LAST_CNTR - PTLRPC_FIRST_CNTR)  + \
 305                            OPC_RANGE(EXTRA))
 306
 307enum {
 308        PTLRPC_REQWAIT_CNTR = 0,
 309        PTLRPC_REQQDEPTH_CNTR,
 310        PTLRPC_REQACTIVE_CNTR,
 311        PTLRPC_TIMEOUT,
 312        PTLRPC_REQBUF_AVAIL_CNTR,
 313        PTLRPC_LAST_CNTR
 314};
 315
 316#define PTLRPC_FIRST_CNTR PTLRPC_REQWAIT_CNTR
 317
 318enum {
 319        LDLM_GLIMPSE_ENQUEUE = 0,
 320        LDLM_PLAIN_ENQUEUE,
 321        LDLM_EXTENT_ENQUEUE,
 322        LDLM_FLOCK_ENQUEUE,
 323        LDLM_IBITS_ENQUEUE,
 324        MDS_REINT_SETATTR,
 325        MDS_REINT_CREATE,
 326        MDS_REINT_LINK,
 327        MDS_REINT_UNLINK,
 328        MDS_REINT_RENAME,
 329        MDS_REINT_OPEN,
 330        MDS_REINT_SETXATTR,
 331        BRW_READ_BYTES,
 332        BRW_WRITE_BYTES,
 333        EXTRA_LAST_OPC
 334};
 335
 336#define EXTRA_FIRST_OPC LDLM_GLIMPSE_ENQUEUE
 337/* class_obd.c */
 338extern struct dentry *debugfs_lustre_root;
 339extern struct kobject *lustre_kobj;
 340
 341struct obd_device;
 342struct obd_histogram;
 343
 344/* Days / hours / mins / seconds format */
 345struct dhms {
 346        int d, h, m, s;
 347};
 348
 349static inline void s2dhms(struct dhms *ts, time64_t secs64)
 350{
 351        unsigned int secs;
 352
 353        ts->d = div_u64_rem(secs64, 86400, &secs);
 354        ts->h = secs / 3600;
 355        secs = secs % 3600;
 356        ts->m = secs / 60;
 357        ts->s = secs % 60;
 358}
 359
 360#define DHMS_FMT "%dd%dh%02dm%02ds"
 361#define DHMS_VARS(x) (x)->d, (x)->h, (x)->m, (x)->s
 362
 363#define JOBSTATS_JOBID_VAR_MAX_LEN      20
 364#define JOBSTATS_DISABLE                "disable"
 365#define JOBSTATS_PROCNAME_UID           "procname_uid"
 366#define JOBSTATS_NODELOCAL              "nodelocal"
 367
 368/* obd_config.c */
 369void lustre_register_client_process_config(int (*cpc)(struct lustre_cfg *lcfg));
 370
 371int lprocfs_write_frac_helper(const char __user *buffer,
 372                              unsigned long count, int *val, int mult);
 373int lprocfs_read_frac_helper(char *buffer, unsigned long count,
 374                             long val, int mult);
 375int lprocfs_stats_alloc_one(struct lprocfs_stats *stats, unsigned int cpuid);
 376
 377/**
 378 * Lock statistics structure for access, possibly only on this CPU.
 379 *
 380 * The statistics struct may be allocated with per-CPU structures for
 381 * efficient concurrent update (usually only on server-wide stats), or
 382 * as a single global struct (e.g. for per-client or per-job statistics),
 383 * so the required locking depends on the type of structure allocated.
 384 *
 385 * For per-CPU statistics, pin the thread to the current cpuid so that
 386 * will only access the statistics for that CPU.  If the stats structure
 387 * for the current CPU has not been allocated (or previously freed),
 388 * allocate it now.  The per-CPU statistics do not need locking since
 389 * the thread is pinned to the CPU during update.
 390 *
 391 * For global statistics, lock the stats structure to prevent concurrent update.
 392 *
 393 * \param[in] stats     statistics structure to lock
 394 * \param[in] opc       type of operation:
 395 *                      LPROCFS_GET_SMP_ID: "lock" and return current CPU index
 396 *                              for incrementing statistics for that CPU
 397 *                      LPROCFS_GET_NUM_CPU: "lock" and return number of used
 398 *                              CPU indices to iterate over all indices
 399 * \param[out] flags    CPU interrupt saved state for IRQ-safe locking
 400 *
 401 * \retval cpuid of current thread or number of allocated structs
 402 * \retval negative on error (only for opc LPROCFS_GET_SMP_ID + per-CPU stats)
 403 */
 404static inline int lprocfs_stats_lock(struct lprocfs_stats *stats,
 405                                     enum lprocfs_stats_lock_ops opc,
 406                                     unsigned long *flags)
 407{
 408        if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
 409                if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
 410                        spin_lock_irqsave(&stats->ls_lock, *flags);
 411                else
 412                        spin_lock(&stats->ls_lock);
 413                return opc == LPROCFS_GET_NUM_CPU ? 1 : 0;
 414        }
 415
 416        switch (opc) {
 417        case LPROCFS_GET_SMP_ID: {
 418                unsigned int cpuid = get_cpu();
 419
 420                if (unlikely(!stats->ls_percpu[cpuid])) {
 421                        int rc = lprocfs_stats_alloc_one(stats, cpuid);
 422
 423                        if (rc < 0) {
 424                                put_cpu();
 425                                return rc;
 426                        }
 427                }
 428                return cpuid;
 429        }
 430        case LPROCFS_GET_NUM_CPU:
 431                return stats->ls_biggest_alloc_num;
 432        default:
 433                LBUG();
 434        }
 435}
 436
 437/**
 438 * Unlock statistics structure after access.
 439 *
 440 * Unlock the lock acquired via lprocfs_stats_lock() for global statistics,
 441 * or unpin this thread from the current cpuid for per-CPU statistics.
 442 *
 443 * This function must be called using the same arguments as used when calling
 444 * lprocfs_stats_lock() so that the correct operation can be performed.
 445 *
 446 * \param[in] stats     statistics structure to unlock
 447 * \param[in] opc       type of operation (current cpuid or number of structs)
 448 * \param[in] flags     CPU interrupt saved state for IRQ-safe locking
 449 */
 450static inline void lprocfs_stats_unlock(struct lprocfs_stats *stats,
 451                                        enum lprocfs_stats_lock_ops opc,
 452                                        unsigned long *flags)
 453{
 454        if (stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) {
 455                if (stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE)
 456                        spin_unlock_irqrestore(&stats->ls_lock, *flags);
 457                else
 458                        spin_unlock(&stats->ls_lock);
 459        } else if (opc == LPROCFS_GET_SMP_ID) {
 460                put_cpu();
 461        }
 462}
 463
 464static inline unsigned int
 465lprocfs_stats_counter_size(struct lprocfs_stats *stats)
 466{
 467        unsigned int percpusize;
 468
 469        percpusize = offsetof(struct lprocfs_percpu, lp_cntr[stats->ls_num]);
 470
 471        /* irq safe stats need lc_array_sum[1] */
 472        if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
 473                percpusize += stats->ls_num * sizeof(__s64);
 474
 475        if ((stats->ls_flags & LPROCFS_STATS_FLAG_NOPERCPU) == 0)
 476                percpusize = L1_CACHE_ALIGN(percpusize);
 477
 478        return percpusize;
 479}
 480
 481static inline struct lprocfs_counter *
 482lprocfs_stats_counter_get(struct lprocfs_stats *stats, unsigned int cpuid,
 483                          int index)
 484{
 485        struct lprocfs_counter *cntr;
 486
 487        cntr = &stats->ls_percpu[cpuid]->lp_cntr[index];
 488
 489        if ((stats->ls_flags & LPROCFS_STATS_FLAG_IRQ_SAFE) != 0)
 490                cntr = (void *)cntr + index * sizeof(__s64);
 491
 492        return cntr;
 493}
 494
 495/* Two optimized LPROCFS counter increment functions are provided:
 496 *     lprocfs_counter_incr(cntr, value) - optimized for by-one counters
 497 *     lprocfs_counter_add(cntr) - use for multi-valued counters
 498 * Counter data layout allows config flag, counter lock and the
 499 * count itself to reside within a single cache line.
 500 */
 501
 502void lprocfs_counter_add(struct lprocfs_stats *stats, int idx, long amount);
 503void lprocfs_counter_sub(struct lprocfs_stats *stats, int idx, long amount);
 504
 505#define lprocfs_counter_incr(stats, idx) \
 506        lprocfs_counter_add(stats, idx, 1)
 507#define lprocfs_counter_decr(stats, idx) \
 508        lprocfs_counter_sub(stats, idx, 1)
 509
 510__s64 lprocfs_read_helper(struct lprocfs_counter *lc,
 511                          struct lprocfs_counter_header *header,
 512                          enum lprocfs_stats_flags flags,
 513                          enum lprocfs_fields_flags field);
 514static inline __u64 lprocfs_stats_collector(struct lprocfs_stats *stats,
 515                                            int idx,
 516                                            enum lprocfs_fields_flags field)
 517{
 518        unsigned int i;
 519        unsigned int  num_cpu;
 520        unsigned long flags     = 0;
 521        __u64         ret       = 0;
 522
 523        LASSERT(stats);
 524
 525        num_cpu = lprocfs_stats_lock(stats, LPROCFS_GET_NUM_CPU, &flags);
 526        for (i = 0; i < num_cpu; i++) {
 527                if (!stats->ls_percpu[i])
 528                        continue;
 529                ret += lprocfs_read_helper(
 530                                lprocfs_stats_counter_get(stats, i, idx),
 531                                &stats->ls_cnt_header[idx], stats->ls_flags,
 532                                field);
 533        }
 534        lprocfs_stats_unlock(stats, LPROCFS_GET_NUM_CPU, &flags);
 535        return ret;
 536}
 537
 538extern struct lprocfs_stats *
 539lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags);
 540void lprocfs_clear_stats(struct lprocfs_stats *stats);
 541void lprocfs_free_stats(struct lprocfs_stats **stats);
 542void lprocfs_counter_init(struct lprocfs_stats *stats, int index,
 543                          unsigned conf, const char *name, const char *units);
 544struct obd_export;
 545int lprocfs_exp_cleanup(struct obd_export *exp);
 546struct dentry *ldebugfs_add_simple(struct dentry *root,
 547                                   char *name,
 548                                   void *data,
 549                                   struct file_operations *fops);
 550
 551int ldebugfs_register_stats(struct dentry *parent,
 552                            const char *name,
 553                            struct lprocfs_stats *stats);
 554
 555/* lprocfs_status.c */
 556int ldebugfs_add_vars(struct dentry *parent,
 557                      struct lprocfs_vars *var,
 558                      void *data);
 559
 560struct dentry *ldebugfs_register(const char *name,
 561                                 struct dentry *parent,
 562                                 struct lprocfs_vars *list,
 563                                 void *data);
 564
 565void ldebugfs_remove(struct dentry **entryp);
 566
 567int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list,
 568                      struct attribute_group *attrs);
 569int lprocfs_obd_cleanup(struct obd_device *obd);
 570
 571int ldebugfs_seq_create(struct dentry *parent,
 572                        const char *name,
 573                        umode_t mode,
 574                        const struct file_operations *seq_fops,
 575                        void *data);
 576int ldebugfs_obd_seq_create(struct obd_device *dev,
 577                            const char *name,
 578                            umode_t mode,
 579                            const struct file_operations *seq_fops,
 580                            void *data);
 581
 582/* Generic callbacks */
 583
 584int lprocfs_rd_uint(struct seq_file *m, void *data);
 585int lprocfs_wr_uint(struct file *file, const char __user *buffer,
 586                    unsigned long count, void *data);
 587int lprocfs_rd_server_uuid(struct seq_file *m, void *data);
 588int lprocfs_rd_conn_uuid(struct seq_file *m, void *data);
 589int lprocfs_rd_import(struct seq_file *m, void *data);
 590int lprocfs_rd_state(struct seq_file *m, void *data);
 591int lprocfs_rd_connect_flags(struct seq_file *m, void *data);
 592
 593struct adaptive_timeout;
 594int lprocfs_at_hist_helper(struct seq_file *m, struct adaptive_timeout *at);
 595int lprocfs_rd_timeouts(struct seq_file *m, void *data);
 596int lprocfs_wr_ping(struct file *file, const char __user *buffer,
 597                    size_t count, loff_t *off);
 598int lprocfs_wr_import(struct file *file, const char __user *buffer,
 599                      size_t count, loff_t *off);
 600int lprocfs_rd_pinger_recov(struct seq_file *m, void *n);
 601int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer,
 602                            size_t count, loff_t *off);
 603
 604/* Statfs helpers */
 605
 606int lprocfs_write_helper(const char __user *buffer, unsigned long count,
 607                         int *val);
 608int lprocfs_write_u64_helper(const char __user *buffer,
 609                             unsigned long count, __u64 *val);
 610int lprocfs_write_frac_u64_helper(const char __user *buffer,
 611                                  unsigned long count,
 612                                  __u64 *val, int mult);
 613char *lprocfs_find_named_value(const char *buffer, const char *name,
 614                               size_t *count);
 615void lprocfs_oh_tally(struct obd_histogram *oh, unsigned int value);
 616void lprocfs_oh_tally_log2(struct obd_histogram *oh, unsigned int value);
 617void lprocfs_oh_clear(struct obd_histogram *oh);
 618unsigned long lprocfs_oh_sum(struct obd_histogram *oh);
 619
 620void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx,
 621                           struct lprocfs_counter *cnt);
 622
 623int lprocfs_single_release(struct inode *, struct file *);
 624int lprocfs_seq_release(struct inode *, struct file *);
 625
 626/* write the name##_seq_show function, call LPROC_SEQ_FOPS_RO for read-only
 627 * proc entries; otherwise, you will define name##_seq_write function also for
 628 * a read-write proc entry, and then call LPROC_SEQ_SEQ instead. Finally,
 629 * call ldebugfs_obd_seq_create(obd, filename, 0444, &name#_fops, data);
 630 */
 631#define __LPROC_SEQ_FOPS(name, custom_seq_write)                        \
 632static int name##_single_open(struct inode *inode, struct file *file)   \
 633{                                                                       \
 634        return single_open(file, name##_seq_show, inode->i_private);    \
 635}                                                                       \
 636static struct file_operations name##_fops = {                           \
 637        .owner   = THIS_MODULE,                                     \
 638        .open    = name##_single_open,                               \
 639        .read    = seq_read,                                           \
 640        .write   = custom_seq_write,                                   \
 641        .llseek  = seq_lseek,                                         \
 642        .release = lprocfs_single_release,                               \
 643}
 644
 645#define LPROC_SEQ_FOPS_RO(name)  __LPROC_SEQ_FOPS(name, NULL)
 646#define LPROC_SEQ_FOPS(name)        __LPROC_SEQ_FOPS(name, name##_seq_write)
 647
 648#define LPROC_SEQ_FOPS_RO_TYPE(name, type)                              \
 649        static int name##_##type##_seq_show(struct seq_file *m, void *v)\
 650        {                                                               \
 651                return lprocfs_rd_##type(m, m->private);                \
 652        }                                                               \
 653        LPROC_SEQ_FOPS_RO(name##_##type)
 654
 655#define LPROC_SEQ_FOPS_RW_TYPE(name, type)                              \
 656        static int name##_##type##_seq_show(struct seq_file *m, void *v)\
 657        {                                                               \
 658                return lprocfs_rd_##type(m, m->private);                \
 659        }                                                               \
 660        static ssize_t name##_##type##_seq_write(struct file *file,     \
 661                        const char __user *buffer, size_t count,        \
 662                                                loff_t *off)            \
 663        {                                                               \
 664                struct seq_file *seq = file->private_data;              \
 665                return lprocfs_wr_##type(file, buffer,                  \
 666                                         count, seq->private);          \
 667        }                                                               \
 668        LPROC_SEQ_FOPS(name##_##type)
 669
 670#define LPROC_SEQ_FOPS_WR_ONLY(name, type)                              \
 671        static ssize_t name##_##type##_write(struct file *file,         \
 672                        const char __user *buffer, size_t count,        \
 673                                                loff_t *off)            \
 674        {                                                               \
 675                return lprocfs_wr_##type(file, buffer, count, off);     \
 676        }                                                               \
 677        static int name##_##type##_open(struct inode *inode, struct file *file) \
 678        {                                                               \
 679                return single_open(file, NULL, inode->i_private);       \
 680        }                                                               \
 681        static struct file_operations name##_##type##_fops = {  \
 682                .open   = name##_##type##_open,                         \
 683                .write  = name##_##type##_write,                        \
 684                .release = lprocfs_single_release,                      \
 685        }
 686
 687struct lustre_attr {
 688        struct attribute attr;
 689        ssize_t (*show)(struct kobject *kobj, struct attribute *attr,
 690                        char *buf);
 691        ssize_t (*store)(struct kobject *kobj, struct attribute *attr,
 692                         const char *buf, size_t len);
 693};
 694
 695#define LUSTRE_ATTR(name, mode, show, store) \
 696static struct lustre_attr lustre_attr_##name = __ATTR(name, mode, show, store)
 697
 698#define LUSTRE_RO_ATTR(name) LUSTRE_ATTR(name, 0444, name##_show, NULL)
 699#define LUSTRE_RW_ATTR(name) LUSTRE_ATTR(name, 0644, name##_show, name##_store)
 700
 701extern const struct sysfs_ops lustre_sysfs_ops;
 702
 703struct root_squash_info;
 704int lprocfs_wr_root_squash(const char *buffer, unsigned long count,
 705                           struct root_squash_info *squash, char *name);
 706int lprocfs_wr_nosquash_nids(const char *buffer, unsigned long count,
 707                             struct root_squash_info *squash, char *name);
 708
 709/* all quota proc functions */
 710int lprocfs_quota_rd_bunit(char *page, char **start,
 711                           loff_t off, int count,
 712                           int *eof, void *data);
 713int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
 714                           unsigned long count, void *data);
 715int lprocfs_quota_rd_btune(char *page, char **start,
 716                           loff_t off, int count,
 717                           int *eof, void *data);
 718int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
 719                           unsigned long count, void *data);
 720int lprocfs_quota_rd_iunit(char *page, char **start,
 721                           loff_t off, int count,
 722                           int *eof, void *data);
 723int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
 724                           unsigned long count, void *data);
 725int lprocfs_quota_rd_itune(char *page, char **start,
 726                           loff_t off, int count,
 727                           int *eof, void *data);
 728int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
 729                           unsigned long count, void *data);
 730int lprocfs_quota_rd_type(char *page, char **start, loff_t off, int count,
 731                          int *eof, void *data);
 732int lprocfs_quota_wr_type(struct file *file, const char *buffer,
 733                          unsigned long count, void *data);
 734int lprocfs_quota_rd_switch_seconds(char *page, char **start, loff_t off,
 735                                    int count, int *eof, void *data);
 736int lprocfs_quota_wr_switch_seconds(struct file *file,
 737                                    const char *buffer,
 738                                    unsigned long count, void *data);
 739int lprocfs_quota_rd_sync_blk(char *page, char **start, loff_t off,
 740                              int count, int *eof, void *data);
 741int lprocfs_quota_wr_sync_blk(struct file *file, const char *buffer,
 742                              unsigned long count, void *data);
 743int lprocfs_quota_rd_switch_qs(char *page, char **start, loff_t off,
 744                               int count, int *eof, void *data);
 745int lprocfs_quota_wr_switch_qs(struct file *file,
 746                               const char *buffer, unsigned long count,
 747                               void *data);
 748int lprocfs_quota_rd_boundary_factor(char *page, char **start, loff_t off,
 749                                     int count, int *eof, void *data);
 750int lprocfs_quota_wr_boundary_factor(struct file *file,
 751                                     const char *buffer, unsigned long count,
 752                                     void *data);
 753int lprocfs_quota_rd_least_bunit(char *page, char **start, loff_t off,
 754                                 int count, int *eof, void *data);
 755int lprocfs_quota_wr_least_bunit(struct file *file,
 756                                 const char *buffer, unsigned long count,
 757                                 void *data);
 758int lprocfs_quota_rd_least_iunit(char *page, char **start, loff_t off,
 759                                 int count, int *eof, void *data);
 760int lprocfs_quota_wr_least_iunit(struct file *file,
 761                                 const char *buffer, unsigned long count,
 762                                 void *data);
 763int lprocfs_quota_rd_qs_factor(char *page, char **start, loff_t off,
 764                               int count, int *eof, void *data);
 765int lprocfs_quota_wr_qs_factor(struct file *file,
 766                               const char *buffer, unsigned long count,
 767                               void *data);
 768#endif /* LPROCFS_SNMP_H */
 769