Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
0004  * All Rights Reserved.
0005  */
0006 #include "xfs.h"
0007 
0008 struct xstats xfsstats;
0009 
0010 static int counter_val(struct xfsstats __percpu *stats, int idx)
0011 {
0012     int val = 0, cpu;
0013 
0014     for_each_possible_cpu(cpu)
0015         val += *(((__u32 *)per_cpu_ptr(stats, cpu) + idx));
0016     return val;
0017 }
0018 
0019 int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
0020 {
0021     int     i, j;
0022     int     len = 0;
0023     uint64_t    xs_xstrat_bytes = 0;
0024     uint64_t    xs_write_bytes = 0;
0025     uint64_t    xs_read_bytes = 0;
0026     uint64_t    defer_relog = 0;
0027 
0028     static const struct xstats_entry {
0029         char    *desc;
0030         int endpoint;
0031     } xstats[] = {
0032         { "extent_alloc",   xfsstats_offset(xs_abt_lookup)  },
0033         { "abt",        xfsstats_offset(xs_blk_mapr)    },
0034         { "blk_map",        xfsstats_offset(xs_bmbt_lookup) },
0035         { "bmbt",       xfsstats_offset(xs_dir_lookup)  },
0036         { "dir",        xfsstats_offset(xs_trans_sync)  },
0037         { "trans",      xfsstats_offset(xs_ig_attempts) },
0038         { "ig",         xfsstats_offset(xs_log_writes)  },
0039         { "log",        xfsstats_offset(xs_try_logspace)},
0040         { "push_ail",       xfsstats_offset(xs_xstrat_quick)},
0041         { "xstrat",     xfsstats_offset(xs_write_calls) },
0042         { "rw",         xfsstats_offset(xs_attr_get)    },
0043         { "attr",       xfsstats_offset(xs_iflush_count)},
0044         { "icluster",       xfsstats_offset(vn_active)  },
0045         { "vnodes",     xfsstats_offset(xb_get)     },
0046         { "buf",        xfsstats_offset(xs_abtb_2)  },
0047         { "abtb2",      xfsstats_offset(xs_abtc_2)  },
0048         { "abtc2",      xfsstats_offset(xs_bmbt_2)  },
0049         { "bmbt2",      xfsstats_offset(xs_ibt_2)   },
0050         { "ibt2",       xfsstats_offset(xs_fibt_2)  },
0051         { "fibt2",      xfsstats_offset(xs_rmap_2)  },
0052         { "rmapbt",     xfsstats_offset(xs_refcbt_2)    },
0053         { "refcntbt",       xfsstats_offset(xs_qm_dqreclaims)},
0054         /* we print both series of quota information together */
0055         { "qm",         xfsstats_offset(xs_xstrat_bytes)},
0056     };
0057 
0058     /* Loop over all stats groups */
0059 
0060     for (i = j = 0; i < ARRAY_SIZE(xstats); i++) {
0061         len += scnprintf(buf + len, PATH_MAX - len, "%s",
0062                 xstats[i].desc);
0063         /* inner loop does each group */
0064         for (; j < xstats[i].endpoint; j++)
0065             len += scnprintf(buf + len, PATH_MAX - len, " %u",
0066                     counter_val(stats, j));
0067         len += scnprintf(buf + len, PATH_MAX - len, "\n");
0068     }
0069     /* extra precision counters */
0070     for_each_possible_cpu(i) {
0071         xs_xstrat_bytes += per_cpu_ptr(stats, i)->s.xs_xstrat_bytes;
0072         xs_write_bytes += per_cpu_ptr(stats, i)->s.xs_write_bytes;
0073         xs_read_bytes += per_cpu_ptr(stats, i)->s.xs_read_bytes;
0074         defer_relog += per_cpu_ptr(stats, i)->s.defer_relog;
0075     }
0076 
0077     len += scnprintf(buf + len, PATH_MAX-len, "xpc %Lu %Lu %Lu\n",
0078             xs_xstrat_bytes, xs_write_bytes, xs_read_bytes);
0079     len += scnprintf(buf + len, PATH_MAX-len, "defer_relog %llu\n",
0080             defer_relog);
0081     len += scnprintf(buf + len, PATH_MAX-len, "debug %u\n",
0082 #if defined(DEBUG)
0083         1);
0084 #else
0085         0);
0086 #endif
0087 
0088     return len;
0089 }
0090 
0091 void xfs_stats_clearall(struct xfsstats __percpu *stats)
0092 {
0093     int     c;
0094     uint32_t    vn_active;
0095 
0096     xfs_notice(NULL, "Clearing xfsstats");
0097     for_each_possible_cpu(c) {
0098         preempt_disable();
0099         /* save vn_active, it's a universal truth! */
0100         vn_active = per_cpu_ptr(stats, c)->s.vn_active;
0101         memset(per_cpu_ptr(stats, c), 0, sizeof(*stats));
0102         per_cpu_ptr(stats, c)->s.vn_active = vn_active;
0103         preempt_enable();
0104     }
0105 }
0106 
0107 #ifdef CONFIG_PROC_FS
0108 /* legacy quota interfaces */
0109 #ifdef CONFIG_XFS_QUOTA
0110 
0111 #define XFSSTAT_START_XQMSTAT xfsstats_offset(xs_qm_dqreclaims)
0112 #define XFSSTAT_END_XQMSTAT xfsstats_offset(xs_qm_dquot)
0113 
0114 static int xqm_proc_show(struct seq_file *m, void *v)
0115 {
0116     /* maximum; incore; ratio free to inuse; freelist */
0117     seq_printf(m, "%d\t%d\t%d\t%u\n",
0118            0, counter_val(xfsstats.xs_stats, XFSSTAT_END_XQMSTAT),
0119            0, counter_val(xfsstats.xs_stats, XFSSTAT_END_XQMSTAT + 1));
0120     return 0;
0121 }
0122 
0123 /* legacy quota stats interface no 2 */
0124 static int xqmstat_proc_show(struct seq_file *m, void *v)
0125 {
0126     int j;
0127 
0128     seq_printf(m, "qm");
0129     for (j = XFSSTAT_START_XQMSTAT; j < XFSSTAT_END_XQMSTAT; j++)
0130         seq_printf(m, " %u", counter_val(xfsstats.xs_stats, j));
0131     seq_putc(m, '\n');
0132     return 0;
0133 }
0134 #endif /* CONFIG_XFS_QUOTA */
0135 
0136 int
0137 xfs_init_procfs(void)
0138 {
0139     if (!proc_mkdir("fs/xfs", NULL))
0140         return -ENOMEM;
0141 
0142     if (!proc_symlink("fs/xfs/stat", NULL,
0143               "/sys/fs/xfs/stats/stats"))
0144         goto out;
0145 
0146 #ifdef CONFIG_XFS_QUOTA
0147     if (!proc_create_single("fs/xfs/xqmstat", 0, NULL, xqmstat_proc_show))
0148         goto out;
0149     if (!proc_create_single("fs/xfs/xqm", 0, NULL, xqm_proc_show))
0150         goto out;
0151 #endif
0152     return 0;
0153 
0154 out:
0155     remove_proc_subtree("fs/xfs", NULL);
0156     return -ENOMEM;
0157 }
0158 
0159 void
0160 xfs_cleanup_procfs(void)
0161 {
0162     remove_proc_subtree("fs/xfs", NULL);
0163 }
0164 #endif /* CONFIG_PROC_FS */