diff options
Diffstat (limited to 'fs/jbd2/commit.c')
-rw-r--r-- | fs/jbd2/commit.c | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 5069b8475150..806525a7269c 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/blkdev.h> | 28 | #include <linux/blkdev.h> |
29 | #include <linux/bitops.h> | 29 | #include <linux/bitops.h> |
30 | #include <trace/events/jbd2.h> | 30 | #include <trace/events/jbd2.h> |
31 | #include <asm/system.h> | ||
32 | 31 | ||
33 | /* | 32 | /* |
34 | * Default IO end handler for temporary BJ_IO buffer_heads. | 33 | * Default IO end handler for temporary BJ_IO buffer_heads. |
@@ -286,10 +285,10 @@ static __u32 jbd2_checksum_data(__u32 crc32_sum, struct buffer_head *bh) | |||
286 | char *addr; | 285 | char *addr; |
287 | __u32 checksum; | 286 | __u32 checksum; |
288 | 287 | ||
289 | addr = kmap_atomic(page, KM_USER0); | 288 | addr = kmap_atomic(page); |
290 | checksum = crc32_be(crc32_sum, | 289 | checksum = crc32_be(crc32_sum, |
291 | (void *)(addr + offset_in_page(bh->b_data)), bh->b_size); | 290 | (void *)(addr + offset_in_page(bh->b_data)), bh->b_size); |
292 | kunmap_atomic(addr, KM_USER0); | 291 | kunmap_atomic(addr); |
293 | 292 | ||
294 | return checksum; | 293 | return checksum; |
295 | } | 294 | } |
@@ -331,6 +330,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
331 | struct buffer_head *cbh = NULL; /* For transactional checksums */ | 330 | struct buffer_head *cbh = NULL; /* For transactional checksums */ |
332 | __u32 crc32_sum = ~0; | 331 | __u32 crc32_sum = ~0; |
333 | struct blk_plug plug; | 332 | struct blk_plug plug; |
333 | /* Tail of the journal */ | ||
334 | unsigned long first_block; | ||
335 | tid_t first_tid; | ||
336 | int update_tail; | ||
334 | 337 | ||
335 | /* | 338 | /* |
336 | * First job: lock down the current transaction and wait for | 339 | * First job: lock down the current transaction and wait for |
@@ -340,7 +343,18 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
340 | /* Do we need to erase the effects of a prior jbd2_journal_flush? */ | 343 | /* Do we need to erase the effects of a prior jbd2_journal_flush? */ |
341 | if (journal->j_flags & JBD2_FLUSHED) { | 344 | if (journal->j_flags & JBD2_FLUSHED) { |
342 | jbd_debug(3, "super block updated\n"); | 345 | jbd_debug(3, "super block updated\n"); |
343 | jbd2_journal_update_superblock(journal, 1); | 346 | mutex_lock(&journal->j_checkpoint_mutex); |
347 | /* | ||
348 | * We hold j_checkpoint_mutex so tail cannot change under us. | ||
349 | * We don't need any special data guarantees for writing sb | ||
350 | * since journal is empty and it is ok for write to be | ||
351 | * flushed only with transaction commit. | ||
352 | */ | ||
353 | jbd2_journal_update_sb_log_tail(journal, | ||
354 | journal->j_tail_sequence, | ||
355 | journal->j_tail, | ||
356 | WRITE_SYNC); | ||
357 | mutex_unlock(&journal->j_checkpoint_mutex); | ||
344 | } else { | 358 | } else { |
345 | jbd_debug(3, "superblock not updated\n"); | 359 | jbd_debug(3, "superblock not updated\n"); |
346 | } | 360 | } |
@@ -677,10 +691,30 @@ start_journal_io: | |||
677 | err = 0; | 691 | err = 0; |
678 | } | 692 | } |
679 | 693 | ||
694 | /* | ||
695 | * Get current oldest transaction in the log before we issue flush | ||
696 | * to the filesystem device. After the flush we can be sure that | ||
697 | * blocks of all older transactions are checkpointed to persistent | ||
698 | * storage and we will be safe to update journal start in the | ||
699 | * superblock with the numbers we get here. | ||
700 | */ | ||
701 | update_tail = | ||
702 | jbd2_journal_get_log_tail(journal, &first_tid, &first_block); | ||
703 | |||
680 | write_lock(&journal->j_state_lock); | 704 | write_lock(&journal->j_state_lock); |
705 | if (update_tail) { | ||
706 | long freed = first_block - journal->j_tail; | ||
707 | |||
708 | if (first_block < journal->j_tail) | ||
709 | freed += journal->j_last - journal->j_first; | ||
710 | /* Update tail only if we free significant amount of space */ | ||
711 | if (freed < journal->j_maxlen / 4) | ||
712 | update_tail = 0; | ||
713 | } | ||
681 | J_ASSERT(commit_transaction->t_state == T_COMMIT); | 714 | J_ASSERT(commit_transaction->t_state == T_COMMIT); |
682 | commit_transaction->t_state = T_COMMIT_DFLUSH; | 715 | commit_transaction->t_state = T_COMMIT_DFLUSH; |
683 | write_unlock(&journal->j_state_lock); | 716 | write_unlock(&journal->j_state_lock); |
717 | |||
684 | /* | 718 | /* |
685 | * If the journal is not located on the file system device, | 719 | * If the journal is not located on the file system device, |
686 | * then we must flush the file system device before we issue | 720 | * then we must flush the file system device before we issue |
@@ -831,6 +865,14 @@ wait_for_iobuf: | |||
831 | if (err) | 865 | if (err) |
832 | jbd2_journal_abort(journal, err); | 866 | jbd2_journal_abort(journal, err); |
833 | 867 | ||
868 | /* | ||
869 | * Now disk caches for filesystem device are flushed so we are safe to | ||
870 | * erase checkpointed transactions from the log by updating journal | ||
871 | * superblock. | ||
872 | */ | ||
873 | if (update_tail) | ||
874 | jbd2_update_log_tail(journal, first_tid, first_block); | ||
875 | |||
834 | /* End of a transaction! Finally, we can do checkpoint | 876 | /* End of a transaction! Finally, we can do checkpoint |
835 | processing: any buffers committed as a result of this | 877 | processing: any buffers committed as a result of this |
836 | transaction can be removed from any checkpoint list it was on | 878 | transaction can be removed from any checkpoint list it was on |
@@ -1048,7 +1090,7 @@ restart_loop: | |||
1048 | jbd_debug(1, "JBD2: commit %d complete, head %d\n", | 1090 | jbd_debug(1, "JBD2: commit %d complete, head %d\n", |
1049 | journal->j_commit_sequence, journal->j_tail_sequence); | 1091 | journal->j_commit_sequence, journal->j_tail_sequence); |
1050 | if (to_free) | 1092 | if (to_free) |
1051 | kfree(commit_transaction); | 1093 | jbd2_journal_free_transaction(commit_transaction); |
1052 | 1094 | ||
1053 | wake_up(&journal->j_wait_done_commit); | 1095 | wake_up(&journal->j_wait_done_commit); |
1054 | } | 1096 | } |