diff options
Diffstat (limited to 'fs/jbd2/checkpoint.c')
-rw-r--r-- | fs/jbd2/checkpoint.c | 19 |
1 files changed, 5 insertions, 14 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index 18c7a8d3da13..90d6091d7e18 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -96,15 +96,8 @@ static int __try_to_free_cp_buf(struct journal_head *jh) | |||
96 | 96 | ||
97 | if (jh->b_transaction == NULL && !buffer_locked(bh) && | 97 | if (jh->b_transaction == NULL && !buffer_locked(bh) && |
98 | !buffer_dirty(bh) && !buffer_write_io_error(bh)) { | 98 | !buffer_dirty(bh) && !buffer_write_io_error(bh)) { |
99 | /* | ||
100 | * Get our reference so that bh cannot be freed before | ||
101 | * we unlock it | ||
102 | */ | ||
103 | get_bh(bh); | ||
104 | JBUFFER_TRACE(jh, "remove from checkpoint list"); | 99 | JBUFFER_TRACE(jh, "remove from checkpoint list"); |
105 | ret = __jbd2_journal_remove_checkpoint(jh) + 1; | 100 | ret = __jbd2_journal_remove_checkpoint(jh) + 1; |
106 | BUFFER_TRACE(bh, "release"); | ||
107 | __brelse(bh); | ||
108 | } | 101 | } |
109 | return ret; | 102 | return ret; |
110 | } | 103 | } |
@@ -216,7 +209,7 @@ int jbd2_log_do_checkpoint(journal_t *journal) | |||
216 | struct buffer_head *bh; | 209 | struct buffer_head *bh; |
217 | transaction_t *transaction; | 210 | transaction_t *transaction; |
218 | tid_t this_tid; | 211 | tid_t this_tid; |
219 | int result, batch_count = 0, done = 0; | 212 | int result, batch_count = 0; |
220 | 213 | ||
221 | jbd_debug(1, "Start checkpoint\n"); | 214 | jbd_debug(1, "Start checkpoint\n"); |
222 | 215 | ||
@@ -291,11 +284,9 @@ restart: | |||
291 | if (!buffer_dirty(bh)) { | 284 | if (!buffer_dirty(bh)) { |
292 | if (unlikely(buffer_write_io_error(bh)) && !result) | 285 | if (unlikely(buffer_write_io_error(bh)) && !result) |
293 | result = -EIO; | 286 | result = -EIO; |
294 | get_bh(bh); | ||
295 | BUFFER_TRACE(bh, "remove from checkpoint"); | 287 | BUFFER_TRACE(bh, "remove from checkpoint"); |
296 | __jbd2_journal_remove_checkpoint(jh); | 288 | __jbd2_journal_remove_checkpoint(jh); |
297 | spin_unlock(&journal->j_list_lock); | 289 | spin_unlock(&journal->j_list_lock); |
298 | __brelse(bh); | ||
299 | goto retry; | 290 | goto retry; |
300 | } | 291 | } |
301 | /* | 292 | /* |
@@ -338,12 +329,12 @@ restart2: | |||
338 | transaction->t_tid != this_tid) | 329 | transaction->t_tid != this_tid) |
339 | goto out; | 330 | goto out; |
340 | 331 | ||
341 | while (!done && transaction->t_checkpoint_io_list) { | 332 | while (transaction->t_checkpoint_io_list) { |
342 | jh = transaction->t_checkpoint_io_list; | 333 | jh = transaction->t_checkpoint_io_list; |
343 | bh = jh2bh(jh); | 334 | bh = jh2bh(jh); |
344 | get_bh(bh); | ||
345 | if (buffer_locked(bh)) { | 335 | if (buffer_locked(bh)) { |
346 | spin_unlock(&journal->j_list_lock); | 336 | spin_unlock(&journal->j_list_lock); |
337 | get_bh(bh); | ||
347 | wait_on_buffer(bh); | 338 | wait_on_buffer(bh); |
348 | /* the journal_head may have gone by now */ | 339 | /* the journal_head may have gone by now */ |
349 | BUFFER_TRACE(bh, "brelse"); | 340 | BUFFER_TRACE(bh, "brelse"); |
@@ -359,8 +350,8 @@ restart2: | |||
359 | * know that it has been written out and so we can | 350 | * know that it has been written out and so we can |
360 | * drop it from the list | 351 | * drop it from the list |
361 | */ | 352 | */ |
362 | done = __jbd2_journal_remove_checkpoint(jh); | 353 | if (__jbd2_journal_remove_checkpoint(jh)) |
363 | __brelse(bh); | 354 | break; |
364 | } | 355 | } |
365 | out: | 356 | out: |
366 | spin_unlock(&journal->j_list_lock); | 357 | spin_unlock(&journal->j_list_lock); |