diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-02 12:57:34 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-02 12:57:34 -0500 |
commit | 5439ca6b8ff8cf8d758c19eb28b617a5912904ee (patch) | |
tree | 676f9e0b25074d2d8c5ab29df30c962b3cb7311e /fs/jbd2 | |
parent | a7a88b23737095e6c18a20c5d4eef9e25ec5b829 (diff) | |
parent | 0e9a9a1ad619e7e987815d20262d36a2f95717ca (diff) |
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 bug fixes from Ted Ts'o:
"Various bug fixes for ext4. Perhaps the most serious bug fixed is one
which could cause file system corruptions when performing file punch
operations."
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
ext4: avoid hang when mounting non-journal filesystems with orphan list
ext4: lock i_mutex when truncating orphan inodes
ext4: do not try to write superblock on ro remount w/o journal
ext4: include journal blocks in df overhead calcs
ext4: remove unaligned AIO warning printk
ext4: fix an incorrect comment about i_mutex
ext4: fix deadlock in journal_unmap_buffer()
ext4: split off ext4_journalled_invalidatepage()
jbd2: fix assertion failure in jbd2_journal_flush()
ext4: check dioread_nolock on remount
ext4: fix extent tree corruption caused by hole punch
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/transaction.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 42f6615af0ac..df9f29760efa 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -209,7 +209,8 @@ repeat: | |||
209 | if (!new_transaction) | 209 | if (!new_transaction) |
210 | goto alloc_transaction; | 210 | goto alloc_transaction; |
211 | write_lock(&journal->j_state_lock); | 211 | write_lock(&journal->j_state_lock); |
212 | if (!journal->j_running_transaction) { | 212 | if (!journal->j_running_transaction && |
213 | !journal->j_barrier_count) { | ||
213 | jbd2_get_transaction(journal, new_transaction); | 214 | jbd2_get_transaction(journal, new_transaction); |
214 | new_transaction = NULL; | 215 | new_transaction = NULL; |
215 | } | 216 | } |
@@ -1839,7 +1840,6 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh, | |||
1839 | 1840 | ||
1840 | BUFFER_TRACE(bh, "entry"); | 1841 | BUFFER_TRACE(bh, "entry"); |
1841 | 1842 | ||
1842 | retry: | ||
1843 | /* | 1843 | /* |
1844 | * It is safe to proceed here without the j_list_lock because the | 1844 | * It is safe to proceed here without the j_list_lock because the |
1845 | * buffers cannot be stolen by try_to_free_buffers as long as we are | 1845 | * buffers cannot be stolen by try_to_free_buffers as long as we are |
@@ -1934,14 +1934,11 @@ retry: | |||
1934 | * for commit and try again. | 1934 | * for commit and try again. |
1935 | */ | 1935 | */ |
1936 | if (partial_page) { | 1936 | if (partial_page) { |
1937 | tid_t tid = journal->j_committing_transaction->t_tid; | ||
1938 | |||
1939 | jbd2_journal_put_journal_head(jh); | 1937 | jbd2_journal_put_journal_head(jh); |
1940 | spin_unlock(&journal->j_list_lock); | 1938 | spin_unlock(&journal->j_list_lock); |
1941 | jbd_unlock_bh_state(bh); | 1939 | jbd_unlock_bh_state(bh); |
1942 | write_unlock(&journal->j_state_lock); | 1940 | write_unlock(&journal->j_state_lock); |
1943 | jbd2_log_wait_commit(journal, tid); | 1941 | return -EBUSY; |
1944 | goto retry; | ||
1945 | } | 1942 | } |
1946 | /* | 1943 | /* |
1947 | * OK, buffer won't be reachable after truncate. We just set | 1944 | * OK, buffer won't be reachable after truncate. We just set |
@@ -2002,21 +1999,23 @@ zap_buffer_unlocked: | |||
2002 | * @page: page to flush | 1999 | * @page: page to flush |
2003 | * @offset: length of page to invalidate. | 2000 | * @offset: length of page to invalidate. |
2004 | * | 2001 | * |
2005 | * Reap page buffers containing data after offset in page. | 2002 | * Reap page buffers containing data after offset in page. Can return -EBUSY |
2006 | * | 2003 | * if buffers are part of the committing transaction and the page is straddling |
2004 | * i_size. Caller then has to wait for current commit and try again. | ||
2007 | */ | 2005 | */ |
2008 | void jbd2_journal_invalidatepage(journal_t *journal, | 2006 | int jbd2_journal_invalidatepage(journal_t *journal, |
2009 | struct page *page, | 2007 | struct page *page, |
2010 | unsigned long offset) | 2008 | unsigned long offset) |
2011 | { | 2009 | { |
2012 | struct buffer_head *head, *bh, *next; | 2010 | struct buffer_head *head, *bh, *next; |
2013 | unsigned int curr_off = 0; | 2011 | unsigned int curr_off = 0; |
2014 | int may_free = 1; | 2012 | int may_free = 1; |
2013 | int ret = 0; | ||
2015 | 2014 | ||
2016 | if (!PageLocked(page)) | 2015 | if (!PageLocked(page)) |
2017 | BUG(); | 2016 | BUG(); |
2018 | if (!page_has_buffers(page)) | 2017 | if (!page_has_buffers(page)) |
2019 | return; | 2018 | return 0; |
2020 | 2019 | ||
2021 | /* We will potentially be playing with lists other than just the | 2020 | /* We will potentially be playing with lists other than just the |
2022 | * data lists (especially for journaled data mode), so be | 2021 | * data lists (especially for journaled data mode), so be |
@@ -2030,9 +2029,11 @@ void jbd2_journal_invalidatepage(journal_t *journal, | |||
2030 | if (offset <= curr_off) { | 2029 | if (offset <= curr_off) { |
2031 | /* This block is wholly outside the truncation point */ | 2030 | /* This block is wholly outside the truncation point */ |
2032 | lock_buffer(bh); | 2031 | lock_buffer(bh); |
2033 | may_free &= journal_unmap_buffer(journal, bh, | 2032 | ret = journal_unmap_buffer(journal, bh, offset > 0); |
2034 | offset > 0); | ||
2035 | unlock_buffer(bh); | 2033 | unlock_buffer(bh); |
2034 | if (ret < 0) | ||
2035 | return ret; | ||
2036 | may_free &= ret; | ||
2036 | } | 2037 | } |
2037 | curr_off = next_off; | 2038 | curr_off = next_off; |
2038 | bh = next; | 2039 | bh = next; |
@@ -2043,6 +2044,7 @@ void jbd2_journal_invalidatepage(journal_t *journal, | |||
2043 | if (may_free && try_to_free_buffers(page)) | 2044 | if (may_free && try_to_free_buffers(page)) |
2044 | J_ASSERT(!page_has_buffers(page)); | 2045 | J_ASSERT(!page_has_buffers(page)); |
2045 | } | 2046 | } |
2047 | return 0; | ||
2046 | } | 2048 | } |
2047 | 2049 | ||
2048 | /* | 2050 | /* |