From 16615be18cadf53ee6f8a4f0bdd647f0753421b1 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 17 Sep 2007 10:59:52 +0100 Subject: [GFS2] Clean up journaled data writing This patch cleans up the code for writing journaled data into the log. It also removes the need to allocate a small "tag" structure for each block written into the log. Instead we just keep count of the outstanding I/O so that we can be sure that its all been written at the correct time. Another result of this patch is that a number of ll_rw_block() calls have become submit_bh() calls, closing some races at the same time. Signed-off-by: Steven Whitehouse --- fs/gfs2/meta_io.c | 55 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) (limited to 'fs/gfs2/meta_io.c') diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 19097bc7c81d..1d80f2d42122 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c @@ -297,6 +297,37 @@ void gfs2_attach_bufdata(struct gfs2_glock *gl, struct buffer_head *bh, unlock_page(bh->b_page); } +void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int meta) +{ + struct gfs2_sbd *sdp = GFS2_SB(bh->b_page->mapping->host); + struct gfs2_bufdata *bd = bh->b_private; + if (test_clear_buffer_pinned(bh)) { + list_del_init(&bd->bd_le.le_list); + if (meta) { + gfs2_assert_warn(sdp, sdp->sd_log_num_buf); + sdp->sd_log_num_buf--; + tr->tr_num_buf_rm++; + } else { + gfs2_assert_warn(sdp, sdp->sd_log_num_databuf); + sdp->sd_log_num_databuf--; + tr->tr_num_databuf_rm++; + } + tr->tr_touched = 1; + brelse(bh); + } + if (bd) { + if (bd->bd_ail) { + gfs2_remove_from_ail(NULL, bd); + bh->b_private = NULL; + bd->bd_bh = NULL; + bd->bd_blkno = bh->b_blocknr; + gfs2_trans_add_revoke(sdp, bd); + } + } + clear_buffer_dirty(bh); + clear_buffer_uptodate(bh); +} + /** * gfs2_meta_wipe - make inode's buffers so they aren't dirty/pinned anymore * @ip: the inode who owns the buffers @@ -313,33 +344,11 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) while (blen) { bh = getbuf(ip->i_gl, bstart, NO_CREATE); if (bh) { - struct gfs2_bufdata *bd; - lock_buffer(bh); gfs2_log_lock(sdp); - bd = bh->b_private; - if (test_clear_buffer_pinned(bh)) { - struct gfs2_trans *tr = current->journal_info; - list_del_init(&bd->bd_le.le_list); - gfs2_assert_warn(sdp, sdp->sd_log_num_buf); - sdp->sd_log_num_buf--; - tr->tr_num_buf_rm++; - brelse(bh); - } - if (bd) { - if (bd->bd_ail) { - gfs2_remove_from_ail(NULL, bd); - bh->b_private = NULL; - bd->bd_bh = NULL; - bd->bd_blkno = bh->b_blocknr; - gfs2_trans_add_revoke(sdp, bd); - } - } - clear_buffer_dirty(bh); - clear_buffer_uptodate(bh); + gfs2_remove_from_journal(bh, current->journal_info, 1); gfs2_log_unlock(sdp); unlock_buffer(bh); - brelse(bh); } -- cgit v1.2.3