diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 20:14:59 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 20:14:59 -0500 |
commit | 2150edc6c5cf00f7adb54538b9ea2a3e9cedca3f (patch) | |
tree | f72a0d85e66f500b4cead348a231e3d3b9f357bc /fs/jbd2/commit.c | |
parent | cd764695b67386a81964f68e9c66efd9f13f4d29 (diff) | |
parent | 4b905671d2ea09fd48fed72c581df17e40823f39 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (57 commits)
jbd2: Fix oops in jbd2_journal_init_inode() on corrupted fs
ext4: Remove "extents" mount option
block: Add Kconfig help which notes that ext4 needs CONFIG_LBD
ext4: Make printk's consistently prefixed with "EXT4-fs: "
ext4: Add sanity checks for the superblock before mounting the filesystem
ext4: Add mount option to set kjournald's I/O priority
jbd2: Submit writes to the journal using WRITE_SYNC
jbd2: Add pid and journal device name to the "kjournald2 starting" message
ext4: Add markers for better debuggability
ext4: Remove code to create the journal inode
ext4: provide function to release metadata pages under memory pressure
ext3: provide function to release metadata pages under memory pressure
add releasepage hooks to block devices which can be used by file systems
ext4: Fix s_dirty_blocks_counter if block allocation failed with nodelalloc
ext4: Init the complete page while building buddy cache
ext4: Don't allow new groups to be added during block allocation
ext4: mark the blocks/inode bitmap beyond end of group as used
ext4: Use new buffer_head flag to check uninit group bitmaps initialization
ext4: Fix the race between read_inode_bitmap() and ext4_new_inode()
ext4: code cleanup
...
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index c8a1bace685a..62804e57a44c 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/crc32.h> | 25 | #include <linux/crc32.h> |
26 | #include <linux/writeback.h> | 26 | #include <linux/writeback.h> |
27 | #include <linux/backing-dev.h> | 27 | #include <linux/backing-dev.h> |
28 | #include <linux/bio.h> | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * Default IO end handler for temporary BJ_IO buffer_heads. | 31 | * Default IO end handler for temporary BJ_IO buffer_heads. |
@@ -137,7 +138,7 @@ static int journal_submit_commit_record(journal_t *journal, | |||
137 | set_buffer_ordered(bh); | 138 | set_buffer_ordered(bh); |
138 | barrier_done = 1; | 139 | barrier_done = 1; |
139 | } | 140 | } |
140 | ret = submit_bh(WRITE, bh); | 141 | ret = submit_bh(WRITE_SYNC, bh); |
141 | if (barrier_done) | 142 | if (barrier_done) |
142 | clear_buffer_ordered(bh); | 143 | clear_buffer_ordered(bh); |
143 | 144 | ||
@@ -158,7 +159,7 @@ static int journal_submit_commit_record(journal_t *journal, | |||
158 | lock_buffer(bh); | 159 | lock_buffer(bh); |
159 | set_buffer_uptodate(bh); | 160 | set_buffer_uptodate(bh); |
160 | clear_buffer_dirty(bh); | 161 | clear_buffer_dirty(bh); |
161 | ret = submit_bh(WRITE, bh); | 162 | ret = submit_bh(WRITE_SYNC, bh); |
162 | } | 163 | } |
163 | *cbh = bh; | 164 | *cbh = bh; |
164 | return ret; | 165 | return ret; |
@@ -168,12 +169,34 @@ static int journal_submit_commit_record(journal_t *journal, | |||
168 | * This function along with journal_submit_commit_record | 169 | * This function along with journal_submit_commit_record |
169 | * allows to write the commit record asynchronously. | 170 | * allows to write the commit record asynchronously. |
170 | */ | 171 | */ |
171 | static int journal_wait_on_commit_record(struct buffer_head *bh) | 172 | static int journal_wait_on_commit_record(journal_t *journal, |
173 | struct buffer_head *bh) | ||
172 | { | 174 | { |
173 | int ret = 0; | 175 | int ret = 0; |
174 | 176 | ||
177 | retry: | ||
175 | clear_buffer_dirty(bh); | 178 | clear_buffer_dirty(bh); |
176 | wait_on_buffer(bh); | 179 | wait_on_buffer(bh); |
180 | if (buffer_eopnotsupp(bh) && (journal->j_flags & JBD2_BARRIER)) { | ||
181 | printk(KERN_WARNING | ||
182 | "JBD2: wait_on_commit_record: sync failed on %s - " | ||
183 | "disabling barriers\n", journal->j_devname); | ||
184 | spin_lock(&journal->j_state_lock); | ||
185 | journal->j_flags &= ~JBD2_BARRIER; | ||
186 | spin_unlock(&journal->j_state_lock); | ||
187 | |||
188 | lock_buffer(bh); | ||
189 | clear_buffer_dirty(bh); | ||
190 | set_buffer_uptodate(bh); | ||
191 | bh->b_end_io = journal_end_buffer_io_sync; | ||
192 | |||
193 | ret = submit_bh(WRITE_SYNC, bh); | ||
194 | if (ret) { | ||
195 | unlock_buffer(bh); | ||
196 | return ret; | ||
197 | } | ||
198 | goto retry; | ||
199 | } | ||
177 | 200 | ||
178 | if (unlikely(!buffer_uptodate(bh))) | 201 | if (unlikely(!buffer_uptodate(bh))) |
179 | ret = -EIO; | 202 | ret = -EIO; |
@@ -332,13 +355,15 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
332 | int flags; | 355 | int flags; |
333 | int err; | 356 | int err; |
334 | unsigned long long blocknr; | 357 | unsigned long long blocknr; |
358 | ktime_t start_time; | ||
359 | u64 commit_time; | ||
335 | char *tagp = NULL; | 360 | char *tagp = NULL; |
336 | journal_header_t *header; | 361 | journal_header_t *header; |
337 | journal_block_tag_t *tag = NULL; | 362 | journal_block_tag_t *tag = NULL; |
338 | int space_left = 0; | 363 | int space_left = 0; |
339 | int first_tag = 0; | 364 | int first_tag = 0; |
340 | int tag_flag; | 365 | int tag_flag; |
341 | int i; | 366 | int i, to_free = 0; |
342 | int tag_bytes = journal_tag_bytes(journal); | 367 | int tag_bytes = journal_tag_bytes(journal); |
343 | struct buffer_head *cbh = NULL; /* For transactional checksums */ | 368 | struct buffer_head *cbh = NULL; /* For transactional checksums */ |
344 | __u32 crc32_sum = ~0; | 369 | __u32 crc32_sum = ~0; |
@@ -458,6 +483,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
458 | commit_transaction->t_state = T_FLUSH; | 483 | commit_transaction->t_state = T_FLUSH; |
459 | journal->j_committing_transaction = commit_transaction; | 484 | journal->j_committing_transaction = commit_transaction; |
460 | journal->j_running_transaction = NULL; | 485 | journal->j_running_transaction = NULL; |
486 | start_time = ktime_get(); | ||
461 | commit_transaction->t_log_start = journal->j_head; | 487 | commit_transaction->t_log_start = journal->j_head; |
462 | wake_up(&journal->j_wait_transaction_locked); | 488 | wake_up(&journal->j_wait_transaction_locked); |
463 | spin_unlock(&journal->j_state_lock); | 489 | spin_unlock(&journal->j_state_lock); |
@@ -803,7 +829,7 @@ wait_for_iobuf: | |||
803 | __jbd2_journal_abort_hard(journal); | 829 | __jbd2_journal_abort_hard(journal); |
804 | } | 830 | } |
805 | if (!err && !is_journal_aborted(journal)) | 831 | if (!err && !is_journal_aborted(journal)) |
806 | err = journal_wait_on_commit_record(cbh); | 832 | err = journal_wait_on_commit_record(journal, cbh); |
807 | 833 | ||
808 | if (err) | 834 | if (err) |
809 | jbd2_journal_abort(journal, err); | 835 | jbd2_journal_abort(journal, err); |
@@ -981,14 +1007,23 @@ restart_loop: | |||
981 | J_ASSERT(commit_transaction == journal->j_committing_transaction); | 1007 | J_ASSERT(commit_transaction == journal->j_committing_transaction); |
982 | journal->j_commit_sequence = commit_transaction->t_tid; | 1008 | journal->j_commit_sequence = commit_transaction->t_tid; |
983 | journal->j_committing_transaction = NULL; | 1009 | journal->j_committing_transaction = NULL; |
984 | spin_unlock(&journal->j_state_lock); | 1010 | commit_time = ktime_to_ns(ktime_sub(ktime_get(), start_time)); |
985 | 1011 | ||
986 | if (journal->j_commit_callback) | 1012 | /* |
987 | journal->j_commit_callback(journal, commit_transaction); | 1013 | * weight the commit time higher than the average time so we don't |
1014 | * react too strongly to vast changes in the commit time | ||
1015 | */ | ||
1016 | if (likely(journal->j_average_commit_time)) | ||
1017 | journal->j_average_commit_time = (commit_time + | ||
1018 | journal->j_average_commit_time*3) / 4; | ||
1019 | else | ||
1020 | journal->j_average_commit_time = commit_time; | ||
1021 | spin_unlock(&journal->j_state_lock); | ||
988 | 1022 | ||
989 | if (commit_transaction->t_checkpoint_list == NULL && | 1023 | if (commit_transaction->t_checkpoint_list == NULL && |
990 | commit_transaction->t_checkpoint_io_list == NULL) { | 1024 | commit_transaction->t_checkpoint_io_list == NULL) { |
991 | __jbd2_journal_drop_transaction(journal, commit_transaction); | 1025 | __jbd2_journal_drop_transaction(journal, commit_transaction); |
1026 | to_free = 1; | ||
992 | } else { | 1027 | } else { |
993 | if (journal->j_checkpoint_transactions == NULL) { | 1028 | if (journal->j_checkpoint_transactions == NULL) { |
994 | journal->j_checkpoint_transactions = commit_transaction; | 1029 | journal->j_checkpoint_transactions = commit_transaction; |
@@ -1007,11 +1042,16 @@ restart_loop: | |||
1007 | } | 1042 | } |
1008 | spin_unlock(&journal->j_list_lock); | 1043 | spin_unlock(&journal->j_list_lock); |
1009 | 1044 | ||
1045 | if (journal->j_commit_callback) | ||
1046 | journal->j_commit_callback(journal, commit_transaction); | ||
1047 | |||
1010 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", | 1048 | trace_mark(jbd2_end_commit, "dev %s transaction %d head %d", |
1011 | journal->j_devname, journal->j_commit_sequence, | 1049 | journal->j_devname, commit_transaction->t_tid, |
1012 | journal->j_tail_sequence); | 1050 | journal->j_tail_sequence); |
1013 | jbd_debug(1, "JBD: commit %d complete, head %d\n", | 1051 | jbd_debug(1, "JBD: commit %d complete, head %d\n", |
1014 | journal->j_commit_sequence, journal->j_tail_sequence); | 1052 | journal->j_commit_sequence, journal->j_tail_sequence); |
1053 | if (to_free) | ||
1054 | kfree(commit_transaction); | ||
1015 | 1055 | ||
1016 | wake_up(&journal->j_wait_done_commit); | 1056 | wake_up(&journal->j_wait_done_commit); |
1017 | } | 1057 | } |