diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-02-17 12:27:37 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-02-17 12:28:05 -0500 |
commit | b7e56edba4b02f2079042c326a8cd72a44635817 (patch) | |
tree | b5042002e9747cd8fb1278d61f86d8b92a74c018 /fs/jbd2 | |
parent | 13ca0fcaa33f6b1984c4111b6ec5df42689fea6f (diff) | |
parent | b0483e78e5c4c9871fc5541875b3bc006846d46b (diff) |
Merge branch 'linus' into x86/mm
x86/mm is on 32-rc4 and missing the spinlock namespace changes which
are needed for further commits into this topic.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/checkpoint.c | 15 | ||||
-rw-r--r-- | fs/jbd2/commit.c | 25 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 19 |
3 files changed, 48 insertions, 11 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c index ca0f5eb62b20..886849370950 100644 --- a/fs/jbd2/checkpoint.c +++ b/fs/jbd2/checkpoint.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/jbd2.h> | 22 | #include <linux/jbd2.h> |
23 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/blkdev.h> | ||
25 | #include <trace/events/jbd2.h> | 26 | #include <trace/events/jbd2.h> |
26 | 27 | ||
27 | /* | 28 | /* |
@@ -515,6 +516,20 @@ int jbd2_cleanup_journal_tail(journal_t *journal) | |||
515 | journal->j_tail_sequence = first_tid; | 516 | journal->j_tail_sequence = first_tid; |
516 | journal->j_tail = blocknr; | 517 | journal->j_tail = blocknr; |
517 | spin_unlock(&journal->j_state_lock); | 518 | spin_unlock(&journal->j_state_lock); |
519 | |||
520 | /* | ||
521 | * If there is an external journal, we need to make sure that | ||
522 | * any data blocks that were recently written out --- perhaps | ||
523 | * by jbd2_log_do_checkpoint() --- are flushed out before we | ||
524 | * drop the transactions from the external journal. It's | ||
525 | * unlikely this will be necessary, especially with a | ||
526 | * appropriately sized journal, but we need this to guarantee | ||
527 | * correctness. Fortunately jbd2_cleanup_journal_tail() | ||
528 | * doesn't get called all that often. | ||
529 | */ | ||
530 | if ((journal->j_fs_dev != journal->j_dev) && | ||
531 | (journal->j_flags & JBD2_BARRIER)) | ||
532 | blkdev_issue_flush(journal->j_fs_dev, NULL); | ||
518 | if (!(journal->j_flags & JBD2_ABORT)) | 533 | if (!(journal->j_flags & JBD2_ABORT)) |
519 | jbd2_journal_update_superblock(journal, 1); | 534 | jbd2_journal_update_superblock(journal, 1); |
520 | return 0; | 535 | return 0; |
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index d4cfd6d2779e..1bc74b6f26d2 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -259,6 +259,7 @@ static int journal_submit_data_buffers(journal_t *journal, | |||
259 | ret = err; | 259 | ret = err; |
260 | spin_lock(&journal->j_list_lock); | 260 | spin_lock(&journal->j_list_lock); |
261 | J_ASSERT(jinode->i_transaction == commit_transaction); | 261 | J_ASSERT(jinode->i_transaction == commit_transaction); |
262 | commit_transaction->t_flushed_data_blocks = 1; | ||
262 | jinode->i_flags &= ~JI_COMMIT_RUNNING; | 263 | jinode->i_flags &= ~JI_COMMIT_RUNNING; |
263 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); | 264 | wake_up_bit(&jinode->i_flags, __JI_COMMIT_RUNNING); |
264 | } | 265 | } |
@@ -286,7 +287,7 @@ static int journal_finish_inode_data_buffers(journal_t *journal, | |||
286 | if (err) { | 287 | if (err) { |
287 | /* | 288 | /* |
288 | * Because AS_EIO is cleared by | 289 | * Because AS_EIO is cleared by |
289 | * wait_on_page_writeback_range(), set it again so | 290 | * filemap_fdatawait_range(), set it again so |
290 | * that user process can get -EIO from fsync(). | 291 | * that user process can get -EIO from fsync(). |
291 | */ | 292 | */ |
292 | set_bit(AS_EIO, | 293 | set_bit(AS_EIO, |
@@ -636,6 +637,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
636 | JBUFFER_TRACE(jh, "ph3: write metadata"); | 637 | JBUFFER_TRACE(jh, "ph3: write metadata"); |
637 | flags = jbd2_journal_write_metadata_buffer(commit_transaction, | 638 | flags = jbd2_journal_write_metadata_buffer(commit_transaction, |
638 | jh, &new_jh, blocknr); | 639 | jh, &new_jh, blocknr); |
640 | if (flags < 0) { | ||
641 | jbd2_journal_abort(journal, flags); | ||
642 | continue; | ||
643 | } | ||
639 | set_bit(BH_JWrite, &jh2bh(new_jh)->b_state); | 644 | set_bit(BH_JWrite, &jh2bh(new_jh)->b_state); |
640 | wbuf[bufs++] = jh2bh(new_jh); | 645 | wbuf[bufs++] = jh2bh(new_jh); |
641 | 646 | ||
@@ -704,8 +709,17 @@ start_journal_io: | |||
704 | } | 709 | } |
705 | } | 710 | } |
706 | 711 | ||
707 | /* Done it all: now write the commit record asynchronously. */ | 712 | /* |
713 | * If the journal is not located on the file system device, | ||
714 | * then we must flush the file system device before we issue | ||
715 | * the commit record | ||
716 | */ | ||
717 | if (commit_transaction->t_flushed_data_blocks && | ||
718 | (journal->j_fs_dev != journal->j_dev) && | ||
719 | (journal->j_flags & JBD2_BARRIER)) | ||
720 | blkdev_issue_flush(journal->j_fs_dev, NULL); | ||
708 | 721 | ||
722 | /* Done it all: now write the commit record asynchronously. */ | ||
709 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, | 723 | if (JBD2_HAS_INCOMPAT_FEATURE(journal, |
710 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { | 724 | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)) { |
711 | err = journal_submit_commit_record(journal, commit_transaction, | 725 | err = journal_submit_commit_record(journal, commit_transaction, |
@@ -716,13 +730,6 @@ start_journal_io: | |||
716 | blkdev_issue_flush(journal->j_dev, NULL); | 730 | blkdev_issue_flush(journal->j_dev, NULL); |
717 | } | 731 | } |
718 | 732 | ||
719 | /* | ||
720 | * This is the right place to wait for data buffers both for ASYNC | ||
721 | * and !ASYNC commit. If commit is ASYNC, we need to wait only after | ||
722 | * the commit block went to disk (which happens above). If commit is | ||
723 | * SYNC, we need to wait for data buffers before we start writing | ||
724 | * commit block, which happens below in such setting. | ||
725 | */ | ||
726 | err = journal_finish_inode_data_buffers(journal, commit_transaction); | 733 | err = journal_finish_inode_data_buffers(journal, commit_transaction); |
727 | if (err) { | 734 | if (err) { |
728 | printk(KERN_WARNING | 735 | printk(KERN_WARNING |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index b0ab5219becb..ac0d027595d0 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -78,6 +78,7 @@ EXPORT_SYMBOL(jbd2_journal_errno); | |||
78 | EXPORT_SYMBOL(jbd2_journal_ack_err); | 78 | EXPORT_SYMBOL(jbd2_journal_ack_err); |
79 | EXPORT_SYMBOL(jbd2_journal_clear_err); | 79 | EXPORT_SYMBOL(jbd2_journal_clear_err); |
80 | EXPORT_SYMBOL(jbd2_log_wait_commit); | 80 | EXPORT_SYMBOL(jbd2_log_wait_commit); |
81 | EXPORT_SYMBOL(jbd2_log_start_commit); | ||
81 | EXPORT_SYMBOL(jbd2_journal_start_commit); | 82 | EXPORT_SYMBOL(jbd2_journal_start_commit); |
82 | EXPORT_SYMBOL(jbd2_journal_force_commit_nested); | 83 | EXPORT_SYMBOL(jbd2_journal_force_commit_nested); |
83 | EXPORT_SYMBOL(jbd2_journal_wipe); | 84 | EXPORT_SYMBOL(jbd2_journal_wipe); |
@@ -358,6 +359,10 @@ repeat: | |||
358 | 359 | ||
359 | jbd_unlock_bh_state(bh_in); | 360 | jbd_unlock_bh_state(bh_in); |
360 | tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); | 361 | tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); |
362 | if (!tmp) { | ||
363 | jbd2_journal_put_journal_head(new_jh); | ||
364 | return -ENOMEM; | ||
365 | } | ||
361 | jbd_lock_bh_state(bh_in); | 366 | jbd_lock_bh_state(bh_in); |
362 | if (jh_in->b_frozen_data) { | 367 | if (jh_in->b_frozen_data) { |
363 | jbd2_free(tmp, bh_in->b_size); | 368 | jbd2_free(tmp, bh_in->b_size); |
@@ -809,7 +814,7 @@ static journal_t * journal_init_common (void) | |||
809 | journal_t *journal; | 814 | journal_t *journal; |
810 | int err; | 815 | int err; |
811 | 816 | ||
812 | journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL); | 817 | journal = kzalloc(sizeof(*journal), GFP_KERNEL); |
813 | if (!journal) | 818 | if (!journal) |
814 | goto fail; | 819 | goto fail; |
815 | 820 | ||
@@ -913,6 +918,7 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev, | |||
913 | 918 | ||
914 | return journal; | 919 | return journal; |
915 | out_err: | 920 | out_err: |
921 | kfree(journal->j_wbuf); | ||
916 | jbd2_stats_proc_exit(journal); | 922 | jbd2_stats_proc_exit(journal); |
917 | kfree(journal); | 923 | kfree(journal); |
918 | return NULL; | 924 | return NULL; |
@@ -986,6 +992,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) | |||
986 | 992 | ||
987 | return journal; | 993 | return journal; |
988 | out_err: | 994 | out_err: |
995 | kfree(journal->j_wbuf); | ||
989 | jbd2_stats_proc_exit(journal); | 996 | jbd2_stats_proc_exit(journal); |
990 | kfree(journal); | 997 | kfree(journal); |
991 | return NULL; | 998 | return NULL; |
@@ -1246,6 +1253,13 @@ int jbd2_journal_load(journal_t *journal) | |||
1246 | if (jbd2_journal_recover(journal)) | 1253 | if (jbd2_journal_recover(journal)) |
1247 | goto recovery_error; | 1254 | goto recovery_error; |
1248 | 1255 | ||
1256 | if (journal->j_failed_commit) { | ||
1257 | printk(KERN_ERR "JBD2: journal transaction %u on %s " | ||
1258 | "is corrupt.\n", journal->j_failed_commit, | ||
1259 | journal->j_devname); | ||
1260 | return -EIO; | ||
1261 | } | ||
1262 | |||
1249 | /* OK, we've finished with the dynamic journal bits: | 1263 | /* OK, we've finished with the dynamic journal bits: |
1250 | * reinitialise the dynamic contents of the superblock in memory | 1264 | * reinitialise the dynamic contents of the superblock in memory |
1251 | * and reset them on disk. */ | 1265 | * and reset them on disk. */ |
@@ -2101,7 +2115,8 @@ static void __init jbd2_create_debugfs_entry(void) | |||
2101 | { | 2115 | { |
2102 | jbd2_debugfs_dir = debugfs_create_dir("jbd2", NULL); | 2116 | jbd2_debugfs_dir = debugfs_create_dir("jbd2", NULL); |
2103 | if (jbd2_debugfs_dir) | 2117 | if (jbd2_debugfs_dir) |
2104 | jbd2_debug = debugfs_create_u8(JBD2_DEBUG_NAME, S_IRUGO, | 2118 | jbd2_debug = debugfs_create_u8(JBD2_DEBUG_NAME, |
2119 | S_IRUGO | S_IWUSR, | ||
2105 | jbd2_debugfs_dir, | 2120 | jbd2_debugfs_dir, |
2106 | &jbd2_journal_enable_debug); | 2121 | &jbd2_journal_enable_debug); |
2107 | } | 2122 | } |