diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-03-13 04:52:33 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-03-14 12:09:06 -0400 |
commit | 48776fd22344ad80adcbac0abc9c0da60c6481d2 (patch) | |
tree | 8ab09fce19aab58e0e451d16c98ff7d1e84dcc53 /fs/xfs | |
parent | 8f639ddea0c4978ae9b4e46ea041c9e5afe0ee8d (diff) |
xfs: use common code for quota statistics
Switch the quota code over to use the generic XFS statistics infrastructure.
While the legacy /proc/fs/xfs/xqm and /proc/fs/xfs/xqmstats interfaces are
preserved for now the statistics that still have a meaning with the current
code are now also available from /proc/fs/xfs/stats.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/Makefile | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_dquot.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_qm.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_qm.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_qm_bhv.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_qm_stats.c | 105 | ||||
-rw-r--r-- | fs/xfs/xfs_qm_stats.h | 53 | ||||
-rw-r--r-- | fs/xfs/xfs_stats.c | 99 | ||||
-rw-r--r-- | fs/xfs/xfs_stats.h | 10 |
9 files changed, 110 insertions, 187 deletions
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 427a4e82a588..0a9977983f92 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile | |||
@@ -96,9 +96,6 @@ xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \ | |||
96 | xfs_qm_bhv.o \ | 96 | xfs_qm_bhv.o \ |
97 | xfs_qm.o \ | 97 | xfs_qm.o \ |
98 | xfs_quotaops.o | 98 | xfs_quotaops.o |
99 | ifeq ($(CONFIG_XFS_QUOTA),y) | ||
100 | xfs-$(CONFIG_PROC_FS) += xfs_qm_stats.o | ||
101 | endif | ||
102 | xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o | 99 | xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o |
103 | xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o | 100 | xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o |
104 | xfs-$(CONFIG_PROC_FS) += xfs_stats.o | 101 | xfs-$(CONFIG_PROC_FS) += xfs_stats.o |
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 71e615fef174..98d7e25947fa 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
@@ -74,7 +74,7 @@ xfs_qm_dqdestroy( | |||
74 | mutex_destroy(&dqp->q_qlock); | 74 | mutex_destroy(&dqp->q_qlock); |
75 | kmem_zone_free(xfs_Gqm->qm_dqzone, dqp); | 75 | kmem_zone_free(xfs_Gqm->qm_dqzone, dqp); |
76 | 76 | ||
77 | atomic_dec(&xfs_Gqm->qm_totaldquots); | 77 | XFS_STATS_DEC(xs_qm_dquot); |
78 | } | 78 | } |
79 | 79 | ||
80 | /* | 80 | /* |
@@ -516,7 +516,7 @@ xfs_qm_dqread( | |||
516 | if (!(type & XFS_DQ_USER)) | 516 | if (!(type & XFS_DQ_USER)) |
517 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class); | 517 | lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class); |
518 | 518 | ||
519 | atomic_inc(&xfs_Gqm->qm_totaldquots); | 519 | XFS_STATS_INC(xs_qm_dquot); |
520 | 520 | ||
521 | trace_xfs_dqread(dqp); | 521 | trace_xfs_dqread(dqp); |
522 | 522 | ||
@@ -712,12 +712,12 @@ restart: | |||
712 | */ | 712 | */ |
713 | switch (xfs_qm_dqlookup(mp, id, h, O_dqpp)) { | 713 | switch (xfs_qm_dqlookup(mp, id, h, O_dqpp)) { |
714 | case -1: | 714 | case -1: |
715 | XQM_STATS_INC(xqmstats.xs_qm_dquot_dups); | 715 | XFS_STATS_INC(xs_qm_dquot_dups); |
716 | mutex_unlock(&h->qh_lock); | 716 | mutex_unlock(&h->qh_lock); |
717 | delay(1); | 717 | delay(1); |
718 | goto restart; | 718 | goto restart; |
719 | case 0: | 719 | case 0: |
720 | XQM_STATS_INC(xqmstats.xs_qm_dqcachehits); | 720 | XFS_STATS_INC(xs_qm_dqcachehits); |
721 | /* | 721 | /* |
722 | * The dquot was found, moved to the front of the chain, | 722 | * The dquot was found, moved to the front of the chain, |
723 | * taken off the freelist if it was on it, and locked | 723 | * taken off the freelist if it was on it, and locked |
@@ -729,7 +729,7 @@ restart: | |||
729 | trace_xfs_dqget_hit(*O_dqpp); | 729 | trace_xfs_dqget_hit(*O_dqpp); |
730 | return 0; /* success */ | 730 | return 0; /* success */ |
731 | default: | 731 | default: |
732 | XQM_STATS_INC(xqmstats.xs_qm_dqcachemisses); | 732 | XFS_STATS_INC(xs_qm_dqcachemisses); |
733 | break; | 733 | break; |
734 | } | 734 | } |
735 | 735 | ||
@@ -804,7 +804,7 @@ restart: | |||
804 | xfs_qm_dqput(tmpdqp); | 804 | xfs_qm_dqput(tmpdqp); |
805 | mutex_unlock(&h->qh_lock); | 805 | mutex_unlock(&h->qh_lock); |
806 | xfs_qm_dqdestroy(dqp); | 806 | xfs_qm_dqdestroy(dqp); |
807 | XQM_STATS_INC(xqmstats.xs_qm_dquot_dups); | 807 | XFS_STATS_INC(xs_qm_dquot_dups); |
808 | goto restart; | 808 | goto restart; |
809 | default: | 809 | default: |
810 | break; | 810 | break; |
@@ -873,6 +873,7 @@ recurse: | |||
873 | if (list_empty(&dqp->q_freelist)) { | 873 | if (list_empty(&dqp->q_freelist)) { |
874 | list_add_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist); | 874 | list_add_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist); |
875 | xfs_Gqm->qm_dqfrlist_cnt++; | 875 | xfs_Gqm->qm_dqfrlist_cnt++; |
876 | XFS_STATS_INC(xs_qm_dquot_unused); | ||
876 | } | 877 | } |
877 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); | 878 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); |
878 | 879 | ||
@@ -1178,6 +1179,7 @@ xfs_qm_dqpurge( | |||
1178 | ASSERT(!list_empty(&dqp->q_freelist)); | 1179 | ASSERT(!list_empty(&dqp->q_freelist)); |
1179 | list_del_init(&dqp->q_freelist); | 1180 | list_del_init(&dqp->q_freelist); |
1180 | xfs_Gqm->qm_dqfrlist_cnt--; | 1181 | xfs_Gqm->qm_dqfrlist_cnt--; |
1182 | XFS_STATS_DEC(xs_qm_dquot_unused); | ||
1181 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); | 1183 | mutex_unlock(&xfs_Gqm->qm_dqfrlist_lock); |
1182 | 1184 | ||
1183 | xfs_qm_dqdestroy(dqp); | 1185 | xfs_qm_dqdestroy(dqp); |
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index c872feaf3697..0dde1f48c280 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -134,7 +134,6 @@ xfs_Gqm_init(void) | |||
134 | } else | 134 | } else |
135 | xqm->qm_dqtrxzone = qm_dqtrxzone; | 135 | xqm->qm_dqtrxzone = qm_dqtrxzone; |
136 | 136 | ||
137 | atomic_set(&xqm->qm_totaldquots, 0); | ||
138 | xqm->qm_nrefs = 0; | 137 | xqm->qm_nrefs = 0; |
139 | return xqm; | 138 | return xqm; |
140 | 139 | ||
@@ -1637,10 +1636,11 @@ xfs_qm_dqreclaim_one( | |||
1637 | xfs_dqunlock(dqp); | 1636 | xfs_dqunlock(dqp); |
1638 | 1637 | ||
1639 | trace_xfs_dqreclaim_want(dqp); | 1638 | trace_xfs_dqreclaim_want(dqp); |
1640 | XQM_STATS_INC(xqmstats.xs_qm_dqwants); | 1639 | XFS_STATS_INC(xs_qm_dqwants); |
1641 | 1640 | ||
1642 | list_del_init(&dqp->q_freelist); | 1641 | list_del_init(&dqp->q_freelist); |
1643 | xfs_Gqm->qm_dqfrlist_cnt--; | 1642 | xfs_Gqm->qm_dqfrlist_cnt--; |
1643 | XFS_STATS_DEC(xs_qm_dquot_unused); | ||
1644 | return; | 1644 | return; |
1645 | } | 1645 | } |
1646 | 1646 | ||
@@ -1690,9 +1690,10 @@ xfs_qm_dqreclaim_one( | |||
1690 | ASSERT(dqp->q_nrefs == 0); | 1690 | ASSERT(dqp->q_nrefs == 0); |
1691 | list_move_tail(&dqp->q_freelist, dispose_list); | 1691 | list_move_tail(&dqp->q_freelist, dispose_list); |
1692 | xfs_Gqm->qm_dqfrlist_cnt--; | 1692 | xfs_Gqm->qm_dqfrlist_cnt--; |
1693 | XFS_STATS_DEC(xs_qm_dquot_unused); | ||
1693 | 1694 | ||
1694 | trace_xfs_dqreclaim_done(dqp); | 1695 | trace_xfs_dqreclaim_done(dqp); |
1695 | XQM_STATS_INC(xqmstats.xs_qm_dqreclaims); | 1696 | XFS_STATS_INC(xs_qm_dqreclaims); |
1696 | return; | 1697 | return; |
1697 | 1698 | ||
1698 | out_busy: | 1699 | out_busy: |
@@ -1704,7 +1705,7 @@ out_busy: | |||
1704 | list_move_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist); | 1705 | list_move_tail(&dqp->q_freelist, &xfs_Gqm->qm_dqfrlist); |
1705 | 1706 | ||
1706 | trace_xfs_dqreclaim_busy(dqp); | 1707 | trace_xfs_dqreclaim_busy(dqp); |
1707 | XQM_STATS_INC(xqmstats.xs_qm_dqreclaim_misses); | 1708 | XFS_STATS_INC(xs_qm_dqreclaim_misses); |
1708 | } | 1709 | } |
1709 | 1710 | ||
1710 | STATIC int | 1711 | STATIC int |
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 9a9b997e1a0a..89f213f7252a 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "xfs_dquot_item.h" | 21 | #include "xfs_dquot_item.h" |
22 | #include "xfs_dquot.h" | 22 | #include "xfs_dquot.h" |
23 | #include "xfs_quota_priv.h" | 23 | #include "xfs_quota_priv.h" |
24 | #include "xfs_qm_stats.h" | ||
25 | 24 | ||
26 | struct xfs_qm; | 25 | struct xfs_qm; |
27 | struct xfs_inode; | 26 | struct xfs_inode; |
@@ -60,7 +59,6 @@ typedef struct xfs_qm { | |||
60 | struct list_head qm_dqfrlist; /* freelist of dquots */ | 59 | struct list_head qm_dqfrlist; /* freelist of dquots */ |
61 | struct mutex qm_dqfrlist_lock; | 60 | struct mutex qm_dqfrlist_lock; |
62 | int qm_dqfrlist_cnt; | 61 | int qm_dqfrlist_cnt; |
63 | atomic_t qm_totaldquots; /* total incore dquots */ | ||
64 | uint qm_nrefs; /* file systems with quota on */ | 62 | uint qm_nrefs; /* file systems with quota on */ |
65 | kmem_zone_t *qm_dqzone; /* dquot mem-alloc zone */ | 63 | kmem_zone_t *qm_dqzone; /* dquot mem-alloc zone */ |
66 | kmem_zone_t *qm_dqtrxzone; /* t_dqinfo of transactions */ | 64 | kmem_zone_t *qm_dqtrxzone; /* t_dqinfo of transactions */ |
diff --git a/fs/xfs/xfs_qm_bhv.c b/fs/xfs/xfs_qm_bhv.c index e4e37877f867..809f86857c6d 100644 --- a/fs/xfs/xfs_qm_bhv.c +++ b/fs/xfs/xfs_qm_bhv.c | |||
@@ -162,13 +162,11 @@ xfs_qm_init(void) | |||
162 | { | 162 | { |
163 | printk(KERN_INFO "SGI XFS Quota Management subsystem\n"); | 163 | printk(KERN_INFO "SGI XFS Quota Management subsystem\n"); |
164 | mutex_init(&xfs_Gqm_lock); | 164 | mutex_init(&xfs_Gqm_lock); |
165 | xfs_qm_init_procfs(); | ||
166 | } | 165 | } |
167 | 166 | ||
168 | void __exit | 167 | void __exit |
169 | xfs_qm_exit(void) | 168 | xfs_qm_exit(void) |
170 | { | 169 | { |
171 | xfs_qm_cleanup_procfs(); | ||
172 | if (qm_dqzone) | 170 | if (qm_dqzone) |
173 | kmem_zone_destroy(qm_dqzone); | 171 | kmem_zone_destroy(qm_dqzone); |
174 | if (qm_dqtrxzone) | 172 | if (qm_dqtrxzone) |
diff --git a/fs/xfs/xfs_qm_stats.c b/fs/xfs/xfs_qm_stats.c deleted file mode 100644 index 5729ba570877..000000000000 --- a/fs/xfs/xfs_qm_stats.c +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000-2003 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #include "xfs.h" | ||
19 | #include "xfs_fs.h" | ||
20 | #include "xfs_bit.h" | ||
21 | #include "xfs_log.h" | ||
22 | #include "xfs_inum.h" | ||
23 | #include "xfs_trans.h" | ||
24 | #include "xfs_sb.h" | ||
25 | #include "xfs_ag.h" | ||
26 | #include "xfs_alloc.h" | ||
27 | #include "xfs_quota.h" | ||
28 | #include "xfs_mount.h" | ||
29 | #include "xfs_bmap_btree.h" | ||
30 | #include "xfs_inode.h" | ||
31 | #include "xfs_itable.h" | ||
32 | #include "xfs_bmap.h" | ||
33 | #include "xfs_rtalloc.h" | ||
34 | #include "xfs_error.h" | ||
35 | #include "xfs_attr.h" | ||
36 | #include "xfs_buf_item.h" | ||
37 | #include "xfs_qm.h" | ||
38 | |||
39 | struct xqmstats xqmstats; | ||
40 | |||
41 | static int xqm_proc_show(struct seq_file *m, void *v) | ||
42 | { | ||
43 | /* maximum; incore; ratio free to inuse; freelist */ | ||
44 | seq_printf(m, "%d\t%d\t%d\t%u\n", | ||
45 | 0, | ||
46 | xfs_Gqm? atomic_read(&xfs_Gqm->qm_totaldquots) : 0, | ||
47 | 0, | ||
48 | xfs_Gqm? xfs_Gqm->qm_dqfrlist_cnt : 0); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | static int xqm_proc_open(struct inode *inode, struct file *file) | ||
53 | { | ||
54 | return single_open(file, xqm_proc_show, NULL); | ||
55 | } | ||
56 | |||
57 | static const struct file_operations xqm_proc_fops = { | ||
58 | .owner = THIS_MODULE, | ||
59 | .open = xqm_proc_open, | ||
60 | .read = seq_read, | ||
61 | .llseek = seq_lseek, | ||
62 | .release = single_release, | ||
63 | }; | ||
64 | |||
65 | static int xqmstat_proc_show(struct seq_file *m, void *v) | ||
66 | { | ||
67 | /* quota performance statistics */ | ||
68 | seq_printf(m, "qm %u %u %u %u %u %u %u %u\n", | ||
69 | xqmstats.xs_qm_dqreclaims, | ||
70 | xqmstats.xs_qm_dqreclaim_misses, | ||
71 | xqmstats.xs_qm_dquot_dups, | ||
72 | xqmstats.xs_qm_dqcachemisses, | ||
73 | xqmstats.xs_qm_dqcachehits, | ||
74 | xqmstats.xs_qm_dqwants, | ||
75 | xqmstats.xs_qm_dqshake_reclaims, | ||
76 | xqmstats.xs_qm_dqinact_reclaims); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int xqmstat_proc_open(struct inode *inode, struct file *file) | ||
81 | { | ||
82 | return single_open(file, xqmstat_proc_show, NULL); | ||
83 | } | ||
84 | |||
85 | static const struct file_operations xqmstat_proc_fops = { | ||
86 | .owner = THIS_MODULE, | ||
87 | .open = xqmstat_proc_open, | ||
88 | .read = seq_read, | ||
89 | .llseek = seq_lseek, | ||
90 | .release = single_release, | ||
91 | }; | ||
92 | |||
93 | void | ||
94 | xfs_qm_init_procfs(void) | ||
95 | { | ||
96 | proc_create("fs/xfs/xqmstat", 0, NULL, &xqmstat_proc_fops); | ||
97 | proc_create("fs/xfs/xqm", 0, NULL, &xqm_proc_fops); | ||
98 | } | ||
99 | |||
100 | void | ||
101 | xfs_qm_cleanup_procfs(void) | ||
102 | { | ||
103 | remove_proc_entry("fs/xfs/xqm", NULL); | ||
104 | remove_proc_entry("fs/xfs/xqmstat", NULL); | ||
105 | } | ||
diff --git a/fs/xfs/xfs_qm_stats.h b/fs/xfs/xfs_qm_stats.h deleted file mode 100644 index 5b964fc0dc09..000000000000 --- a/fs/xfs/xfs_qm_stats.h +++ /dev/null | |||
@@ -1,53 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2002 Silicon Graphics, Inc. | ||
3 | * All Rights Reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or | ||
6 | * modify it under the terms of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it would be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write the Free Software Foundation, | ||
16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
17 | */ | ||
18 | #ifndef __XFS_QM_STATS_H__ | ||
19 | #define __XFS_QM_STATS_H__ | ||
20 | |||
21 | #if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF) | ||
22 | |||
23 | /* | ||
24 | * XQM global statistics | ||
25 | */ | ||
26 | struct xqmstats { | ||
27 | __uint32_t xs_qm_dqreclaims; | ||
28 | __uint32_t xs_qm_dqreclaim_misses; | ||
29 | __uint32_t xs_qm_dquot_dups; | ||
30 | __uint32_t xs_qm_dqcachemisses; | ||
31 | __uint32_t xs_qm_dqcachehits; | ||
32 | __uint32_t xs_qm_dqwants; | ||
33 | __uint32_t xs_qm_dqshake_reclaims; | ||
34 | __uint32_t xs_qm_dqinact_reclaims; | ||
35 | }; | ||
36 | |||
37 | extern struct xqmstats xqmstats; | ||
38 | |||
39 | # define XQM_STATS_INC(count) ( (count)++ ) | ||
40 | |||
41 | extern void xfs_qm_init_procfs(void); | ||
42 | extern void xfs_qm_cleanup_procfs(void); | ||
43 | |||
44 | #else | ||
45 | |||
46 | # define XQM_STATS_INC(count) do { } while (0) | ||
47 | |||
48 | static inline void xfs_qm_init_procfs(void) { }; | ||
49 | static inline void xfs_qm_cleanup_procfs(void) { }; | ||
50 | |||
51 | #endif | ||
52 | |||
53 | #endif /* __XFS_QM_STATS_H__ */ | ||
diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index 76fdc5861932..ce372b7d5644 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c | |||
@@ -20,9 +20,18 @@ | |||
20 | 20 | ||
21 | DEFINE_PER_CPU(struct xfsstats, xfsstats); | 21 | DEFINE_PER_CPU(struct xfsstats, xfsstats); |
22 | 22 | ||
23 | static int counter_val(int idx) | ||
24 | { | ||
25 | int val = 0, cpu; | ||
26 | |||
27 | for_each_possible_cpu(cpu) | ||
28 | val += *(((__u32 *)&per_cpu(xfsstats, cpu) + idx)); | ||
29 | return val; | ||
30 | } | ||
31 | |||
23 | static int xfs_stat_proc_show(struct seq_file *m, void *v) | 32 | static int xfs_stat_proc_show(struct seq_file *m, void *v) |
24 | { | 33 | { |
25 | int c, i, j, val; | 34 | int i, j; |
26 | __uint64_t xs_xstrat_bytes = 0; | 35 | __uint64_t xs_xstrat_bytes = 0; |
27 | __uint64_t xs_write_bytes = 0; | 36 | __uint64_t xs_write_bytes = 0; |
28 | __uint64_t xs_read_bytes = 0; | 37 | __uint64_t xs_read_bytes = 0; |
@@ -50,20 +59,16 @@ static int xfs_stat_proc_show(struct seq_file *m, void *v) | |||
50 | { "abtc2", XFSSTAT_END_ABTC_V2 }, | 59 | { "abtc2", XFSSTAT_END_ABTC_V2 }, |
51 | { "bmbt2", XFSSTAT_END_BMBT_V2 }, | 60 | { "bmbt2", XFSSTAT_END_BMBT_V2 }, |
52 | { "ibt2", XFSSTAT_END_IBT_V2 }, | 61 | { "ibt2", XFSSTAT_END_IBT_V2 }, |
62 | /* we print both series of quota information together */ | ||
63 | { "qm", XFSSTAT_END_QM }, | ||
53 | }; | 64 | }; |
54 | 65 | ||
55 | /* Loop over all stats groups */ | 66 | /* Loop over all stats groups */ |
56 | for (i=j = 0; i < ARRAY_SIZE(xstats); i++) { | 67 | for (i = j = 0; i < ARRAY_SIZE(xstats); i++) { |
57 | seq_printf(m, "%s", xstats[i].desc); | 68 | seq_printf(m, "%s", xstats[i].desc); |
58 | /* inner loop does each group */ | 69 | /* inner loop does each group */ |
59 | while (j < xstats[i].endpoint) { | 70 | for (; j < xstats[i].endpoint; j++) |
60 | val = 0; | 71 | seq_printf(m, " %u", counter_val(j)); |
61 | /* sum over all cpus */ | ||
62 | for_each_possible_cpu(c) | ||
63 | val += *(((__u32*)&per_cpu(xfsstats, c) + j)); | ||
64 | seq_printf(m, " %u", val); | ||
65 | j++; | ||
66 | } | ||
67 | seq_putc(m, '\n'); | 72 | seq_putc(m, '\n'); |
68 | } | 73 | } |
69 | /* extra precision counters */ | 74 | /* extra precision counters */ |
@@ -97,6 +102,58 @@ static const struct file_operations xfs_stat_proc_fops = { | |||
97 | .release = single_release, | 102 | .release = single_release, |
98 | }; | 103 | }; |
99 | 104 | ||
105 | /* legacy quota interfaces */ | ||
106 | #ifdef CONFIG_XFS_QUOTA | ||
107 | static int xqm_proc_show(struct seq_file *m, void *v) | ||
108 | { | ||
109 | /* maximum; incore; ratio free to inuse; freelist */ | ||
110 | seq_printf(m, "%d\t%d\t%d\t%u\n", | ||
111 | 0, | ||
112 | counter_val(XFSSTAT_END_XQMSTAT), | ||
113 | 0, | ||
114 | counter_val(XFSSTAT_END_XQMSTAT + 1)); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int xqm_proc_open(struct inode *inode, struct file *file) | ||
119 | { | ||
120 | return single_open(file, xqm_proc_show, NULL); | ||
121 | } | ||
122 | |||
123 | static const struct file_operations xqm_proc_fops = { | ||
124 | .owner = THIS_MODULE, | ||
125 | .open = xqm_proc_open, | ||
126 | .read = seq_read, | ||
127 | .llseek = seq_lseek, | ||
128 | .release = single_release, | ||
129 | }; | ||
130 | |||
131 | /* legacy quota stats interface no 2 */ | ||
132 | static int xqmstat_proc_show(struct seq_file *m, void *v) | ||
133 | { | ||
134 | int j; | ||
135 | |||
136 | seq_printf(m, "qm"); | ||
137 | for (j = XFSSTAT_END_IBT_V2; j < XFSSTAT_END_XQMSTAT; j++) | ||
138 | seq_printf(m, " %u", counter_val(j)); | ||
139 | seq_putc(m, '\n'); | ||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static int xqmstat_proc_open(struct inode *inode, struct file *file) | ||
144 | { | ||
145 | return single_open(file, xqmstat_proc_show, NULL); | ||
146 | } | ||
147 | |||
148 | static const struct file_operations xqmstat_proc_fops = { | ||
149 | .owner = THIS_MODULE, | ||
150 | .open = xqmstat_proc_open, | ||
151 | .read = seq_read, | ||
152 | .llseek = seq_lseek, | ||
153 | .release = single_release, | ||
154 | }; | ||
155 | #endif /* CONFIG_XFS_QUOTA */ | ||
156 | |||
100 | int | 157 | int |
101 | xfs_init_procfs(void) | 158 | xfs_init_procfs(void) |
102 | { | 159 | { |
@@ -105,10 +162,24 @@ xfs_init_procfs(void) | |||
105 | 162 | ||
106 | if (!proc_create("fs/xfs/stat", 0, NULL, | 163 | if (!proc_create("fs/xfs/stat", 0, NULL, |
107 | &xfs_stat_proc_fops)) | 164 | &xfs_stat_proc_fops)) |
108 | goto out_remove_entry; | 165 | goto out_remove_xfs_dir; |
166 | #ifdef CONFIG_XFS_QUOTA | ||
167 | if (!proc_create("fs/xfs/xqmstat", 0, NULL, | ||
168 | &xqmstat_proc_fops)) | ||
169 | goto out_remove_stat_file; | ||
170 | if (!proc_create("fs/xfs/xqm", 0, NULL, | ||
171 | &xqm_proc_fops)) | ||
172 | goto out_remove_xqmstat_file; | ||
173 | #endif | ||
109 | return 0; | 174 | return 0; |
110 | 175 | ||
111 | out_remove_entry: | 176 | #ifdef CONFIG_XFS_QUOTA |
177 | out_remove_xqmstat_file: | ||
178 | remove_proc_entry("fs/xfs/xqmstat", NULL); | ||
179 | out_remove_stat_file: | ||
180 | remove_proc_entry("fs/xfs/stat", NULL); | ||
181 | #endif | ||
182 | out_remove_xfs_dir: | ||
112 | remove_proc_entry("fs/xfs", NULL); | 183 | remove_proc_entry("fs/xfs", NULL); |
113 | out: | 184 | out: |
114 | return -ENOMEM; | 185 | return -ENOMEM; |
@@ -117,6 +188,10 @@ xfs_init_procfs(void) | |||
117 | void | 188 | void |
118 | xfs_cleanup_procfs(void) | 189 | xfs_cleanup_procfs(void) |
119 | { | 190 | { |
191 | #ifdef CONFIG_XFS_QUOTA | ||
192 | remove_proc_entry("fs/xfs/xqm", NULL); | ||
193 | remove_proc_entry("fs/xfs/xqmstat", NULL); | ||
194 | #endif | ||
120 | remove_proc_entry("fs/xfs/stat", NULL); | 195 | remove_proc_entry("fs/xfs/stat", NULL); |
121 | remove_proc_entry("fs/xfs", NULL); | 196 | remove_proc_entry("fs/xfs", NULL); |
122 | } | 197 | } |
diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index 736854b1ca1a..c03ad38ceaeb 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h | |||
@@ -183,6 +183,16 @@ struct xfsstats { | |||
183 | __uint32_t xs_ibt_2_alloc; | 183 | __uint32_t xs_ibt_2_alloc; |
184 | __uint32_t xs_ibt_2_free; | 184 | __uint32_t xs_ibt_2_free; |
185 | __uint32_t xs_ibt_2_moves; | 185 | __uint32_t xs_ibt_2_moves; |
186 | #define XFSSTAT_END_XQMSTAT (XFSSTAT_END_IBT_V2+6) | ||
187 | __uint32_t xs_qm_dqreclaims; | ||
188 | __uint32_t xs_qm_dqreclaim_misses; | ||
189 | __uint32_t xs_qm_dquot_dups; | ||
190 | __uint32_t xs_qm_dqcachemisses; | ||
191 | __uint32_t xs_qm_dqcachehits; | ||
192 | __uint32_t xs_qm_dqwants; | ||
193 | #define XFSSTAT_END_QM (XFSSTAT_END_XQMSTAT+2) | ||
194 | __uint32_t xs_qm_dquot; | ||
195 | __uint32_t xs_qm_dquot_unused; | ||
186 | /* Extra precision counters */ | 196 | /* Extra precision counters */ |
187 | __uint64_t xs_xstrat_bytes; | 197 | __uint64_t xs_xstrat_bytes; |
188 | __uint64_t xs_write_bytes; | 198 | __uint64_t xs_write_bytes; |