aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/meta_io.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-09-17 05:59:52 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-10-10 03:56:24 -0400
commit16615be18cadf53ee6f8a4f0bdd647f0753421b1 (patch)
tree670c75e931e6d606211f338ee5e8b1d603c96521 /fs/gfs2/meta_io.c
parent55c0c4ac0be144014651b19e77c9b77f367955de (diff)
[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,
297 unlock_page(bh->b_page); 297 unlock_page(bh->b_page);
298} 298}
299 299
300void gfs2_remove_from_journal(struct buffer_head *bh, struct gfs2_trans *tr, int meta)
301{
302 struct gfs2_sbd *sdp = GFS2_SB(bh->b_page->mapping->host);
303 struct gfs2_bufdata *bd = bh->b_private;
304 if (test_clear_buffer_pinned(bh)) {
305 list_del_init(&bd->bd_le.le_list);
306 if (meta) {
307 gfs2_assert_warn(sdp, sdp->sd_log_num_buf);
308 sdp->sd_log_num_buf--;
309 tr->tr_num_buf_rm++;
310 } else {
311 gfs2_assert_warn(sdp, sdp->sd_log_num_databuf);
312 sdp->sd_log_num_databuf--;
313 tr->tr_num_databuf_rm++;
314 }
315 tr->tr_touched = 1;
316 brelse(bh);
317 }
318 if (bd) {
319 if (bd->bd_ail) {
320 gfs2_remove_from_ail(NULL, bd);
321 bh->b_private = NULL;
322 bd->bd_bh = NULL;
323 bd->bd_blkno = bh->b_blocknr;
324 gfs2_trans_add_revoke(sdp, bd);
325 }
326 }
327 clear_buffer_dirty(bh);
328 clear_buffer_uptodate(bh);
329}
330
300/** 331/**
301 * gfs2_meta_wipe - make inode's buffers so they aren't dirty/pinned anymore 332 * gfs2_meta_wipe - make inode's buffers so they aren't dirty/pinned anymore
302 * @ip: the inode who owns the buffers 333 * @ip: the inode who owns the buffers
@@ -313,33 +344,11 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen)
313 while (blen) { 344 while (blen) {
314 bh = getbuf(ip->i_gl, bstart, NO_CREATE); 345 bh = getbuf(ip->i_gl, bstart, NO_CREATE);
315 if (bh) { 346 if (bh) {
316 struct gfs2_bufdata *bd;
317
318 lock_buffer(bh); 347 lock_buffer(bh);
319 gfs2_log_lock(sdp); 348 gfs2_log_lock(sdp);
320 bd = bh->b_private; 349 gfs2_remove_from_journal(bh, current->journal_info, 1);
321 if (test_clear_buffer_pinned(bh)) {
322 struct gfs2_trans *tr = current->journal_info;
323 list_del_init(&bd->bd_le.le_list);
324 gfs2_assert_warn(sdp, sdp->sd_log_num_buf);
325 sdp->sd_log_num_buf--;
326 tr->tr_num_buf_rm++;
327 brelse(bh);
328 }
329 if (bd) {
330 if (bd->bd_ail) {
331 gfs2_remove_from_ail(NULL, bd);
332 bh->b_private = NULL;
333 bd->bd_bh = NULL;
334 bd->bd_blkno = bh->b_blocknr;
335 gfs2_trans_add_revoke(sdp, bd);
336 }
337 }
338 clear_buffer_dirty(bh);
339 clear_buffer_uptodate(bh);
340 gfs2_log_unlock(sdp); 350 gfs2_log_unlock(sdp);
341 unlock_buffer(bh); 351 unlock_buffer(bh);
342
343 brelse(bh); 352 brelse(bh);
344 } 353 }
345 354