diff options
| author | Theodore Ts'o <tytso@mit.edu> | 2014-09-04 18:09:22 -0400 |
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2014-09-04 18:09:22 -0400 |
| commit | dc6e8d669cf5cb3ff84707c372c0a2a8a5e80845 (patch) | |
| tree | a96b09d5670e5f4a502dc246de2d9526a2bb261a /fs/jbd2 | |
| parent | 754cfed6bbcfdea6afb14f2686f7f8d71e94d4e2 (diff) | |
jbd2: don't call get_bh() before calling __jbd2_journal_remove_checkpoint()
The __jbd2_journal_remove_checkpoint() doesn't require an elevated
b_count; indeed, until the jh structure gets released by the call to
jbd2_journal_put_journal_head(), the bh's b_count is elevated by
virtue of the existence of the jh structure.
Suggested-by: Jan Kara <jack@suse.cz>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2')
| -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); |
