diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2007-09-17 05:59:52 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-10-10 03:56:24 -0400 |
commit | 16615be18cadf53ee6f8a4f0bdd647f0753421b1 (patch) | |
tree | 670c75e931e6d606211f338ee5e8b1d603c96521 /fs/gfs2/meta_io.c | |
parent | 55c0c4ac0be144014651b19e77c9b77f367955de (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.c | 55 |
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 | ||
300 | void 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 | ||