summaryrefslogtreecommitdiffstats
path: root/fs/gfs2/meta_io.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-09-17 11:59:52 +0200
committerSteven Whitehouse <swhiteho@redhat.com>2007-10-10 09:56:24 +0200
commit16615be18cadf53ee6f8a4f0bdd647f0753421b1 (patch)
tree670c75e931e6d606211f338ee5e8b1d603c96521 /fs/gfs2/meta_io.c
parent[GFS2] GFS2: chmod hung - fix race in thread creation (diff)
downloadlinux-16615be18cadf53ee6f8a4f0bdd647f0753421b1.tar.xz
linux-16615be18cadf53ee6f8a4f0bdd647f0753421b1.zip
[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>
Diffstat (limited to 'fs/gfs2/meta_io.c')
-rw-r--r--fs/gfs2/meta_io.c55
1 files changed, 32 insertions, 23 deletions
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);
}