diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 23:13:18 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-27 23:13:18 -0400 |
| commit | 7d2f280e75f05919314e250cadf361a327ed555c (patch) | |
| tree | 47db5a9a0ceaf31adf49c18b663b1e08184f7cff /fs/jbd | |
| parent | e3e1288e86a07cdeb0aee5860a2dff111c6eff79 (diff) | |
| parent | 4408ea41c0ab4b711d4da44dd954fb06dce6c3f8 (diff) | |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6: (24 commits)
quota: Fix possible oops in __dquot_initialize()
ext3: Update kernel-doc comments
jbd/2: fixed typos
ext2: fixed typo.
ext3: Fix debug messages in ext3_group_extend()
jbd: Convert atomic_inc() to get_bh()
ext3: Remove misplaced BUFFER_TRACE() in ext3_truncate()
jbd: Fix debug message in do_get_write_access()
jbd: Check return value of __getblk()
ext3: Use DIV_ROUND_UP() on group desc block counting
ext3: Return proper error code on ext3_fill_super()
ext3: Remove unnecessary casts on bh->b_data
ext3: Cleanup ext3_setup_super()
quota: Fix issuing of warnings from dquot_transfer
quota: fix dquot_disable vs dquot_transfer race v2
jbd: Convert bitops to buffer fns
ext3/jbd: Avoid WARN() messages when failing to write the superblock
jbd: Use offset_in_page() instead of manual calculation
jbd: Remove unnecessary goto statement
jbd: Use printk_ratelimited() in journal_alloc_journal_head()
...
Diffstat (limited to 'fs/jbd')
| -rw-r--r-- | fs/jbd/checkpoint.c | 4 | ||||
| -rw-r--r-- | fs/jbd/commit.c | 8 | ||||
| -rw-r--r-- | fs/jbd/journal.c | 44 | ||||
| -rw-r--r-- | fs/jbd/recovery.c | 2 | ||||
| -rw-r--r-- | fs/jbd/transaction.c | 6 |
5 files changed, 44 insertions, 20 deletions
diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 05a38b9c4c0e..e4b87bc1fa56 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c | |||
| @@ -221,7 +221,7 @@ restart: | |||
| 221 | goto restart; | 221 | goto restart; |
| 222 | } | 222 | } |
| 223 | if (buffer_locked(bh)) { | 223 | if (buffer_locked(bh)) { |
| 224 | atomic_inc(&bh->b_count); | 224 | get_bh(bh); |
| 225 | spin_unlock(&journal->j_list_lock); | 225 | spin_unlock(&journal->j_list_lock); |
| 226 | jbd_unlock_bh_state(bh); | 226 | jbd_unlock_bh_state(bh); |
| 227 | wait_on_buffer(bh); | 227 | wait_on_buffer(bh); |
| @@ -283,7 +283,7 @@ static int __process_buffer(journal_t *journal, struct journal_head *jh, | |||
| 283 | int ret = 0; | 283 | int ret = 0; |
| 284 | 284 | ||
| 285 | if (buffer_locked(bh)) { | 285 | if (buffer_locked(bh)) { |
| 286 | atomic_inc(&bh->b_count); | 286 | get_bh(bh); |
| 287 | spin_unlock(&journal->j_list_lock); | 287 | spin_unlock(&journal->j_list_lock); |
| 288 | jbd_unlock_bh_state(bh); | 288 | jbd_unlock_bh_state(bh); |
| 289 | wait_on_buffer(bh); | 289 | wait_on_buffer(bh); |
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index 85a6883c0aca..34a4861c14b8 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
| @@ -587,13 +587,13 @@ void journal_commit_transaction(journal_t *journal) | |||
| 587 | /* Bump b_count to prevent truncate from stumbling over | 587 | /* Bump b_count to prevent truncate from stumbling over |
| 588 | the shadowed buffer! @@@ This can go if we ever get | 588 | the shadowed buffer! @@@ This can go if we ever get |
| 589 | rid of the BJ_IO/BJ_Shadow pairing of buffers. */ | 589 | rid of the BJ_IO/BJ_Shadow pairing of buffers. */ |
| 590 | atomic_inc(&jh2bh(jh)->b_count); | 590 | get_bh(jh2bh(jh)); |
| 591 | 591 | ||
| 592 | /* Make a temporary IO buffer with which to write it out | 592 | /* Make a temporary IO buffer with which to write it out |
| 593 | (this will requeue both the metadata buffer and the | 593 | (this will requeue both the metadata buffer and the |
| 594 | temporary IO buffer). new_bh goes on BJ_IO*/ | 594 | temporary IO buffer). new_bh goes on BJ_IO*/ |
| 595 | 595 | ||
| 596 | set_bit(BH_JWrite, &jh2bh(jh)->b_state); | 596 | set_buffer_jwrite(jh2bh(jh)); |
| 597 | /* | 597 | /* |
| 598 | * akpm: journal_write_metadata_buffer() sets | 598 | * akpm: journal_write_metadata_buffer() sets |
| 599 | * new_bh->b_transaction to commit_transaction. | 599 | * new_bh->b_transaction to commit_transaction. |
| @@ -603,7 +603,7 @@ void journal_commit_transaction(journal_t *journal) | |||
| 603 | JBUFFER_TRACE(jh, "ph3: write metadata"); | 603 | JBUFFER_TRACE(jh, "ph3: write metadata"); |
| 604 | flags = journal_write_metadata_buffer(commit_transaction, | 604 | flags = journal_write_metadata_buffer(commit_transaction, |
| 605 | jh, &new_jh, blocknr); | 605 | jh, &new_jh, blocknr); |
| 606 | set_bit(BH_JWrite, &jh2bh(new_jh)->b_state); | 606 | set_buffer_jwrite(jh2bh(new_jh)); |
| 607 | wbuf[bufs++] = jh2bh(new_jh); | 607 | wbuf[bufs++] = jh2bh(new_jh); |
| 608 | 608 | ||
| 609 | /* Record the new block's tag in the current descriptor | 609 | /* Record the new block's tag in the current descriptor |
| @@ -713,7 +713,7 @@ wait_for_iobuf: | |||
| 713 | shadowed buffer */ | 713 | shadowed buffer */ |
| 714 | jh = commit_transaction->t_shadow_list->b_tprev; | 714 | jh = commit_transaction->t_shadow_list->b_tprev; |
| 715 | bh = jh2bh(jh); | 715 | bh = jh2bh(jh); |
| 716 | clear_bit(BH_JWrite, &bh->b_state); | 716 | clear_buffer_jwrite(bh); |
| 717 | J_ASSERT_BH(bh, buffer_jbddirty(bh)); | 717 | J_ASSERT_BH(bh, buffer_jbddirty(bh)); |
| 718 | 718 | ||
| 719 | /* The metadata is now released for reuse, but we need | 719 | /* The metadata is now released for reuse, but we need |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 2c4b1f109da9..da1b5e4ffce1 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include <linux/poison.h> | 36 | #include <linux/poison.h> |
| 37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
| 38 | #include <linux/debugfs.h> | 38 | #include <linux/debugfs.h> |
| 39 | #include <linux/ratelimit.h> | ||
| 39 | 40 | ||
| 40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
| 41 | #include <asm/page.h> | 42 | #include <asm/page.h> |
| @@ -84,6 +85,7 @@ EXPORT_SYMBOL(journal_force_commit); | |||
| 84 | 85 | ||
| 85 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); | 86 | static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); |
| 86 | static void __journal_abort_soft (journal_t *journal, int errno); | 87 | static void __journal_abort_soft (journal_t *journal, int errno); |
| 88 | static const char *journal_dev_name(journal_t *journal, char *buffer); | ||
| 87 | 89 | ||
| 88 | /* | 90 | /* |
| 89 | * Helper function used to manage commit timeouts | 91 | * Helper function used to manage commit timeouts |
| @@ -439,7 +441,7 @@ int __log_start_commit(journal_t *journal, tid_t target) | |||
| 439 | */ | 441 | */ |
| 440 | if (!tid_geq(journal->j_commit_request, target)) { | 442 | if (!tid_geq(journal->j_commit_request, target)) { |
| 441 | /* | 443 | /* |
| 442 | * We want a new commit: OK, mark the request and wakup the | 444 | * We want a new commit: OK, mark the request and wakeup the |
| 443 | * commit thread. We do _not_ do the commit ourselves. | 445 | * commit thread. We do _not_ do the commit ourselves. |
| 444 | */ | 446 | */ |
| 445 | 447 | ||
| @@ -950,6 +952,8 @@ int journal_create(journal_t *journal) | |||
| 950 | if (err) | 952 | if (err) |
| 951 | return err; | 953 | return err; |
| 952 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); | 954 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); |
| 955 | if (unlikely(!bh)) | ||
| 956 | return -ENOMEM; | ||
| 953 | lock_buffer(bh); | 957 | lock_buffer(bh); |
| 954 | memset (bh->b_data, 0, journal->j_blocksize); | 958 | memset (bh->b_data, 0, journal->j_blocksize); |
| 955 | BUFFER_TRACE(bh, "marking dirty"); | 959 | BUFFER_TRACE(bh, "marking dirty"); |
| @@ -1010,6 +1014,23 @@ void journal_update_superblock(journal_t *journal, int wait) | |||
| 1010 | goto out; | 1014 | goto out; |
| 1011 | } | 1015 | } |
| 1012 | 1016 | ||
| 1017 | if (buffer_write_io_error(bh)) { | ||
| 1018 | char b[BDEVNAME_SIZE]; | ||
| 1019 | /* | ||
| 1020 | * Oh, dear. A previous attempt to write the journal | ||
| 1021 | * superblock failed. This could happen because the | ||
| 1022 | * USB device was yanked out. Or it could happen to | ||
| 1023 | * be a transient write error and maybe the block will | ||
| 1024 | * be remapped. Nothing we can do but to retry the | ||
| 1025 | * write and hope for the best. | ||
| 1026 | */ | ||
| 1027 | printk(KERN_ERR "JBD: previous I/O error detected " | ||
| 1028 | "for journal superblock update for %s.\n", | ||
| 1029 | journal_dev_name(journal, b)); | ||
| 1030 | clear_buffer_write_io_error(bh); | ||
| 1031 | set_buffer_uptodate(bh); | ||
| 1032 | } | ||
| 1033 | |||
| 1013 | spin_lock(&journal->j_state_lock); | 1034 | spin_lock(&journal->j_state_lock); |
| 1014 | jbd_debug(1,"JBD: updating superblock (start %u, seq %d, errno %d)\n", | 1035 | jbd_debug(1,"JBD: updating superblock (start %u, seq %d, errno %d)\n", |
| 1015 | journal->j_tail, journal->j_tail_sequence, journal->j_errno); | 1036 | journal->j_tail, journal->j_tail_sequence, journal->j_errno); |
| @@ -1021,9 +1042,17 @@ void journal_update_superblock(journal_t *journal, int wait) | |||
| 1021 | 1042 | ||
| 1022 | BUFFER_TRACE(bh, "marking dirty"); | 1043 | BUFFER_TRACE(bh, "marking dirty"); |
| 1023 | mark_buffer_dirty(bh); | 1044 | mark_buffer_dirty(bh); |
| 1024 | if (wait) | 1045 | if (wait) { |
| 1025 | sync_dirty_buffer(bh); | 1046 | sync_dirty_buffer(bh); |
| 1026 | else | 1047 | if (buffer_write_io_error(bh)) { |
| 1048 | char b[BDEVNAME_SIZE]; | ||
| 1049 | printk(KERN_ERR "JBD: I/O error detected " | ||
| 1050 | "when updating journal superblock for %s.\n", | ||
| 1051 | journal_dev_name(journal, b)); | ||
| 1052 | clear_buffer_write_io_error(bh); | ||
| 1053 | set_buffer_uptodate(bh); | ||
| 1054 | } | ||
| 1055 | } else | ||
| 1027 | write_dirty_buffer(bh, WRITE); | 1056 | write_dirty_buffer(bh, WRITE); |
| 1028 | 1057 | ||
| 1029 | out: | 1058 | out: |
| @@ -1719,7 +1748,6 @@ static void journal_destroy_journal_head_cache(void) | |||
| 1719 | static struct journal_head *journal_alloc_journal_head(void) | 1748 | static struct journal_head *journal_alloc_journal_head(void) |
| 1720 | { | 1749 | { |
| 1721 | struct journal_head *ret; | 1750 | struct journal_head *ret; |
| 1722 | static unsigned long last_warning; | ||
| 1723 | 1751 | ||
| 1724 | #ifdef CONFIG_JBD_DEBUG | 1752 | #ifdef CONFIG_JBD_DEBUG |
| 1725 | atomic_inc(&nr_journal_heads); | 1753 | atomic_inc(&nr_journal_heads); |
| @@ -1727,11 +1755,9 @@ static struct journal_head *journal_alloc_journal_head(void) | |||
| 1727 | ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); | 1755 | ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); |
| 1728 | if (ret == NULL) { | 1756 | if (ret == NULL) { |
| 1729 | jbd_debug(1, "out of memory for journal_head\n"); | 1757 | jbd_debug(1, "out of memory for journal_head\n"); |
| 1730 | if (time_after(jiffies, last_warning + 5*HZ)) { | 1758 | printk_ratelimited(KERN_NOTICE "ENOMEM in %s, retrying.\n", |
| 1731 | printk(KERN_NOTICE "ENOMEM in %s, retrying.\n", | 1759 | __func__); |
| 1732 | __func__); | 1760 | |
| 1733 | last_warning = jiffies; | ||
| 1734 | } | ||
| 1735 | while (ret == NULL) { | 1761 | while (ret == NULL) { |
| 1736 | yield(); | 1762 | yield(); |
| 1737 | ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); | 1763 | ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); |
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c index 81051dafebf5..5b43e96788e6 100644 --- a/fs/jbd/recovery.c +++ b/fs/jbd/recovery.c | |||
| @@ -296,10 +296,10 @@ int journal_skip_recovery(journal_t *journal) | |||
| 296 | #ifdef CONFIG_JBD_DEBUG | 296 | #ifdef CONFIG_JBD_DEBUG |
| 297 | int dropped = info.end_transaction - | 297 | int dropped = info.end_transaction - |
| 298 | be32_to_cpu(journal->j_superblock->s_sequence); | 298 | be32_to_cpu(journal->j_superblock->s_sequence); |
| 299 | #endif | ||
| 300 | jbd_debug(1, | 299 | jbd_debug(1, |
| 301 | "JBD: ignoring %d transaction%s from the journal.\n", | 300 | "JBD: ignoring %d transaction%s from the journal.\n", |
| 302 | dropped, (dropped == 1) ? "" : "s"); | 301 | dropped, (dropped == 1) ? "" : "s"); |
| 302 | #endif | ||
| 303 | journal->j_transaction_sequence = ++info.end_transaction; | 303 | journal->j_transaction_sequence = ++info.end_transaction; |
| 304 | } | 304 | } |
| 305 | 305 | ||
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 5ae71e75a491..846a3f314111 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
| @@ -293,9 +293,7 @@ handle_t *journal_start(journal_t *journal, int nblocks) | |||
| 293 | jbd_free_handle(handle); | 293 | jbd_free_handle(handle); |
| 294 | current->journal_info = NULL; | 294 | current->journal_info = NULL; |
| 295 | handle = ERR_PTR(err); | 295 | handle = ERR_PTR(err); |
| 296 | goto out; | ||
| 297 | } | 296 | } |
| 298 | out: | ||
| 299 | return handle; | 297 | return handle; |
| 300 | } | 298 | } |
| 301 | 299 | ||
| @@ -528,7 +526,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, | |||
| 528 | transaction = handle->h_transaction; | 526 | transaction = handle->h_transaction; |
| 529 | journal = transaction->t_journal; | 527 | journal = transaction->t_journal; |
| 530 | 528 | ||
| 531 | jbd_debug(5, "buffer_head %p, force_copy %d\n", jh, force_copy); | 529 | jbd_debug(5, "journal_head %p, force_copy %d\n", jh, force_copy); |
| 532 | 530 | ||
| 533 | JBUFFER_TRACE(jh, "entry"); | 531 | JBUFFER_TRACE(jh, "entry"); |
| 534 | repeat: | 532 | repeat: |
| @@ -713,7 +711,7 @@ done: | |||
| 713 | J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)), | 711 | J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)), |
| 714 | "Possible IO failure.\n"); | 712 | "Possible IO failure.\n"); |
| 715 | page = jh2bh(jh)->b_page; | 713 | page = jh2bh(jh)->b_page; |
| 716 | offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; | 714 | offset = offset_in_page(jh2bh(jh)->b_data); |
| 717 | source = kmap_atomic(page, KM_USER0); | 715 | source = kmap_atomic(page, KM_USER0); |
| 718 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); | 716 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); |
| 719 | kunmap_atomic(source, KM_USER0); | 717 | kunmap_atomic(source, KM_USER0); |
