aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jbd/commit.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index 5a8ca61498ca..f943b9b3f208 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -36,7 +36,7 @@ static void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
36 36
37/* 37/*
38 * When an ext3-ordered file is truncated, it is possible that many pages are 38 * When an ext3-ordered file is truncated, it is possible that many pages are
39 * not sucessfully freed, because they are attached to a committing transaction. 39 * not successfully freed, because they are attached to a committing transaction.
40 * After the transaction commits, these pages are left on the LRU, with no 40 * After the transaction commits, these pages are left on the LRU, with no
41 * ->mapping, and with attached buffers. These pages are trivially reclaimable 41 * ->mapping, and with attached buffers. These pages are trivially reclaimable
42 * by the VM, but their apparent absence upsets the VM accounting, and it makes 42 * by the VM, but their apparent absence upsets the VM accounting, and it makes
@@ -45,8 +45,8 @@ static void journal_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
45 * So here, we have a buffer which has just come off the forget list. Look to 45 * So here, we have a buffer which has just come off the forget list. Look to
46 * see if we can strip all buffers from the backing page. 46 * see if we can strip all buffers from the backing page.
47 * 47 *
48 * Called under lock_journal(), and possibly under journal_datalist_lock. The 48 * Called under journal->j_list_lock. The caller provided us with a ref
49 * caller provided us with a ref against the buffer, and we drop that here. 49 * against the buffer, and we drop that here.
50 */ 50 */
51static void release_buffer_page(struct buffer_head *bh) 51static void release_buffer_page(struct buffer_head *bh)
52{ 52{
@@ -78,6 +78,19 @@ nope:
78} 78}
79 79
80/* 80/*
81 * Decrement reference counter for data buffer. If it has been marked
82 * 'BH_Freed', release it and the page to which it belongs if possible.
83 */
84static void release_data_buffer(struct buffer_head *bh)
85{
86 if (buffer_freed(bh)) {
87 clear_buffer_freed(bh);
88 release_buffer_page(bh);
89 } else
90 put_bh(bh);
91}
92
93/*
81 * Try to acquire jbd_lock_bh_state() against the buffer, when j_list_lock is 94 * Try to acquire jbd_lock_bh_state() against the buffer, when j_list_lock is
82 * held. For ranking reasons we must trylock. If we lose, schedule away and 95 * held. For ranking reasons we must trylock. If we lose, schedule away and
83 * return 0. j_list_lock is dropped in this case. 96 * return 0. j_list_lock is dropped in this case.
@@ -231,7 +244,7 @@ write_out_data:
231 if (locked) 244 if (locked)
232 unlock_buffer(bh); 245 unlock_buffer(bh);
233 BUFFER_TRACE(bh, "already cleaned up"); 246 BUFFER_TRACE(bh, "already cleaned up");
234 put_bh(bh); 247 release_data_buffer(bh);
235 continue; 248 continue;
236 } 249 }
237 if (locked && test_clear_buffer_dirty(bh)) { 250 if (locked && test_clear_buffer_dirty(bh)) {
@@ -258,10 +271,10 @@ write_out_data:
258 if (locked) 271 if (locked)
259 unlock_buffer(bh); 272 unlock_buffer(bh);
260 journal_remove_journal_head(bh); 273 journal_remove_journal_head(bh);
261 /* Once for our safety reference, once for 274 /* One for our safety reference, other for
262 * journal_remove_journal_head() */ 275 * journal_remove_journal_head() */
263 put_bh(bh); 276 put_bh(bh);
264 put_bh(bh); 277 release_data_buffer(bh);
265 } 278 }
266 279
267 if (need_resched() || spin_needbreak(&journal->j_list_lock)) { 280 if (need_resched() || spin_needbreak(&journal->j_list_lock)) {
@@ -443,7 +456,7 @@ void journal_commit_transaction(journal_t *journal)
443 } else { 456 } else {
444 jbd_unlock_bh_state(bh); 457 jbd_unlock_bh_state(bh);
445 } 458 }
446 put_bh(bh); 459 release_data_buffer(bh);
447 cond_resched_lock(&journal->j_list_lock); 460 cond_resched_lock(&journal->j_list_lock);
448 } 461 }
449 spin_unlock(&journal->j_list_lock); 462 spin_unlock(&journal->j_list_lock);
@@ -453,8 +466,6 @@ void journal_commit_transaction(journal_t *journal)
453 466
454 journal_write_revoke_records(journal, commit_transaction); 467 journal_write_revoke_records(journal, commit_transaction);
455 468
456 jbd_debug(3, "JBD: commit phase 2\n");
457
458 /* 469 /*
459 * If we found any dirty or locked buffers, then we should have 470 * If we found any dirty or locked buffers, then we should have
460 * looped back up to the write_out_data label. If there weren't 471 * looped back up to the write_out_data label. If there weren't