diff options
Diffstat (limited to 'fs/jbd/journal.c')
| -rw-r--r-- | fs/jbd/journal.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 737f7246a4b5..f96f85092d1c 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
| @@ -287,6 +287,7 @@ int journal_write_metadata_buffer(transaction_t *transaction, | |||
| 287 | struct page *new_page; | 287 | struct page *new_page; |
| 288 | unsigned int new_offset; | 288 | unsigned int new_offset; |
| 289 | struct buffer_head *bh_in = jh2bh(jh_in); | 289 | struct buffer_head *bh_in = jh2bh(jh_in); |
| 290 | journal_t *journal = transaction->t_journal; | ||
| 290 | 291 | ||
| 291 | /* | 292 | /* |
| 292 | * The buffer really shouldn't be locked: only the current committing | 293 | * The buffer really shouldn't be locked: only the current committing |
| @@ -300,6 +301,11 @@ int journal_write_metadata_buffer(transaction_t *transaction, | |||
| 300 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); | 301 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); |
| 301 | 302 | ||
| 302 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); | 303 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); |
| 304 | /* keep subsequent assertions sane */ | ||
| 305 | new_bh->b_state = 0; | ||
| 306 | init_buffer(new_bh, NULL, NULL); | ||
| 307 | atomic_set(&new_bh->b_count, 1); | ||
| 308 | new_jh = journal_add_journal_head(new_bh); /* This sleeps */ | ||
| 303 | 309 | ||
| 304 | /* | 310 | /* |
| 305 | * If a new transaction has already done a buffer copy-out, then | 311 | * If a new transaction has already done a buffer copy-out, then |
| @@ -361,14 +367,6 @@ repeat: | |||
| 361 | kunmap_atomic(mapped_data, KM_USER0); | 367 | kunmap_atomic(mapped_data, KM_USER0); |
| 362 | } | 368 | } |
| 363 | 369 | ||
| 364 | /* keep subsequent assertions sane */ | ||
| 365 | new_bh->b_state = 0; | ||
| 366 | init_buffer(new_bh, NULL, NULL); | ||
| 367 | atomic_set(&new_bh->b_count, 1); | ||
| 368 | jbd_unlock_bh_state(bh_in); | ||
| 369 | |||
| 370 | new_jh = journal_add_journal_head(new_bh); /* This sleeps */ | ||
| 371 | |||
| 372 | set_bh_page(new_bh, new_page, new_offset); | 370 | set_bh_page(new_bh, new_page, new_offset); |
| 373 | new_jh->b_transaction = NULL; | 371 | new_jh->b_transaction = NULL; |
| 374 | new_bh->b_size = jh2bh(jh_in)->b_size; | 372 | new_bh->b_size = jh2bh(jh_in)->b_size; |
| @@ -385,7 +383,11 @@ repeat: | |||
| 385 | * copying is moved to the transaction's shadow queue. | 383 | * copying is moved to the transaction's shadow queue. |
| 386 | */ | 384 | */ |
| 387 | JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); | 385 | JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); |
| 388 | journal_file_buffer(jh_in, transaction, BJ_Shadow); | 386 | spin_lock(&journal->j_list_lock); |
| 387 | __journal_file_buffer(jh_in, transaction, BJ_Shadow); | ||
| 388 | spin_unlock(&journal->j_list_lock); | ||
| 389 | jbd_unlock_bh_state(bh_in); | ||
| 390 | |||
| 389 | JBUFFER_TRACE(new_jh, "file as BJ_IO"); | 391 | JBUFFER_TRACE(new_jh, "file as BJ_IO"); |
| 390 | journal_file_buffer(new_jh, transaction, BJ_IO); | 392 | journal_file_buffer(new_jh, transaction, BJ_IO); |
| 391 | 393 | ||
| @@ -848,6 +850,12 @@ static int journal_reset(journal_t *journal) | |||
| 848 | 850 | ||
| 849 | first = be32_to_cpu(sb->s_first); | 851 | first = be32_to_cpu(sb->s_first); |
| 850 | last = be32_to_cpu(sb->s_maxlen); | 852 | last = be32_to_cpu(sb->s_maxlen); |
| 853 | if (first + JFS_MIN_JOURNAL_BLOCKS > last + 1) { | ||
| 854 | printk(KERN_ERR "JBD: Journal too short (blocks %lu-%lu).\n", | ||
| 855 | first, last); | ||
| 856 | journal_fail_superblock(journal); | ||
| 857 | return -EINVAL; | ||
| 858 | } | ||
| 851 | 859 | ||
| 852 | journal->j_first = first; | 860 | journal->j_first = first; |
| 853 | journal->j_last = last; | 861 | journal->j_last = last; |
