[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 <swhiteho@redhat.com>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user