[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>
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c
index 19097bc7..1d80f2d 100644
--- a/fs/gfs2/meta_io.c
+++ b/fs/gfs2/meta_io.c
@@ -297,6 +297,37 @@
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 @@
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);
}