From: Darrick J. Wong <[email protected]>

Export json versions of xfs time statistics information.

Signed-off-by: Darrick J. Wong <[email protected]>
---
 fs/xfs/scrub/stats.c   |   12 ++++++++++--
 fs/xfs/xfs_timestats.c |   45 +++++++++++++++++++++++++++++++++++++++++++--
 fs/xfs/xfs_timestats.h |    1 +
 3 files changed, 54 insertions(+), 4 deletions(-)


diff --git a/fs/xfs/scrub/stats.c b/fs/xfs/scrub/stats.c
index b9e6ace59e572..12f6ebbda3758 100644
--- a/fs/xfs/scrub/stats.c
+++ b/fs/xfs/scrub/stats.c
@@ -163,13 +163,21 @@ xchk_timestats_register(
                if (!name_map[i])
                        continue;
 
-               snprintf(name, 32, "scrub::%s", name_map[i]);
+               snprintf(name, 32, "scrub::%s.txt", name_map[i]);
                debugfs_create_file(name, 0444, ts->parent,
                                &ts->scrub[i].scrub, &xfs_timestats_fops);
 
-               snprintf(name, 32, "repair::%s", name_map[i]);
+               snprintf(name, 32, "repair::%s.txt", name_map[i]);
                debugfs_create_file(name, 0444, ts->parent,
                                &ts->scrub[i].repair, &xfs_timestats_fops);
+
+               snprintf(name, 32, "scrub::%s.json", name_map[i]);
+               debugfs_create_file(name, 0444, ts->parent,
+                               &ts->scrub[i].scrub, &xfs_timestats_json_fops);
+
+               snprintf(name, 32, "repair::%s.json", name_map[i]);
+               debugfs_create_file(name, 0444, ts->parent,
+                               &ts->scrub[i].repair, &xfs_timestats_json_fops);
        }
 }
 
diff --git a/fs/xfs/xfs_timestats.c b/fs/xfs/xfs_timestats.c
index 163a37e6717f7..dccecbe1ad922 100644
--- a/fs/xfs/xfs_timestats.c
+++ b/fs/xfs/xfs_timestats.c
@@ -49,6 +49,43 @@ const struct file_operations xfs_timestats_fops = {
        .read                   = xfs_timestats_read,
 };
 
+/* Format a timestats report into a buffer as json. */
+static ssize_t
+xfs_timestats_read_json(
+       struct file             *file,
+       char __user             *ubuf,
+       size_t                  count,
+       loff_t                  *ppos)
+{
+       struct seq_buf          s;
+       struct time_stats       *ts = file->private_data;
+       char                    *buf;
+       ssize_t                 ret;
+
+       /*
+        * This generates a stringly snapshot of a timestats report, so we
+        * do not want userspace to receive garbled text from multiple calls.
+        * If the file position is greater than 0, return a short read.
+        */
+       if (*ppos > 0)
+               return 0;
+
+       buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       seq_buf_init(&s, buf, PAGE_SIZE);
+       time_stats_to_json(&s, ts, "mount", TIME_STATS_PRINT_NO_ZEROES);
+       ret = simple_read_from_buffer(ubuf, count, ppos, buf, seq_buf_used(&s));
+       kfree(buf);
+       return ret;
+}
+
+const struct file_operations xfs_timestats_json_fops = {
+       .open                   = simple_open,
+       .read                   = xfs_timestats_read_json,
+};
+
 /* Set up timestats collection. */
 void
 xfs_timestats_init(
@@ -79,8 +116,12 @@ xfs_timestats_destroy(
 
 /* Export timestats via debugfs */
 #define X(p, ts, name) \
-       debugfs_create_file("blocked::" #name, 0444, (p), &(ts)->ts_##name, \
-                       &xfs_timestats_fops)
+       do { \
+               debugfs_create_file("blocked::" #name ".txt", 0444, (p), \
+                               &(ts)->ts_##name, &xfs_timestats_fops); \
+               debugfs_create_file("blocked::" #name ".json", 0444, (p), \
+                               &(ts)->ts_##name, &xfs_timestats_json_fops); \
+       } while (0)
 void
 xfs_timestats_export(
        struct xfs_mount        *mp)
diff --git a/fs/xfs/xfs_timestats.h b/fs/xfs/xfs_timestats.h
index 418e5abf2cf12..33ea794bdabce 100644
--- a/fs/xfs/xfs_timestats.h
+++ b/fs/xfs/xfs_timestats.h
@@ -8,6 +8,7 @@
 
 #ifdef CONFIG_XFS_TIME_STATS
 extern const struct file_operations xfs_timestats_fops;
+extern const struct file_operations xfs_timestats_json_fops;
 
 void xfs_timestats_init(struct xfs_mount *mp);
 void xfs_timestats_export(struct xfs_mount *mp);


Reply via email to