* [PATCH v4 1/8] ext4: add percpu counters and related functions to account io types.
2012-01-23 16:50 [PATCH v4 0/8] ext4: io type accouting Zheng Liu
@ 2012-01-23 16:50 ` Zheng Liu
2012-01-23 16:50 ` [PATCH v4 2/8] ext4: add wrapper functions for buffer layer Zheng Liu
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Zheng Liu @ 2012-01-23 16:50 UTC (permalink / raw)
To: linux-ext4, linux-fsdevel
Cc: Zheng Liu, Jens Axboe, Steven Whitehouse, Aditya Kali,
Wang Shaoyan
Add percpu counters in ext4_sb_info and related functions to save the result of
io types. IO types in ext4 are splitted as follows:
* Metadata:
- super block
- group descriptor
- inode bitmap
- block bitmap
- inode table
- extent block
- indirect block
- dir index and entry
- extended attribute
* Data:
- regular data block
CC: Jens Axboe <axboe@kernel.dk>
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: Aditya Kali <adityakali@google.com>
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/ext4.h | 37 +++++++++++++++++++++++++++++++++
fs/ext4/super.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 0 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 513004f..7ec0596 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1118,6 +1118,23 @@ struct ext4_super_block {
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
/*
+ * ext4 io types
+ */
+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,
+};
+
+/*
* fourth extended-fs super-block data in memory
*/
struct ext4_sb_info {
@@ -1259,6 +1276,9 @@ struct ext4_sb_info {
/* record the last minlen when FITRIM is called. */
atomic_t s_last_trim_minblks;
+
+ /* for io type accouting */
+ struct percpu_counter s_ios_counters[EXT4_IOS_TYPE_END][2];
};
static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
@@ -1294,6 +1314,11 @@ static inline void ext4_set_io_unwritten_flag(struct inode *inode,
}
}
+static inline unsigned int ext4_blocks_per_page(struct inode *inode)
+{
+ return PAGE_CACHE_SIZE >> inode->i_blkbits;
+}
+
/*
* Inode dynamic state flags
*/
@@ -1931,6 +1956,18 @@ extern int ext4_group_extend(struct super_block *sb,
extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count);
/* super.c */
+extern void __ext4_io_stat(struct super_block *sb, int rw,
+ int type, unsigned long count);
+extern void ext4_ios_write(struct super_block *sb, handle_t *handle,
+ struct buffer_head *bh, int type,
+ unsigned long count);
+
+static inline void ext4_ios_read(struct super_block *sb, int type,
+ unsigned long count)
+{
+ __ext4_io_stat(sb, READ, type, count);
+}
+
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 502c61f..f3a5cab 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -842,6 +842,10 @@ static void ext4_put_super(struct super_block *sb)
percpu_counter_destroy(&sbi->s_freeinodes_counter);
percpu_counter_destroy(&sbi->s_dirs_counter);
percpu_counter_destroy(&sbi->s_dirtyclusters_counter);
+ for (i = 0; i < EXT4_IOS_TYPE_END; i++) {
+ percpu_counter_destroy(&sbi->s_ios_counters[i][READ]);
+ percpu_counter_destroy(&sbi->s_ios_counters[i][WRITE]);
+ }
brelse(sbi->s_sbh);
#ifdef CONFIG_QUOTA
for (i = 0; i < MAXQUOTAS; i++)
@@ -3153,6 +3157,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
}
/*
+ * Note: s_ios_counters must be initialized as soon as possible becuase
+ * ext4 io type accouting depends on it
+ */
+ for (i = 0; i < EXT4_IOS_TYPE_END; i++) {
+ if (percpu_counter_init(&sbi->s_ios_counters[i][READ], 0))
+ goto out_init_ios;
+ if (percpu_counter_init(&sbi->s_ios_counters[i][WRITE], 0))
+ goto out_init_ios;
+ }
+ /*
* The ext4 superblock will not be buffer aligned for other than 1kB
* block sizes. We need to calculate the offset from buffer start.
*/
@@ -3874,6 +3888,11 @@ out_fail:
sb->s_fs_info = NULL;
kfree(sbi->s_blockgroup_lock);
kfree(sbi);
+out_init_ios:
+ for (i = 0; i < EXT4_IOS_TYPE_END; i++) {
+ percpu_counter_destroy(&sbi->s_ios_counters[i][READ]);
+ percpu_counter_destroy(&sbi->s_ios_counters[i][WRITE]);
+ }
out_free_orig:
kfree(orig_data);
return ret;
@@ -4939,6 +4958,47 @@ out:
#endif
+static inline u64 ext4_get_ios_counter(struct ext4_sb_info *sbi,
+ int rw, int type)
+{
+ return percpu_counter_sum(&sbi->s_ios_counters[type][rw]);
+}
+
+static inline void ext4_reset_ios_counter(struct ext4_sb_info *sbi)
+{
+ int i;
+
+ for (i = 0; i < EXT4_IOS_TYPE_END; i++) {
+ percpu_counter_set(&sbi->s_ios_counters[i][READ], 0);
+ percpu_counter_set(&sbi->s_ios_counters[i][WRITE], 0);
+ }
+}
+
+void __ext4_io_stat(struct super_block *sb, int rw,
+ int type, unsigned long count)
+{
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+
+ BUG_ON(type < 0 || type >= EXT4_IOS_TYPE_END);
+ percpu_counter_add(&sbi->s_ios_counters[type][rw], count);
+}
+
+void ext4_ios_write(struct super_block *sb, handle_t *handle,
+ struct buffer_head *bh, int type, unsigned long count)
+{
+ if (!bh)
+ goto count;
+ if (!handle || !ext4_handle_valid(handle)) {
+ if (buffer_dirty(bh))
+ return;
+ } else {
+ if (buffer_jbddirty(bh))
+ return;
+ }
+count:
+ __ext4_io_stat(sb, WRITE, type, count);
+}
+
static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 2/8] ext4: add wrapper functions for buffer layer
2012-01-23 16:50 [PATCH v4 0/8] ext4: io type accouting Zheng Liu
2012-01-23 16:50 ` [PATCH v4 1/8] ext4: add percpu counters and related functions to account io types Zheng Liu
@ 2012-01-23 16:50 ` Zheng Liu
2012-01-23 16:50 ` [PATCH v4 3/8] ext4: account the metadata request of read operations in buffered io Zheng Liu
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Zheng Liu @ 2012-01-23 16:50 UTC (permalink / raw)
To: linux-ext4, linux-fsdevel
Cc: Zheng Liu, Jens Axboe, Steven Whitehouse, Aditya Kali,
Wang Shaoyan
Wrapper functions are defined to account the result of different IO type.
CC: Jens Axboe <axboe@kernel.dk>
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: Aditya Kali <adityakali@google.com>
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/ext4.h | 21 +++++++++++++++
fs/ext4/super.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 7ec0596..688891e 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1968,6 +1968,27 @@ static inline void ext4_ios_read(struct super_block *sb, int type,
__ext4_io_stat(sb, READ, type, count);
}
+extern void ext4_submit_bh_read_nowait(int rw, struct buffer_head *bh,
+ struct super_block *sb, int type,
+ unsigned long count);
+extern int ext4_submit_bh_read(int rw, struct buffer_head *bh,
+ struct super_block *sb, int type,
+ unsigned long count);
+extern void ext4_submit_bh_write_nowait(int rw, struct buffer_head *bh,
+ struct super_block *sb, int type,
+ unsigned long count);
+extern struct buffer_head *ext4_sb_bread(struct super_block *sb, sector_t block,
+ int type, unsigned long count);
+extern void ext4_sb_breadahead(struct super_block *sb,
+ sector_t block, int type);
+
+static inline int ext4_bh_submit_read(struct buffer_head *bh,
+ struct super_block *sb,
+ int type, unsigned long count)
+{
+ return ext4_submit_bh_read(READ, bh, sb, type, count);
+}
+
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 f3a5cab..305ece7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4999,6 +4999,84 @@ count:
__ext4_io_stat(sb, WRITE, type, count);
}
+void ext4_submit_bh_read_nowait(int rw, struct buffer_head *bh,
+ struct super_block *sb, int type,
+ unsigned long count)
+{
+ BUG_ON(rw & WRITE);
+ BUG_ON(!buffer_locked(bh));
+
+ /* IO type accouting */
+ ext4_ios_read(sb, type, count);
+
+ get_bh(bh);
+ bh->b_end_io = end_buffer_read_sync;
+ submit_bh(rw, bh);
+}
+
+int ext4_submit_bh_read(int rw, struct buffer_head *bh, struct super_block *sb,
+ int type, unsigned long count)
+{
+ BUG_ON(rw & WRITE);
+ BUG_ON(!buffer_locked(bh));
+
+ if (buffer_uptodate(bh)) {
+ unlock_buffer(bh);
+ return 0;
+ }
+
+ ext4_submit_bh_read_nowait(rw, bh, sb, type, count);
+ wait_on_buffer(bh);
+ if (buffer_uptodate(bh))
+ return 0;
+ return -EIO;
+}
+
+void ext4_submit_bh_write_nowait(int rw, struct buffer_head *bh,
+ struct super_block *sb, int type,
+ unsigned long count)
+{
+ BUG_ON(!(rw & WRITE));
+ BUG_ON(!buffer_locked(bh));
+
+ /* IO type accouting */
+ ext4_ios_write(sb, NULL, NULL, type, count);
+
+ get_bh(bh);
+ bh->b_end_io = end_buffer_write_sync;
+ submit_bh(rw, bh);
+}
+
+struct buffer_head *ext4_sb_bread(struct super_block *sb, sector_t block,
+ int type, unsigned long count)
+{
+ struct buffer_head *bh = __getblk(sb->s_bdev, block, sb->s_blocksize);
+
+ if (likely(bh) && !buffer_uptodate(bh)) {
+ lock_buffer(bh);
+ if (ext4_submit_bh_read(READ, bh, sb, type, count)) {
+ brelse(bh);
+ bh = NULL;
+ }
+ }
+ return bh;
+}
+
+void ext4_sb_breadahead(struct super_block *sb, sector_t block, int type)
+{
+ struct buffer_head *bh = __getblk(sb->s_bdev, block, sb->s_blocksize);
+ if (likely(bh)) {
+ if (trylock_buffer(bh)) {
+ if (buffer_uptodate(bh))
+ ext4_submit_bh_read_nowait(READ, bh, sb,
+ type, 1);
+ else
+ unlock_buffer(bh);
+ }
+ brelse(bh);
+ }
+}
+
static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 3/8] ext4: account the metadata request of read operations in buffered io
2012-01-23 16:50 [PATCH v4 0/8] ext4: io type accouting Zheng Liu
2012-01-23 16:50 ` [PATCH v4 1/8] ext4: add percpu counters and related functions to account io types Zheng Liu
2012-01-23 16:50 ` [PATCH v4 2/8] ext4: add wrapper functions for buffer layer Zheng Liu
@ 2012-01-23 16:50 ` Zheng Liu
2012-01-23 16:50 ` [PATCH v4 4/8] ext4: account the data " Zheng Liu
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Zheng Liu @ 2012-01-23 16:50 UTC (permalink / raw)
To: linux-ext4, linux-fsdevel
Cc: Zheng Liu, Jens Axboe, Steven Whitehouse, Aditya Kali,
Wang Shaoyan
We replace all the call to the buffer layer with wrapper functions we defined.
CC: Jens Axboe <axboe@kernel.dk>
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: Aditya Kali <adityakali@google.com>
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/balloc.c | 2 +-
fs/ext4/extents.c | 11 +++++++----
fs/ext4/ialloc.c | 2 +-
fs/ext4/indirect.c | 6 ++++--
fs/ext4/inode.c | 17 +++++++----------
fs/ext4/mballoc.c | 5 ++---
fs/ext4/move_extent.c | 8 +++++---
fs/ext4/namei.c | 7 ++++---
fs/ext4/super.c | 9 ++++++---
fs/ext4/xattr.c | 18 ++++++++++++------
10 files changed, 49 insertions(+), 36 deletions(-)
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index f9e2cd8..6768a03 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -389,7 +389,7 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
*/
trace_ext4_read_block_bitmap_load(sb, block_group);
set_bitmap_uptodate(bh);
- if (bh_submit_read(bh) < 0) {
+ if (ext4_bh_submit_read(bh, sb, EXT4_IOS_BLOCK_BITMAP, 1) < 0) {
put_bh(bh);
ext4_error(sb, "Cannot read block bitmap - "
"block_group = %u, block_bitmap = %llu",
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 74f23c2..a26423f 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -667,7 +667,8 @@ ext4_ext_find_extent(struct inode *inode, ext4_lblk_t block,
if (!bh_uptodate_or_lock(bh)) {
trace_ext4_ext_load_extent(inode, block,
path[ppos].p_block);
- if (bh_submit_read(bh) < 0) {
+ if (ext4_bh_submit_read(bh, inode->i_sb,
+ EXT4_IOS_EXTENT_BLOCK, 1) < 0) {
put_bh(bh);
goto err;
}
@@ -1322,7 +1323,8 @@ got_index:
ix++;
block = ext4_idx_pblock(ix);
while (++depth < path->p_depth) {
- bh = sb_bread(inode->i_sb, block);
+ bh = ext4_sb_bread(inode->i_sb, block,
+ EXT4_IOS_EXTENT_BLOCK, 1);
if (bh == NULL)
return -EIO;
eh = ext_block_hdr(bh);
@@ -1336,7 +1338,7 @@ got_index:
put_bh(bh);
}
- bh = sb_bread(inode->i_sb, block);
+ bh = ext4_sb_bread(inode->i_sb, block, EXT4_IOS_EXTENT_BLOCK, 1);
if (bh == NULL)
return -EIO;
eh = ext_block_hdr(bh);
@@ -2561,7 +2563,8 @@ again:
ext_debug("move to level %d (block %llu)\n",
i + 1, ext4_idx_pblock(path[i].p_idx));
memset(path + i + 1, 0, sizeof(*path));
- bh = sb_bread(sb, ext4_idx_pblock(path[i].p_idx));
+ bh = ext4_sb_bread(sb, ext4_idx_pblock(path[i].p_idx),
+ EXT4_IOS_EXTENT_BLOCK, 1);
if (!bh) {
/* should we reset i_size? */
err = -EIO;
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 25d8c97..7edc9c0 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -154,7 +154,7 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
*/
trace_ext4_load_inode_bitmap(sb, block_group);
set_bitmap_uptodate(bh);
- if (bh_submit_read(bh) < 0) {
+ if (ext4_bh_submit_read(bh, sb, EXT4_IOS_INODE_BITMAP, 1) < 0) {
put_bh(bh);
ext4_error(sb, "Cannot read inode bitmap - "
"block_group = %u, inode_bitmap = %llu",
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 830e1b2..f0219fa 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -157,7 +157,8 @@ static Indirect *ext4_get_branch(struct inode *inode, int depth,
goto failure;
if (!bh_uptodate_or_lock(bh)) {
- if (bh_submit_read(bh) < 0) {
+ if (ext4_bh_submit_read(bh, sb,
+ EXT4_IOS_INDIRECT_BLOCK, 1) < 0) {
put_bh(bh);
goto failure;
}
@@ -1253,7 +1254,8 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
}
/* Go read the buffer for the next level down */
- bh = sb_bread(inode->i_sb, nr);
+ bh = ext4_sb_bread(inode->i_sb, nr,
+ EXT4_IOS_INDIRECT_BLOCK, 1);
/*
* A read failure? Report error and clear slot
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index feaa82f..b68d129 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -699,11 +699,10 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
bh = ext4_getblk(handle, inode, block, create, err);
if (!bh)
return bh;
- if (buffer_uptodate(bh))
+ if (bh_uptodate_or_lock(bh))
return bh;
- ll_rw_block(READ | REQ_META | REQ_PRIO, 1, &bh);
- wait_on_buffer(bh);
- if (buffer_uptodate(bh))
+ if (!ext4_submit_bh_read(READ | REQ_META | REQ_PRIO, bh, inode->i_sb,
+ EXT4_IOS_DIR_ENTRY, 1))
return bh;
put_bh(bh);
*err = -EIO;
@@ -3513,7 +3512,8 @@ make_io:
if (end > table)
end = table;
while (b <= end)
- sb_breadahead(sb, b++);
+ ext4_sb_breadahead(sb, b++,
+ EXT4_IOS_INODE_TABLE);
}
/*
@@ -3522,11 +3522,8 @@ make_io:
* Read the block from disk.
*/
trace_ext4_load_inode(inode);
- get_bh(bh);
- bh->b_end_io = end_buffer_read_sync;
- submit_bh(READ | REQ_META | REQ_PRIO, bh);
- wait_on_buffer(bh);
- if (!buffer_uptodate(bh)) {
+ if (ext4_submit_bh_read(READ | REQ_META | REQ_PRIO, bh, sb,
+ EXT4_IOS_INODE_TABLE, 1)) {
EXT4_ERROR_INODE_BLOCK(inode, block,
"unable to read itable block");
brelse(bh);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index cb990b2..f9bc9eb 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -873,7 +873,6 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
unlock_buffer(bh[i]);
continue;
}
- get_bh(bh[i]);
/*
* submit the buffer_head for read. We can
* safely mark the bitmap as uptodate now.
@@ -881,8 +880,8 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
* get set with buffer lock held.
*/
set_bitmap_uptodate(bh[i]);
- bh[i]->b_end_io = end_buffer_read_sync;
- submit_bh(READ, bh[i]);
+ ext4_submit_bh_read_nowait(READ, bh[i], sb,
+ EXT4_IOS_BLOCK_BITMAP, 1);
mb_debug(1, "read bitmap for group %u\n", first_group + i);
}
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c5826c6..c1d2d3a 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -99,7 +99,8 @@ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
if (path[ppos+1].p_bh)
brelse(path[ppos+1].p_bh);
path[ppos+1].p_bh =
- sb_bread(inode->i_sb, path[ppos].p_block);
+ ext4_sb_bread(inode->i_sb, path[ppos].p_block,
+ EXT4_IOS_EXTENT_BLOCK, 1);
if (!path[ppos+1].p_bh)
return -EIO;
path[ppos+1].p_hdr =
@@ -113,8 +114,9 @@ mext_next_extent(struct inode *inode, struct ext4_ext_path *path,
ext4_idx_pblock(path[cur_ppos].p_idx);
if (path[cur_ppos+1].p_bh)
brelse(path[cur_ppos+1].p_bh);
- path[cur_ppos+1].p_bh = sb_bread(inode->i_sb,
- path[cur_ppos].p_block);
+ path[cur_ppos+1].p_bh = ext4_sb_bread(
+ inode->i_sb, path[cur_ppos].p_block,
+ EXT4_IOS_EXTENT_BLOCK, 1);
if (!path[cur_ppos+1].p_bh)
return -EIO;
path[cur_ppos+1].p_hdr =
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 2043f48..4508257 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -921,9 +921,10 @@ restart:
num++;
bh = ext4_getblk(NULL, dir, b++, 0, &err);
bh_use[ra_max] = bh;
- if (bh)
- ll_rw_block(READ | REQ_META | REQ_PRIO,
- 1, &bh);
+ if (bh && !bh_uptodate_or_lock(bh))
+ ext4_submit_bh_read_nowait(
+ READ | REQ_META | REQ_PRIO,
+ bh, sb, EXT4_IOS_DIR_ENTRY, 1);
}
}
if ((bh = bh_use[ra_ptr++]) == NULL)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 305ece7..f6f4a0f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3177,7 +3177,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
logical_sb_block = sb_block;
}
- if (!(bh = sb_bread(sb, logical_sb_block))) {
+ if (!(bh = ext4_sb_bread(sb, logical_sb_block,
+ EXT4_IOS_SUPER_BLOCK, 1))) {
ext4_msg(sb, KERN_ERR, "unable to read superblock");
goto out_fail;
}
@@ -3349,7 +3350,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
brelse(bh);
logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
offset = do_div(logical_sb_block, blocksize);
- bh = sb_bread(sb, logical_sb_block);
+ bh = ext4_sb_bread(sb, logical_sb_block,
+ EXT4_IOS_SUPER_BLOCK, 1);
if (!bh) {
ext4_msg(sb, KERN_ERR,
"Can't read superblock on 2nd try");
@@ -3558,7 +3560,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
for (i = 0; i < db_count; i++) {
block = descriptor_loc(sb, logical_sb_block, i);
- sbi->s_group_desc[i] = sb_bread(sb, block);
+ sbi->s_group_desc[i] = ext4_sb_bread(sb, block,
+ EXT4_IOS_GROUP_DESC, 1);
if (!sbi->s_group_desc[i]) {
ext4_msg(sb, KERN_ERR,
"can't read group descriptor %d", i);
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index 93a00d8..a7b393f 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -221,7 +221,8 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
if (!EXT4_I(inode)->i_file_acl)
goto cleanup;
ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl);
- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl,
+ EXT4_IOS_EXTENDED_ATTR, 1);
if (!bh)
goto cleanup;
ea_bdebug(bh, "b_count=%d, refcount=%d",
@@ -364,7 +365,8 @@ ext4_xattr_block_list(struct dentry *dentry, char *buffer, size_t buffer_size)
if (!EXT4_I(inode)->i_file_acl)
goto cleanup;
ea_idebug(inode, "reading block %u", EXT4_I(inode)->i_file_acl);
- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl,
+ EXT4_IOS_EXTENDED_ATTR, 1);
error = -EIO;
if (!bh)
goto cleanup;
@@ -655,7 +657,8 @@ ext4_xattr_block_find(struct inode *inode, struct ext4_xattr_info *i,
if (EXT4_I(inode)->i_file_acl) {
/* The inode already has an extended attribute block. */
- bs->bh = sb_bread(sb, EXT4_I(inode)->i_file_acl);
+ bs->bh = ext4_sb_bread(sb, EXT4_I(inode)->i_file_acl,
+ EXT4_IOS_EXTENDED_ATTR, 1);
error = -EIO;
if (!bs->bh)
goto cleanup;
@@ -1188,7 +1191,8 @@ retry:
* EA block can hold new_extra_isize bytes.
*/
if (EXT4_I(inode)->i_file_acl) {
- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl,
+ EXT4_IOS_EXTENDED_ATTR, 1);
error = -EIO;
if (!bh)
goto cleanup;
@@ -1369,7 +1373,8 @@ ext4_xattr_delete_inode(handle_t *handle, struct inode *inode)
if (!EXT4_I(inode)->i_file_acl)
goto cleanup;
- bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl);
+ bh = ext4_sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl,
+ EXT4_IOS_EXTENDED_ATTR, 1);
if (!bh) {
EXT4_ERROR_INODE(inode, "block %llu read error",
EXT4_I(inode)->i_file_acl);
@@ -1501,7 +1506,8 @@ again:
goto again;
break;
}
- bh = sb_bread(inode->i_sb, ce->e_block);
+ bh = ext4_sb_bread(inode->i_sb, ce->e_block,
+ EXT4_IOS_EXTENDED_ATTR, 1);
if (!bh) {
EXT4_ERROR_INODE(inode, "block %lu read error",
(unsigned long) ce->e_block);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 4/8] ext4: account the data request of read operations in buffered io
2012-01-23 16:50 [PATCH v4 0/8] ext4: io type accouting Zheng Liu
` (2 preceding siblings ...)
2012-01-23 16:50 ` [PATCH v4 3/8] ext4: account the metadata request of read operations in buffered io Zheng Liu
@ 2012-01-23 16:50 ` Zheng Liu
2012-01-23 16:50 ` [PATCH v4 5/8] ext4: account the metadata request of write " Zheng Liu
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Zheng Liu @ 2012-01-23 16:50 UTC (permalink / raw)
To: linux-ext4, linux-fsdevel
Cc: Zheng Liu, Jens Axboe, Steven Whitehouse, Aditya Kali,
Wang Shaoyan
ll_rw_block in ext4_discard_partial_page_buffers_no_lock is replaced with
ext4_submit_bh_read, and ext4_ios_read are called in ext4_readpage and
ext4_readpages in order to account the data request.
CC: Jens Axboe <axboe@kernel.dk>
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: Aditya Kali <adityakali@google.com>
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/inode.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index b68d129..ff56658 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2665,6 +2665,8 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block)
static int ext4_readpage(struct file *file, struct page *page)
{
trace_ext4_readpage(page);
+ ext4_ios_read(page->mapping->host->i_sb, EXT4_IOS_REGULAR_DATA,
+ ext4_blocks_per_page(page->mapping->host));
return mpage_readpage(page, ext4_get_block);
}
@@ -2672,6 +2674,8 @@ static int
ext4_readpages(struct file *file, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages)
{
+ ext4_ios_read(mapping->host->i_sb, EXT4_IOS_REGULAR_DATA,
+ ext4_blocks_per_page(mapping->host));
return mpage_readpages(mapping, pages, nr_pages, ext4_get_block);
}
@@ -3268,12 +3272,12 @@ static int ext4_discard_partial_page_buffers_no_lock(handle_t *handle,
if (PageUptodate(page))
set_buffer_uptodate(bh);
- if (!buffer_uptodate(bh)) {
- err = -EIO;
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
+ if (!bh_uptodate_or_lock(bh)) {
+ err = ext4_submit_bh_read(READ, bh, inode->i_sb,
+ EXT4_IOS_REGULAR_DATA,
+ ext4_blocks_per_page(inode));
/* Uhhuh. Read error. Complain and punt.*/
- if (!buffer_uptodate(bh))
+ if (err)
goto next;
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 5/8] ext4: account the metadata request of write operations in buffered io
2012-01-23 16:50 [PATCH v4 0/8] ext4: io type accouting Zheng Liu
` (3 preceding siblings ...)
2012-01-23 16:50 ` [PATCH v4 4/8] ext4: account the data " Zheng Liu
@ 2012-01-23 16:50 ` Zheng Liu
2012-01-23 16:50 ` [PATCH v4 6/8] ext4: account the data " Zheng Liu
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Zheng Liu @ 2012-01-23 16:50 UTC (permalink / raw)
To: linux-ext4, linux-fsdevel
Cc: Zheng Liu, Jens Axboe, Steven Whitehouse, Aditya Kali,
Wang Shaoyan
ext4_ios_write is used to account metadata request of write in buffered io.
CC: Jens Axboe <axboe@kernel.dk>
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: Aditya Kali <adityakali@google.com>
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/extents.c | 6 ++++++
fs/ext4/ialloc.c | 8 ++++++++
fs/ext4/indirect.c | 15 +++++++++++++--
fs/ext4/inode.c | 4 ++++
fs/ext4/mballoc.c | 7 +++++++
fs/ext4/move_extent.c | 2 ++
fs/ext4/namei.c | 19 +++++++++++++++++++
fs/ext4/super.c | 2 ++
fs/ext4/xattr.c | 11 ++++++++++-
9 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index a26423f..1f0938a 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -105,6 +105,8 @@ static int __ext4_ext_dirty(const char *where, unsigned int line,
/* path points to block */
err = __ext4_handle_dirty_metadata(where, line, handle,
inode, path->p_bh);
+ ext4_ios_write(inode->i_sb, handle, path->p_bh,
+ EXT4_IOS_EXTENT_BLOCK, 1);
} else {
/* path points to leaf/index in inode body */
err = ext4_mark_inode_dirty(handle, inode);
@@ -901,6 +903,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
set_buffer_uptodate(bh);
unlock_buffer(bh);
+ ext4_ios_write(inode->i_sb, handle, bh, EXT4_IOS_EXTENT_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, inode, bh);
if (err)
goto cleanup;
@@ -979,6 +982,8 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
set_buffer_uptodate(bh);
unlock_buffer(bh);
+ ext4_ios_write(inode->i_sb, handle, bh,
+ EXT4_IOS_EXTENT_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, inode, bh);
if (err)
goto cleanup;
@@ -1076,6 +1081,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
set_buffer_uptodate(bh);
unlock_buffer(bh);
+ ext4_ios_write(inode->i_sb, handle, bh, EXT4_IOS_EXTENT_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, inode, bh);
if (err)
goto out;
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 7edc9c0..88424c5 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -277,10 +277,12 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
atomic_dec(&sbi->s_flex_groups[f].used_dirs);
}
BUFFER_TRACE(bh2, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(sb, handle, bh2, EXT4_IOS_GROUP_DESC, 1);
fatal = ext4_handle_dirty_metadata(handle, NULL, bh2);
out:
if (cleared) {
BUFFER_TRACE(bitmap_bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(sb, handle, bitmap_bh, EXT4_IOS_INODE_BITMAP, 1);
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
if (!fatal)
fatal = err;
@@ -776,6 +778,8 @@ repeat_in_this_group:
/* we won it */
BUFFER_TRACE(inode_bitmap_bh,
"call ext4_handle_dirty_metadata");
+ ext4_ios_write(sb, handle, inode_bitmap_bh,
+ EXT4_IOS_INODE_BITMAP, 1);
err = ext4_handle_dirty_metadata(handle,
NULL,
inode_bitmap_bh);
@@ -821,6 +825,8 @@ got:
}
BUFFER_TRACE(block_bitmap_bh, "dirty block bitmap");
+ ext4_ios_write(sb, handle, block_bitmap_bh,
+ EXT4_IOS_BLOCK_BITMAP, 1);
err = ext4_handle_dirty_metadata(handle, NULL, block_bitmap_bh);
brelse(block_bitmap_bh);
@@ -839,6 +845,7 @@ got:
goto fail;
}
BUFFER_TRACE(group_desc_bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(sb, handle, group_desc_bh, EXT4_IOS_GROUP_DESC, 1);
err = ext4_handle_dirty_metadata(handle, NULL, group_desc_bh);
if (err)
goto fail;
@@ -1191,6 +1198,7 @@ skip_zeroout:
BUFFER_TRACE(group_desc_bh,
"call ext4_handle_dirty_metadata");
+ ext4_ios_write(sb, handle, group_desc_bh, EXT4_IOS_GROUP_DESC, 1);
ret = ext4_handle_dirty_metadata(handle, NULL,
group_desc_bh);
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index f0219fa..8f9bfd2 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -505,6 +505,8 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
unlock_buffer(bh);
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(inode->i_sb, handle, bh,
+ EXT4_IOS_INDIRECT_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, inode, bh);
if (err)
goto failed;
@@ -592,6 +594,8 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode,
*/
jbd_debug(5, "splicing indirect only\n");
BUFFER_TRACE(where->bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(inode->i_sb, handle, where->bh,
+ EXT4_IOS_INDIRECT_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, inode, where->bh);
if (err)
goto err_out;
@@ -1092,6 +1096,8 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
if (try_to_extend_transaction(handle, inode)) {
if (bh) {
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(inode->i_sb, handle, bh,
+ EXT4_IOS_INDIRECT_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, inode, bh);
if (unlikely(err))
goto out_err;
@@ -1202,9 +1208,11 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
* block pointed to itself, it would have been detached when
* the block was cleared. Check for this instead of OOPSing.
*/
- if ((EXT4_JOURNAL(inode) == NULL) || bh2jh(this_bh))
+ if ((EXT4_JOURNAL(inode) == NULL) || bh2jh(this_bh)) {
+ ext4_ios_write(inode->i_sb, handle, this_bh,
+ EXT4_IOS_INDIRECT_BLOCK, 1);
ext4_handle_dirty_metadata(handle, inode, this_bh);
- else
+ } else
EXT4_ERROR_INODE(inode,
"circular indirect block detected at "
"block %llu",
@@ -1325,6 +1333,9 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
*p = 0;
BUFFER_TRACE(parent_bh,
"call ext4_handle_dirty_metadata");
+ ext4_ios_write(inode->i_sb, handle,
+ parent_bh,
+ EXT4_IOS_INDIRECT_BLOCK, 1);
ext4_handle_dirty_metadata(handle,
inode,
parent_bh);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index ff56658..176977a 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -677,6 +677,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
}
unlock_buffer(bh);
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(inode->i_sb, handle, bh, EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, inode, bh);
if (!fatal)
fatal = err;
@@ -3927,6 +3928,8 @@ static int ext4_do_update_inode(handle_t *handle,
EXT4_FEATURE_RO_COMPAT_LARGE_FILE);
sb->s_dirt = 1;
ext4_handle_sync(handle);
+ ext4_ios_write(inode->i_sb, handle, EXT4_SB(sb)->s_sbh,
+ EXT4_IOS_SUPER_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, NULL,
EXT4_SB(sb)->s_sbh);
}
@@ -3956,6 +3959,7 @@ static int ext4_do_update_inode(handle_t *handle,
}
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(inode->i_sb, handle, bh, EXT4_IOS_INODE_TABLE, 1);
rc = ext4_handle_dirty_metadata(handle, NULL, bh);
if (!err)
err = rc;
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index f9bc9eb..f09416c 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2823,6 +2823,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
ext4_set_bits(bitmap_bh->b_data, ac->ac_b_ex.fe_start,
ac->ac_b_ex.fe_len);
ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
+ ext4_ios_write(sb, handle, bitmap_bh, EXT4_IOS_BLOCK_BITMAP, 1);
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
if (!err)
err = -EAGAIN;
@@ -2868,9 +2869,11 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
&sbi->s_flex_groups[flex_group].free_clusters);
}
+ ext4_ios_write(sb, handle, bitmap_bh, EXT4_IOS_BLOCK_BITMAP, 1);
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
if (err)
goto out_err;
+ ext4_ios_write(sb, handle, gdp_bh, EXT4_IOS_GROUP_DESC, 1);
err = ext4_handle_dirty_metadata(handle, NULL, gdp_bh);
out_err:
@@ -4734,10 +4737,12 @@ do_more:
/* We dirtied the bitmap block */
BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
+ ext4_ios_write(sb, handle, bitmap_bh, EXT4_IOS_BLOCK_BITMAP, 1);
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
/* And the group descriptor block */
BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
+ ext4_ios_write(sb, handle, gd_bh, EXT4_IOS_GROUP_DESC, 1);
ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
if (!err)
err = ret;
@@ -4874,10 +4879,12 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
/* We dirtied the bitmap block */
BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
+ ext4_ios_write(sb, handle, bitmap_bh, EXT4_IOS_BLOCK_BITMAP, 1);
err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
/* And the group descriptor block */
BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
+ ext4_ios_write(sb, handle, gd_bh, EXT4_IOS_GROUP_DESC, 1);
ret = ext4_handle_dirty_metadata(handle, NULL, gd_bh);
if (!err)
err = ret;
diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
index c1d2d3a..8807abc 100644
--- a/fs/ext4/move_extent.c
+++ b/fs/ext4/move_extent.c
@@ -441,6 +441,8 @@ mext_insert_extents(handle_t *handle, struct inode *orig_inode,
end_ext, eh, range_to_move);
if (depth) {
+ ext4_ios_write(orig_inode->i_sb, handle, orig_path->p_bh,
+ EXT4_IOS_EXTENT_BLOCK, 1);
ret = ext4_handle_dirty_metadata(handle, orig_inode,
orig_path->p_bh);
if (ret)
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 4508257..a4f83f2 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1222,9 +1222,11 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
de = de2;
}
dx_insert_block(frame, hash2 + continued, newblock);
+ ext4_ios_write(dir->i_sb, handle, bh2, EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, dir, bh2);
if (err)
goto journal_error;
+ ext4_ios_write(dir->i_sb, handle, frame->bh, EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, dir, frame->bh);
if (err)
goto journal_error;
@@ -1322,6 +1324,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
dir->i_version++;
ext4_mark_inode_dirty(handle, dir);
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(inode->i_sb, handle, bh, EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, dir, bh);
if (err)
ext4_std_error(dir->i_sb, err);
@@ -1412,7 +1415,9 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
frame->bh = bh;
bh = bh2;
+ ext4_ios_write(inode->i_sb, handle, frame->bh, EXT4_IOS_DIR_ENTRY, 1);
ext4_handle_dirty_metadata(handle, dir, frame->bh);
+ ext4_ios_write(inode->i_sb, handle, bh, EXT4_IOS_DIR_ENTRY, 1);
ext4_handle_dirty_metadata(handle, dir, bh);
de = do_split(handle,dir, &bh, frame, &hinfo, &retval);
@@ -1587,6 +1592,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
dxtrace(dx_show_index("node", frames[1].entries));
dxtrace(dx_show_index("node",
((struct dx_node *) bh2->b_data)->entries));
+ ext4_ios_write(inode->i_sb, handle, bh2,
+ EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, dir, bh2);
if (err)
goto journal_error;
@@ -1613,6 +1620,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
if (err)
goto journal_error;
}
+ ext4_ios_write(inode->i_sb, handle, frames[0].bh,
+ EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, dir, frames[0].bh);
if (err) {
ext4_std_error(inode->i_sb, err);
@@ -1671,6 +1680,8 @@ static int ext4_delete_entry(handle_t *handle,
de->inode = 0;
dir->i_version++;
BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(dir->i_sb, handle, bh,
+ EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, dir, bh);
if (unlikely(err)) {
ext4_std_error(dir->i_sb, err);
@@ -1863,6 +1874,7 @@ retry:
ext4_set_de_type(dir->i_sb, de, S_IFDIR);
set_nlink(inode, 2);
BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(inode->i_sb, handle, dir_block, EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, inode, dir_block);
if (err)
goto out_clear_inode;
@@ -2014,6 +2026,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
/* Insert this inode at the head of the on-disk orphan list... */
NEXT_ORPHAN(inode) = le32_to_cpu(EXT4_SB(sb)->s_es->s_last_orphan);
EXT4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);
+ ext4_ios_write(sb, handle, EXT4_SB(sb)->s_sbh, EXT4_IOS_DIR_ENTRY, 1);
err = ext4_handle_dirty_metadata(handle, NULL, EXT4_SB(sb)->s_sbh);
rc = ext4_mark_iloc_dirty(handle, inode, &iloc);
if (!err)
@@ -2087,6 +2100,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
if (err)
goto out_brelse;
sbi->s_es->s_last_orphan = cpu_to_le32(ino_next);
+ ext4_ios_write(inode->i_sb, handle, sbi->s_sbh,
+ EXT4_IOS_SUPER_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, NULL, sbi->s_sbh);
} else {
struct ext4_iloc iloc2;
@@ -2476,6 +2491,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
ext4_current_time(new_dir);
ext4_mark_inode_dirty(handle, new_dir);
BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(old_dir->i_sb, handle, new_bh,
+ EXT4_IOS_DIR_ENTRY, 1);
retval = ext4_handle_dirty_metadata(handle, new_dir, new_bh);
if (unlikely(retval)) {
ext4_std_error(new_dir->i_sb, retval);
@@ -2530,6 +2547,8 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
PARENT_INO(dir_bh->b_data, new_dir->i_sb->s_blocksize) =
cpu_to_le32(new_dir->i_ino);
BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata");
+ ext4_ios_write(old_dir->i_sb, handle, dir_bh,
+ EXT4_IOS_DIR_ENTRY, 1);
retval = ext4_handle_dirty_metadata(handle, old_inode, dir_bh);
if (retval) {
ext4_std_error(old_dir->i_sb, retval);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index f6f4a0f..7aee0dd 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4206,6 +4206,7 @@ static int ext4_commit_super(struct super_block *sb, int sync)
&EXT4_SB(sb)->s_freeinodes_counter));
sb->s_dirt = 0;
BUFFER_TRACE(sbh, "marking dirty");
+ ext4_ios_write(sb, NULL, sbh, EXT4_IOS_SUPER_BLOCK, 1);
mark_buffer_dirty(sbh);
if (sync) {
error = sync_dirty_buffer(sbh);
@@ -4943,6 +4944,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
memcpy(bh->b_data+offset, data, len);
flush_dcache_page(bh->b_page);
unlock_buffer(bh);
+ ext4_ios_write(sb, handle, bh, EXT4_IOS_SUPER_BLOCK, 1);
err = ext4_handle_dirty_metadata(handle, NULL, bh);
brelse(bh);
out:
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index a7b393f..7bb3258 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -491,6 +491,8 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode,
EXT4_FREE_BLOCKS_FORGET);
} else {
le32_add_cpu(&BHDR(bh)->h_refcount, -1);
+ ext4_ios_write(inode->i_sb, handle, bh,
+ EXT4_IOS_EXTENDED_ATTR, 1);
error = ext4_handle_dirty_metadata(handle, inode, bh);
if (IS_SYNC(inode))
ext4_handle_sync(handle);
@@ -727,10 +729,13 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode,
unlock_buffer(bs->bh);
if (error == -EIO)
goto bad_block;
- if (!error)
+ if (!error) {
+ ext4_ios_write(sb, handle, bs->bh,
+ EXT4_IOS_EXTENDED_ATTR, 1);
error = ext4_handle_dirty_metadata(handle,
inode,
bs->bh);
+ }
if (error)
goto cleanup;
goto inserted;
@@ -799,6 +804,8 @@ inserted:
ea_bdebug(new_bh, "reusing; refcount now=%d",
le32_to_cpu(BHDR(new_bh)->h_refcount));
unlock_buffer(new_bh);
+ ext4_ios_write(sb, handle, new_bh,
+ EXT4_IOS_EXTENDED_ATTR, 1);
error = ext4_handle_dirty_metadata(handle,
inode,
new_bh);
@@ -857,6 +864,8 @@ getblk_failed:
set_buffer_uptodate(new_bh);
unlock_buffer(new_bh);
ext4_xattr_cache_insert(new_bh);
+ ext4_ios_write(sb, handle, new_bh,
+ EXT4_IOS_EXTENDED_ATTR, 1);
error = ext4_handle_dirty_metadata(handle,
inode, new_bh);
if (error)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 6/8] ext4: account the data request of write operations in buffered io
2012-01-23 16:50 [PATCH v4 0/8] ext4: io type accouting Zheng Liu
` (4 preceding siblings ...)
2012-01-23 16:50 ` [PATCH v4 5/8] ext4: account the metadata request of write " Zheng Liu
@ 2012-01-23 16:50 ` Zheng Liu
2012-01-23 16:50 ` [PATCH v4 7/8] ext4: request accouting in direct io Zheng Liu
2012-01-23 16:50 ` [PATCH v4 8/8] ext4: show the result of io types accouting Zheng Liu
7 siblings, 0 replies; 9+ messages in thread
From: Zheng Liu @ 2012-01-23 16:50 UTC (permalink / raw)
To: linux-ext4, linux-fsdevel
Cc: Zheng Liu, Jens Axboe, Steven Whitehouse, Aditya Kali,
Wang Shaoyan
We call ext4_ios_write() function to account the data request of write in
buffered io.
CC: Jens Axboe <axboe@kernel.dk>
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: Aditya Kali <adityakali@google.com>
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/inode.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 176977a..cfebc6d 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1910,6 +1910,8 @@ static int ext4_writepage(struct page *page,
struct inode *inode = page->mapping->host;
trace_ext4_writepage(page);
+ ext4_ios_write(inode->i_sb, NULL, NULL, EXT4_IOS_REGULAR_DATA,
+ ext4_blocks_per_page(inode));
size = i_size_read(inode);
if (page->index == size >> PAGE_CACHE_SHIFT)
len = size & ~PAGE_CACHE_MASK;
@@ -2084,6 +2086,9 @@ static int write_cache_pages_da(struct address_space *mapping,
logical = (sector_t) page->index <<
(PAGE_CACHE_SHIFT - inode->i_blkbits);
+ ext4_ios_write(inode->i_sb, NULL, NULL,
+ EXT4_IOS_REGULAR_DATA,
+ ext4_blocks_per_page(inode));
if (!page_has_buffers(page)) {
mpage_add_bh_to_extent(mpd, logical,
PAGE_CACHE_SIZE,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 7/8] ext4: request accouting in direct io
2012-01-23 16:50 [PATCH v4 0/8] ext4: io type accouting Zheng Liu
` (5 preceding siblings ...)
2012-01-23 16:50 ` [PATCH v4 6/8] ext4: account the data " Zheng Liu
@ 2012-01-23 16:50 ` Zheng Liu
2012-01-23 16:50 ` [PATCH v4 8/8] ext4: show the result of io types accouting Zheng Liu
7 siblings, 0 replies; 9+ messages in thread
From: Zheng Liu @ 2012-01-23 16:50 UTC (permalink / raw)
To: linux-ext4, linux-fsdevel
Cc: Zheng Liu, Jens Axboe, Steven Whitehouse, Aditya Kali,
Wang Shaoyan
ext4_ios_submit_io() function is defined to be called by __blockdev_direct_IO()
to count direct io.
CC: Jens Axboe <axboe@kernel.dk>
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: Aditya Kali <adityakali@google.com>
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/ext4.h | 2 ++
fs/ext4/indirect.c | 9 ++++++---
fs/ext4/inode.c | 13 ++++++++++++-
3 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 688891e..0f67d92 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1923,6 +1923,8 @@ extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
extern qsize_t *ext4_get_reserved_space(struct inode *inode);
extern void ext4_da_update_reserve_space(struct inode *inode,
int used, int quota_claim);
+extern void ext4_ios_submit_io(int rw, struct bio *bio,
+ struct inode *inode, loff_t file_offset);
/* indirect.c */
extern int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 8f9bfd2..143276a 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -820,10 +820,13 @@ retry:
ret = __blockdev_direct_IO(rw, iocb, inode,
inode->i_sb->s_bdev, iov,
offset, nr_segs,
- ext4_get_block, NULL, NULL, 0);
+ ext4_get_block, NULL, ext4_ios_submit_io, 0);
} else {
- ret = blockdev_direct_IO(rw, iocb, inode, iov,
- offset, nr_segs, ext4_get_block);
+ ret = __blockdev_direct_IO(rw, iocb, inode,
+ inode->i_sb->s_bdev, iov,
+ offset, nr_segs,
+ ext4_get_block, NULL, ext4_ios_submit_io,
+ DIO_LOCKING | DIO_SKIP_HOLES);
if (unlikely((rw & WRITE) && ret < 0)) {
loff_t isize = i_size_read(inode);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index cfebc6d..8ff6aea 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2948,7 +2948,7 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
offset, nr_segs,
ext4_get_block_write,
ext4_end_io_dio,
- NULL,
+ ext4_ios_submit_io,
DIO_LOCKING | DIO_SKIP_HOLES);
if (iocb->private)
EXT4_I(inode)->cur_aio_dio = NULL;
@@ -2989,6 +2989,17 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb,
return ext4_ind_direct_IO(rw, iocb, iov, offset, nr_segs);
}
+void ext4_ios_submit_io(int rw, struct bio *bio,
+ struct inode *inode, loff_t file_offset)
+{
+ int tmprw = !!rw;
+
+ /* ext4 io type accouting */
+ __ext4_io_stat(inode->i_sb, tmprw, EXT4_IOS_REGULAR_DATA,
+ ext4_blocks_per_page(inode));
+ submit_bio(rw, bio);
+}
+
static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb,
const struct iovec *iov, loff_t offset,
unsigned long nr_segs)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 8/8] ext4: show the result of io types accouting
2012-01-23 16:50 [PATCH v4 0/8] ext4: io type accouting Zheng Liu
` (6 preceding siblings ...)
2012-01-23 16:50 ` [PATCH v4 7/8] ext4: request accouting in direct io Zheng Liu
@ 2012-01-23 16:50 ` Zheng Liu
7 siblings, 0 replies; 9+ messages in thread
From: Zheng Liu @ 2012-01-23 16:50 UTC (permalink / raw)
To: linux-ext4, linux-fsdevel
Cc: Zheng Liu, Jens Axboe, Steven Whitehouse, Aditya Kali,
Wang Shaoyan
We create three files to control io type accouting and show the result.
* io_stats_enable is used to turn on/off io type accouting.
* io_stats_reset is used to reset the counters.
* io_stats shows the result of accouting.
CC: Jens Axboe <axboe@kernel.dk>
CC: Steven Whitehouse <swhiteho@redhat.com>
CC: Aditya Kali <adityakali@google.com>
Signed-off-by: Wang Shaoyan <wangshaoyan.pt@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
---
fs/ext4/ext4.h | 3 ++
fs/ext4/super.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 103 insertions(+), 1 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0f67d92..8c6d25f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1117,6 +1117,8 @@ struct ext4_super_block {
#define EXT4_MF_MNTDIR_SAMPLED 0x0001
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
+#define EXT4_IOS_VERSION "1.0"
+
/*
* ext4 io types
*/
@@ -1278,6 +1280,7 @@ struct ext4_sb_info {
atomic_t s_last_trim_minblks;
/* for io type accouting */
+ int s_ios_enable;
struct percpu_counter s_ios_counters[EXT4_IOS_TYPE_END][2];
};
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 7aee0dd..0a47cee 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2535,6 +2535,96 @@ static ssize_t inode_readahead_blks_store(struct ext4_attr *a,
return count;
}
+static inline u64 ext4_get_ios_counter(struct ext4_sb_info *sbi,
+ int rw, int flag);
+static inline void ext4_reset_ios_counter(struct ext4_sb_info *sbi);
+static ssize_t io_stats_show(struct ext4_attr *a,
+ struct ext4_sb_info *sbi, char *buf)
+{
+ int i;
+ unsigned long ios_counters[EXT4_IOS_TYPE_END][2] = {{0,},};
+
+ if (!sbi->s_ios_enable)
+ return snprintf(buf, PAGE_SIZE, "disabled\n");
+
+ for (i = 0; i < EXT4_IOS_TYPE_END; i++) {
+ ios_counters[i][READ] = ext4_get_ios_counter(sbi, READ, i);
+ ios_counters[i][WRITE] = ext4_get_ios_counter(sbi, WRITE, i);
+ }
+
+ return snprintf(buf, PAGE_SIZE,
+ "Version: %s\n"
+ "TYPE READ WRITE\n"
+ "super block %8lu %8lu\n"
+ "group descriptor %8lu %8lu\n"
+ "inode bitmap %8lu %8lu\n"
+ "block bitmap %8lu %8lu\n"
+ "inode table %8lu %8lu\n"
+ "extent block %8lu %8lu\n"
+ "indirect block %8lu %8lu\n"
+ "dir entry %8lu %8lu\n"
+ "extended attribute %8lu %8lu\n"
+ "regular data %8lu %8lu\n",
+ EXT4_IOS_VERSION,
+ ios_counters[EXT4_IOS_SUPER_BLOCK][READ],
+ ios_counters[EXT4_IOS_SUPER_BLOCK][WRITE],
+ ios_counters[EXT4_IOS_GROUP_DESC][READ],
+ ios_counters[EXT4_IOS_GROUP_DESC][WRITE],
+ ios_counters[EXT4_IOS_INODE_BITMAP][READ],
+ ios_counters[EXT4_IOS_INODE_BITMAP][WRITE],
+ ios_counters[EXT4_IOS_BLOCK_BITMAP][READ],
+ ios_counters[EXT4_IOS_BLOCK_BITMAP][WRITE],
+ ios_counters[EXT4_IOS_INODE_TABLE][READ],
+ ios_counters[EXT4_IOS_INODE_TABLE][WRITE],
+ ios_counters[EXT4_IOS_EXTENT_BLOCK][READ],
+ ios_counters[EXT4_IOS_EXTENT_BLOCK][WRITE],
+ ios_counters[EXT4_IOS_INDIRECT_BLOCK][READ],
+ ios_counters[EXT4_IOS_INDIRECT_BLOCK][WRITE],
+ ios_counters[EXT4_IOS_DIR_ENTRY][READ],
+ ios_counters[EXT4_IOS_DIR_ENTRY][WRITE],
+ ios_counters[EXT4_IOS_EXTENDED_ATTR][READ],
+ ios_counters[EXT4_IOS_EXTENDED_ATTR][WRITE],
+ ios_counters[EXT4_IOS_REGULAR_DATA][READ],
+ ios_counters[EXT4_IOS_REGULAR_DATA][WRITE]);
+}
+
+static ssize_t io_stats_reset_store(struct ext4_attr *a,
+ struct ext4_sb_info *sbi,
+ const char *buf, size_t count)
+{
+ unsigned long t;
+
+ if (parse_strtoul(buf, 0xffffffff, &t))
+ return -EINVAL;
+ if (t == 1)
+ ext4_reset_ios_counter(sbi);
+ return count;
+}
+
+static ssize_t io_stats_enable_show(struct ext4_attr *a,
+ struct ext4_sb_info *sbi, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", sbi->s_ios_enable);
+}
+
+static ssize_t io_stats_enable_store(struct ext4_attr *a,
+ struct ext4_sb_info *sbi,
+ const char *buf, size_t count)
+{
+ unsigned long val;
+
+ if (parse_strtoul(buf, 0xffffffff, &val))
+ return -EINVAL;
+
+ switch (val) {
+ case 0: ext4_reset_ios_counter(sbi);
+ case 1: sbi->s_ios_enable = val; break;
+ default: return -EINVAL;
+ }
+
+ return count;
+}
+
static ssize_t sbi_ui_show(struct ext4_attr *a,
struct ext4_sb_info *sbi, char *buf)
{
@@ -2568,6 +2658,7 @@ static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store)
#define EXT4_INFO_ATTR(name) EXT4_ATTR(name, 0444, NULL, NULL)
#define EXT4_RO_ATTR(name) EXT4_ATTR(name, 0444, name##_show, NULL)
+#define EXT4_WO_ATTR(name) EXT4_ATTR(name, 0222, NULL, name##_store)
#define EXT4_RW_ATTR(name) EXT4_ATTR(name, 0644, name##_show, name##_store)
#define EXT4_RW_ATTR_SBI_UI(name, elname) \
EXT4_ATTR_OFFSET(name, 0644, sbi_ui_show, sbi_ui_store, elname)
@@ -2578,6 +2669,9 @@ EXT4_RO_ATTR(session_write_kbytes);
EXT4_RO_ATTR(lifetime_write_kbytes);
EXT4_RO_ATTR(extent_cache_hits);
EXT4_RO_ATTR(extent_cache_misses);
+EXT4_RO_ATTR(io_stats);
+EXT4_RW_ATTR(io_stats_enable);
+EXT4_WO_ATTR(io_stats_reset);
EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show,
inode_readahead_blks_store, s_inode_readahead_blks);
EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal);
@@ -2597,6 +2691,9 @@ static struct attribute *ext4_attrs[] = {
ATTR_LIST(extent_cache_misses),
ATTR_LIST(inode_readahead_blks),
ATTR_LIST(inode_goal),
+ ATTR_LIST(io_stats),
+ ATTR_LIST(io_stats_enable),
+ ATTR_LIST(io_stats_reset),
ATTR_LIST(mb_stats),
ATTR_LIST(mb_max_to_scan),
ATTR_LIST(mb_min_to_scan),
@@ -3160,6 +3257,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
* Note: s_ios_counters must be initialized as soon as possible becuase
* ext4 io type accouting depends on it
*/
+ sbi->s_ios_enable = 0;
for (i = 0; i < EXT4_IOS_TYPE_END; i++) {
if (percpu_counter_init(&sbi->s_ios_counters[i][READ], 0))
goto out_init_ios;
@@ -4985,7 +5083,8 @@ void __ext4_io_stat(struct super_block *sb, int rw,
struct ext4_sb_info *sbi = EXT4_SB(sb);
BUG_ON(type < 0 || type >= EXT4_IOS_TYPE_END);
- percpu_counter_add(&sbi->s_ios_counters[type][rw], count);
+ if (sbi->s_ios_enable)
+ percpu_counter_add(&sbi->s_ios_counters[type][rw], count);
}
void ext4_ios_write(struct super_block *sb, handle_t *handle,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread