[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1320054184-14329-2-git-send-email-wenqing.lz@taobao.com>
Date: Mon, 31 Oct 2011 17:43:00 +0800
From: Zheng Liu <gnehzuil.liu@...il.com>
To: linux-ext4@...r.kernel.org, linux-fsdevel@...r.kernel.org
Cc: Wang Shaoyan <wangshaoyan.pt@...bao.com>
Subject: [PATCH 1/5] ext4: add data structure and functions for io statistic
From: Wang Shaoyan <wangshaoyan.pt@...bao.com>
This patch adds two data structures and related functions for
counting different io types. The per-cpu counters are added for ios which
are issued to the disk.
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@...bao.com>
---
fs/ext4/ext4.h | 43 ++++++++++++++++++++++++++++
fs/ext4/super.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 8 +++++
3 files changed, 131 insertions(+), 0 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index b7d7bd0..b0c51da 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1080,6 +1080,31 @@ struct ext4_super_block {
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
/*
+ * ext4 io statistics flags
+ */
+enum {
+ EXT4_IOS_SUPER_BLOCK = 0,
+ EXT4_IOS_GROUP_DESC,
+ EXT4_IOS_INODE_BITMAP,
+ EXT4_IOS_BLOCK_BITMAP,
+ EXT4_IOS_INODE_TABLE,
+ EXT4_IOS_EXTENT_BLOCK,
+ EXT4_IOS_INDIRECT_BLOCK,
+ EXT4_IOS_DIR_ENTRY,
+ EXT4_IOS_EXTENDED_ATTR,
+ EXT4_IOS_REGULAR_DATA,
+ EXT4_IOS_TYPE_END,
+};
+
+struct ext4_ios {
+ const char *function;
+ unsigned int line;
+ int rw;
+ int flag;
+ int count;
+};
+
+/*
* fourth extended-fs super-block data in memory
*/
struct ext4_sb_info {
@@ -1248,6 +1273,11 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino)
ino <= le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count));
}
+static inline unsigned ext4_blocks_per_page(struct inode *inode)
+{
+ return PAGE_CACHE_SIZE >> inode->i_blkbits;
+}
+
/*
* Inode dynamic state flags
*/
@@ -1875,6 +1905,19 @@ extern int ext4_group_extend(struct super_block *sb,
ext4_fsblk_t n_blocks_count);
/* super.c */
+extern void __ext4_io_stat(const char *, unsigned int, int, int, unsigned long);
+extern void ext4_io_stat_read(void *ios);
+extern void ext4_io_stat_write(handle_t *, struct buffer_head *,
+ const char *, unsigned int,
+ int, unsigned long);
+extern void __ext4_init_ios(struct ios *ios, struct ext4_ios *ext4_ios,
+ const char *function, unsigned int line,
+ int rw, int flag, unsigned long count,
+ void (*io_stat)(void *));
+#define ext4_init_ios(ios, ext4_ios, flag) \
+ __ext4_init_ios(ios, ext4_ios, __func__, __LINE__, \
+ READ, flag, 1, ext4_io_stat_read)
+
extern void *ext4_kvmalloc(size_t size, gfp_t flags);
extern void *ext4_kvzalloc(size_t size, gfp_t flags);
extern void ext4_kvfree(void *ptr);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 44d0c8d..684f98a 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4851,6 +4851,86 @@ out:
#endif
+#define EXT4_IOS_DEBUG
+
+#ifdef EXT4_IOS_DEBUG
+#define ext4_ios_debug(f, a...) trace_printk(f, ##a)
+#else
+#define ext4_ios_debug(f, a...)
+#endif
+
+static DEFINE_PER_CPU(unsigned long [EXT4_IOS_TYPE_END][2], ext4_ios_counters);
+
+void ext4_io_stat_write(handle_t *handle, struct buffer_head *bh,
+ const char *function, unsigned int line,
+ int flag, unsigned long count)
+{
+ if (!bh)
+ goto write;
+
+ if (!handle || !ext4_handle_valid(handle)) {
+ if (buffer_dirty(bh))
+ return;
+ } else {
+ if (buffer_jbddirty(bh))
+ return;
+ }
+write:
+ __ext4_io_stat(function, line, WRITE, flag, count);
+}
+
+static inline unsigned long ext4_get_ios_counter(int rw, int flag)
+{
+ unsigned long sum = 0;
+ int i;
+
+ for_each_possible_cpu(i)
+ sum += per_cpu(ext4_ios_counters[flag][rw], i);
+
+ return sum;
+}
+
+void __ext4_io_stat(const char *function, unsigned int line,
+ int rw, int flag, unsigned long count)
+{
+ const char *rwstr = rw ? "write" : "read";
+ const char *typestr[EXT4_IOS_TYPE_END] = {
+ "super block", "group descriptor",
+ "inode bitmap", "block bitmap",
+ "inode table", "extent block",
+ "indirect block", "dir entry",
+ "extended attributes", "regular data"
+ };
+
+ BUG_ON(flag < 0 || flag >= EXT4_IOS_TYPE_END);
+ this_cpu_add(ext4_ios_counters[flag][rw], count);
+
+ ext4_ios_debug("%s:%d - %s %s - %ld block" " - total %s %ld block\n",
+ function, line, rwstr, typestr[flag], count, rwstr,
+ ext4_get_ios_counter(rw, flag));
+}
+
+void ext4_io_stat_read(void *data)
+{
+ struct ext4_ios *ext4_ios = data;
+ return __ext4_io_stat(ext4_ios->function, ext4_ios->line,
+ ext4_ios->rw, ext4_ios->flag, ext4_ios->count);
+}
+
+void __ext4_init_ios(struct ios *ios, struct ext4_ios *ext4_ios,
+ const char *function, unsigned int line,
+ int rw, int flag, unsigned long count,
+ void (*io_stat)(void *))
+{
+ ext4_ios->function = function;
+ ext4_ios->line = line;
+ ext4_ios->rw = rw;
+ ext4_ios->flag = flag;
+ ext4_ios->count = count;
+ ios->data = ext4_ios;
+ ios->io_stat = io_stat;
+}
+
static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 14493a2..49b3c24 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2676,5 +2676,13 @@ static inline void inode_has_no_xattr(struct inode *inode)
inode->i_flags |= S_NOSEC;
}
+/*
+ * IO statistics
+ */
+struct ios {
+ void *data;
+ void (*io_stat)(void *data);
+};
+
#endif /* __KERNEL__ */
#endif /* _LINUX_FS_H */
--
1.7.4.1
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists