From patchwork Mon Nov 28 12:20:25 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zheng Liu X-Patchwork-Id: 127974 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id E0015B6F94 for ; Mon, 28 Nov 2011 23:18:46 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753573Ab1K1MSp (ORCPT ); Mon, 28 Nov 2011 07:18:45 -0500 Received: from mail-iy0-f174.google.com ([209.85.210.174]:53709 "EHLO mail-iy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752455Ab1K1MSo (ORCPT ); Mon, 28 Nov 2011 07:18:44 -0500 Received: by mail-iy0-f174.google.com with SMTP id e36so8873378iag.19 for ; Mon, 28 Nov 2011 04:18:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=zQWDqs6bUjHwVOhAsEsqmbICP82VNuxVLRFzarxNanE=; b=tom1f1dkNOq+bziAT6mzGoEtXUN2dgrHBRKgikalpYkhLg2fnQbjsjid9pFoYrwaPO h/Qwq9em91Dbm6sUcYAotP1p6F7n+ZOprZEMK08p5+/fjcGzhBvUscd74aa2EcQ4Wewm t/ydg0MxFC/VQHZND7bcRDcr4sJtEMjDVDklQ= Received: by 10.42.197.195 with SMTP id el3mr23812419icb.54.1322482723094; Mon, 28 Nov 2011 04:18:43 -0800 (PST) Received: from localhost.localdomain ([182.92.247.2]) by mx.google.com with ESMTPS id cb15sm40036924ibb.4.2011.11.28.04.18.39 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 28 Nov 2011 04:18:42 -0800 (PST) From: Zheng Liu To: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org Cc: Jens Axboe , Steven Whitehouse , Aditya Kali , Wang Shaoyan , Zheng Liu Subject: [PATCH v3 5/8] ext4: account the metadata request of write operations in buffered io Date: Mon, 28 Nov 2011 20:20:25 +0800 Message-Id: <1322482828-5529-5-git-send-email-wenqing.lz@taobao.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1322482828-5529-1-git-send-email-wenqing.lz@taobao.com> References: <1322482392-5346-1-git-send-email-wenqing.lz@taobao.com> <1322482828-5529-1-git-send-email-wenqing.lz@taobao.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Zheng Liu Calling ext4_ios_write to account metadata request of write in buffered io. CC: Jens Axboe CC: Steven Whitehouse CC: Aditya Kali Signed-off-by: Wang Shaoyan Signed-off-by: Zheng Liu --- 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 50aff92..9eb78ac 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -106,6 +106,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); @@ -902,6 +904,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; @@ -980,6 +983,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; @@ -1077,6 +1082,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 4eb4e59..38282bf 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; @@ -1187,6 +1194,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 0bd0125..dc5046b 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -506,6 +506,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; @@ -593,6 +595,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; @@ -1093,6 +1097,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; @@ -1203,9 +1209,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", @@ -1326,6 +1334,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 426ac55..e5e9acb 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -675,6 +675,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; @@ -4078,6 +4079,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); } @@ -4107,6 +4110,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 dba224c..99de268 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 4be6165..45cdf6d 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 ab999de..9f708ba 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4207,6 +4207,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); @@ -4944,6 +4945,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)