diff options
author | David S. Miller <davem@davemloft.net> | 2009-08-12 20:44:53 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-12 20:44:53 -0400 |
commit | aa11d958d1a6572eda08214d7c6a735804fe48a5 (patch) | |
tree | d025b05270ad1e010660d17eeadc6ac3c1abbd7d /fs/jbd2 | |
parent | 07f6642ee9418e962e54cbc07471cfe2e559c568 (diff) | |
parent | 9799218ae36910af50f002a5db1802d576fffb43 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
arch/microblaze/include/asm/socket.h
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/journal.c | 31 | ||||
-rw-r--r-- | fs/jbd2/transaction.c | 68 |
2 files changed, 52 insertions, 47 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 18bfd5dab642..e378cb383979 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -297,6 +297,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
297 | unsigned int new_offset; | 297 | unsigned int new_offset; |
298 | struct buffer_head *bh_in = jh2bh(jh_in); | 298 | struct buffer_head *bh_in = jh2bh(jh_in); |
299 | struct jbd2_buffer_trigger_type *triggers; | 299 | struct jbd2_buffer_trigger_type *triggers; |
300 | journal_t *journal = transaction->t_journal; | ||
300 | 301 | ||
301 | /* | 302 | /* |
302 | * The buffer really shouldn't be locked: only the current committing | 303 | * The buffer really shouldn't be locked: only the current committing |
@@ -310,6 +311,11 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
310 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); | 311 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); |
311 | 312 | ||
312 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); | 313 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); |
314 | /* keep subsequent assertions sane */ | ||
315 | new_bh->b_state = 0; | ||
316 | init_buffer(new_bh, NULL, NULL); | ||
317 | atomic_set(&new_bh->b_count, 1); | ||
318 | new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ | ||
313 | 319 | ||
314 | /* | 320 | /* |
315 | * If a new transaction has already done a buffer copy-out, then | 321 | * If a new transaction has already done a buffer copy-out, then |
@@ -388,14 +394,6 @@ repeat: | |||
388 | kunmap_atomic(mapped_data, KM_USER0); | 394 | kunmap_atomic(mapped_data, KM_USER0); |
389 | } | 395 | } |
390 | 396 | ||
391 | /* keep subsequent assertions sane */ | ||
392 | new_bh->b_state = 0; | ||
393 | init_buffer(new_bh, NULL, NULL); | ||
394 | atomic_set(&new_bh->b_count, 1); | ||
395 | jbd_unlock_bh_state(bh_in); | ||
396 | |||
397 | new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ | ||
398 | |||
399 | set_bh_page(new_bh, new_page, new_offset); | 397 | set_bh_page(new_bh, new_page, new_offset); |
400 | new_jh->b_transaction = NULL; | 398 | new_jh->b_transaction = NULL; |
401 | new_bh->b_size = jh2bh(jh_in)->b_size; | 399 | new_bh->b_size = jh2bh(jh_in)->b_size; |
@@ -412,7 +410,11 @@ repeat: | |||
412 | * copying is moved to the transaction's shadow queue. | 410 | * copying is moved to the transaction's shadow queue. |
413 | */ | 411 | */ |
414 | JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); | 412 | JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); |
415 | jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); | 413 | spin_lock(&journal->j_list_lock); |
414 | __jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); | ||
415 | spin_unlock(&journal->j_list_lock); | ||
416 | jbd_unlock_bh_state(bh_in); | ||
417 | |||
416 | JBUFFER_TRACE(new_jh, "file as BJ_IO"); | 418 | JBUFFER_TRACE(new_jh, "file as BJ_IO"); |
417 | jbd2_journal_file_buffer(new_jh, transaction, BJ_IO); | 419 | jbd2_journal_file_buffer(new_jh, transaction, BJ_IO); |
418 | 420 | ||
@@ -2410,6 +2412,7 @@ const char *jbd2_dev_to_name(dev_t device) | |||
2410 | int i = hash_32(device, CACHE_SIZE_BITS); | 2412 | int i = hash_32(device, CACHE_SIZE_BITS); |
2411 | char *ret; | 2413 | char *ret; |
2412 | struct block_device *bd; | 2414 | struct block_device *bd; |
2415 | static struct devname_cache *new_dev; | ||
2413 | 2416 | ||
2414 | rcu_read_lock(); | 2417 | rcu_read_lock(); |
2415 | if (devcache[i] && devcache[i]->device == device) { | 2418 | if (devcache[i] && devcache[i]->device == device) { |
@@ -2419,20 +2422,20 @@ const char *jbd2_dev_to_name(dev_t device) | |||
2419 | } | 2422 | } |
2420 | rcu_read_unlock(); | 2423 | rcu_read_unlock(); |
2421 | 2424 | ||
2425 | new_dev = kmalloc(sizeof(struct devname_cache), GFP_KERNEL); | ||
2426 | if (!new_dev) | ||
2427 | return "NODEV-ALLOCFAILURE"; /* Something non-NULL */ | ||
2422 | spin_lock(&devname_cache_lock); | 2428 | spin_lock(&devname_cache_lock); |
2423 | if (devcache[i]) { | 2429 | if (devcache[i]) { |
2424 | if (devcache[i]->device == device) { | 2430 | if (devcache[i]->device == device) { |
2431 | kfree(new_dev); | ||
2425 | ret = devcache[i]->devname; | 2432 | ret = devcache[i]->devname; |
2426 | spin_unlock(&devname_cache_lock); | 2433 | spin_unlock(&devname_cache_lock); |
2427 | return ret; | 2434 | return ret; |
2428 | } | 2435 | } |
2429 | call_rcu(&devcache[i]->rcu, free_devcache); | 2436 | call_rcu(&devcache[i]->rcu, free_devcache); |
2430 | } | 2437 | } |
2431 | devcache[i] = kmalloc(sizeof(struct devname_cache), GFP_KERNEL); | 2438 | devcache[i] = new_dev; |
2432 | if (!devcache[i]) { | ||
2433 | spin_unlock(&devname_cache_lock); | ||
2434 | return "NODEV-ALLOCFAILURE"; /* Something non-NULL */ | ||
2435 | } | ||
2436 | devcache[i]->device = device; | 2439 | devcache[i]->device = device; |
2437 | bd = bdget(device); | 2440 | bd = bdget(device); |
2438 | if (bd) { | 2441 | if (bd) { |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 494501edba6b..6213ac728f30 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -499,34 +499,15 @@ void jbd2_journal_unlock_updates (journal_t *journal) | |||
499 | wake_up(&journal->j_wait_transaction_locked); | 499 | wake_up(&journal->j_wait_transaction_locked); |
500 | } | 500 | } |
501 | 501 | ||
502 | /* | 502 | static void warn_dirty_buffer(struct buffer_head *bh) |
503 | * Report any unexpected dirty buffers which turn up. Normally those | ||
504 | * indicate an error, but they can occur if the user is running (say) | ||
505 | * tune2fs to modify the live filesystem, so we need the option of | ||
506 | * continuing as gracefully as possible. # | ||
507 | * | ||
508 | * The caller should already hold the journal lock and | ||
509 | * j_list_lock spinlock: most callers will need those anyway | ||
510 | * in order to probe the buffer's journaling state safely. | ||
511 | */ | ||
512 | static void jbd_unexpected_dirty_buffer(struct journal_head *jh) | ||
513 | { | 503 | { |
514 | int jlist; | 504 | char b[BDEVNAME_SIZE]; |
515 | |||
516 | /* If this buffer is one which might reasonably be dirty | ||
517 | * --- ie. data, or not part of this journal --- then | ||
518 | * we're OK to leave it alone, but otherwise we need to | ||
519 | * move the dirty bit to the journal's own internal | ||
520 | * JBDDirty bit. */ | ||
521 | jlist = jh->b_jlist; | ||
522 | 505 | ||
523 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || | 506 | printk(KERN_WARNING |
524 | jlist == BJ_Shadow || jlist == BJ_Forget) { | 507 | "JBD: Spotted dirty metadata buffer (dev = %s, blocknr = %llu). " |
525 | struct buffer_head *bh = jh2bh(jh); | 508 | "There's a risk of filesystem corruption in case of system " |
526 | 509 | "crash.\n", | |
527 | if (test_clear_buffer_dirty(bh)) | 510 | bdevname(bh->b_bdev, b), (unsigned long long)bh->b_blocknr); |
528 | set_buffer_jbddirty(bh); | ||
529 | } | ||
530 | } | 511 | } |
531 | 512 | ||
532 | /* | 513 | /* |
@@ -593,14 +574,16 @@ repeat: | |||
593 | if (jh->b_next_transaction) | 574 | if (jh->b_next_transaction) |
594 | J_ASSERT_JH(jh, jh->b_next_transaction == | 575 | J_ASSERT_JH(jh, jh->b_next_transaction == |
595 | transaction); | 576 | transaction); |
577 | warn_dirty_buffer(bh); | ||
596 | } | 578 | } |
597 | /* | 579 | /* |
598 | * In any case we need to clean the dirty flag and we must | 580 | * In any case we need to clean the dirty flag and we must |
599 | * do it under the buffer lock to be sure we don't race | 581 | * do it under the buffer lock to be sure we don't race |
600 | * with running write-out. | 582 | * with running write-out. |
601 | */ | 583 | */ |
602 | JBUFFER_TRACE(jh, "Unexpected dirty buffer"); | 584 | JBUFFER_TRACE(jh, "Journalling dirty buffer"); |
603 | jbd_unexpected_dirty_buffer(jh); | 585 | clear_buffer_dirty(bh); |
586 | set_buffer_jbddirty(bh); | ||
604 | } | 587 | } |
605 | 588 | ||
606 | unlock_buffer(bh); | 589 | unlock_buffer(bh); |
@@ -843,6 +826,15 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) | |||
843 | J_ASSERT_JH(jh, buffer_locked(jh2bh(jh))); | 826 | J_ASSERT_JH(jh, buffer_locked(jh2bh(jh))); |
844 | 827 | ||
845 | if (jh->b_transaction == NULL) { | 828 | if (jh->b_transaction == NULL) { |
829 | /* | ||
830 | * Previous jbd2_journal_forget() could have left the buffer | ||
831 | * with jbddirty bit set because it was being committed. When | ||
832 | * the commit finished, we've filed the buffer for | ||
833 | * checkpointing and marked it dirty. Now we are reallocating | ||
834 | * the buffer so the transaction freeing it must have | ||
835 | * committed and so it's safe to clear the dirty bit. | ||
836 | */ | ||
837 | clear_buffer_dirty(jh2bh(jh)); | ||
846 | jh->b_transaction = transaction; | 838 | jh->b_transaction = transaction; |
847 | 839 | ||
848 | /* first access by this transaction */ | 840 | /* first access by this transaction */ |
@@ -1644,8 +1636,13 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) | |||
1644 | 1636 | ||
1645 | if (jh->b_cp_transaction) { | 1637 | if (jh->b_cp_transaction) { |
1646 | JBUFFER_TRACE(jh, "on running+cp transaction"); | 1638 | JBUFFER_TRACE(jh, "on running+cp transaction"); |
1639 | /* | ||
1640 | * We don't want to write the buffer anymore, clear the | ||
1641 | * bit so that we don't confuse checks in | ||
1642 | * __journal_file_buffer | ||
1643 | */ | ||
1644 | clear_buffer_dirty(bh); | ||
1647 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); | 1645 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); |
1648 | clear_buffer_jbddirty(bh); | ||
1649 | may_free = 0; | 1646 | may_free = 0; |
1650 | } else { | 1647 | } else { |
1651 | JBUFFER_TRACE(jh, "on running transaction"); | 1648 | JBUFFER_TRACE(jh, "on running transaction"); |
@@ -1896,12 +1893,17 @@ void __jbd2_journal_file_buffer(struct journal_head *jh, | |||
1896 | if (jh->b_transaction && jh->b_jlist == jlist) | 1893 | if (jh->b_transaction && jh->b_jlist == jlist) |
1897 | return; | 1894 | return; |
1898 | 1895 | ||
1899 | /* The following list of buffer states needs to be consistent | ||
1900 | * with __jbd_unexpected_dirty_buffer()'s handling of dirty | ||
1901 | * state. */ | ||
1902 | |||
1903 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || | 1896 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || |
1904 | jlist == BJ_Shadow || jlist == BJ_Forget) { | 1897 | jlist == BJ_Shadow || jlist == BJ_Forget) { |
1898 | /* | ||
1899 | * For metadata buffers, we track dirty bit in buffer_jbddirty | ||
1900 | * instead of buffer_dirty. We should not see a dirty bit set | ||
1901 | * here because we clear it in do_get_write_access but e.g. | ||
1902 | * tune2fs can modify the sb and set the dirty bit at any time | ||
1903 | * so we try to gracefully handle that. | ||
1904 | */ | ||
1905 | if (buffer_dirty(bh)) | ||
1906 | warn_dirty_buffer(bh); | ||
1905 | if (test_clear_buffer_dirty(bh) || | 1907 | if (test_clear_buffer_dirty(bh) || |
1906 | test_clear_buffer_jbddirty(bh)) | 1908 | test_clear_buffer_jbddirty(bh)) |
1907 | was_dirty = 1; | 1909 | was_dirty = 1; |