diff options
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/commit.c | 9 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 19 | ||||
-rw-r--r-- | fs/jbd2/transaction.c | 47 |
3 files changed, 75 insertions, 0 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 073124a29b8c..62804e57a44c 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -535,6 +535,10 @@ void jbd2_journal_commit_transaction(journal_t *journal) | |||
535 | if (is_journal_aborted(journal)) { | 535 | if (is_journal_aborted(journal)) { |
536 | clear_buffer_jbddirty(jh2bh(jh)); | 536 | clear_buffer_jbddirty(jh2bh(jh)); |
537 | JBUFFER_TRACE(jh, "journal is aborting: refile"); | 537 | JBUFFER_TRACE(jh, "journal is aborting: refile"); |
538 | jbd2_buffer_abort_trigger(jh, | ||
539 | jh->b_frozen_data ? | ||
540 | jh->b_frozen_triggers : | ||
541 | jh->b_triggers); | ||
538 | jbd2_journal_refile_buffer(journal, jh); | 542 | jbd2_journal_refile_buffer(journal, jh); |
539 | /* If that was the last one, we need to clean up | 543 | /* If that was the last one, we need to clean up |
540 | * any descriptor buffers which may have been | 544 | * any descriptor buffers which may have been |
@@ -870,6 +874,9 @@ restart_loop: | |||
870 | * data. | 874 | * data. |
871 | * | 875 | * |
872 | * Otherwise, we can just throw away the frozen data now. | 876 | * Otherwise, we can just throw away the frozen data now. |
877 | * | ||
878 | * We also know that the frozen data has already fired | ||
879 | * its triggers if they exist, so we can clear that too. | ||
873 | */ | 880 | */ |
874 | if (jh->b_committed_data) { | 881 | if (jh->b_committed_data) { |
875 | jbd2_free(jh->b_committed_data, bh->b_size); | 882 | jbd2_free(jh->b_committed_data, bh->b_size); |
@@ -877,10 +884,12 @@ restart_loop: | |||
877 | if (jh->b_frozen_data) { | 884 | if (jh->b_frozen_data) { |
878 | jh->b_committed_data = jh->b_frozen_data; | 885 | jh->b_committed_data = jh->b_frozen_data; |
879 | jh->b_frozen_data = NULL; | 886 | jh->b_frozen_data = NULL; |
887 | jh->b_frozen_triggers = NULL; | ||
880 | } | 888 | } |
881 | } else if (jh->b_frozen_data) { | 889 | } else if (jh->b_frozen_data) { |
882 | jbd2_free(jh->b_frozen_data, bh->b_size); | 890 | jbd2_free(jh->b_frozen_data, bh->b_size); |
883 | jh->b_frozen_data = NULL; | 891 | jh->b_frozen_data = NULL; |
892 | jh->b_frozen_triggers = NULL; | ||
884 | } | 893 | } |
885 | 894 | ||
886 | spin_lock(&journal->j_list_lock); | 895 | spin_lock(&journal->j_list_lock); |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 2932c8f55199..56675306ed81 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -51,6 +51,7 @@ EXPORT_SYMBOL(jbd2_journal_unlock_updates); | |||
51 | EXPORT_SYMBOL(jbd2_journal_get_write_access); | 51 | EXPORT_SYMBOL(jbd2_journal_get_write_access); |
52 | EXPORT_SYMBOL(jbd2_journal_get_create_access); | 52 | EXPORT_SYMBOL(jbd2_journal_get_create_access); |
53 | EXPORT_SYMBOL(jbd2_journal_get_undo_access); | 53 | EXPORT_SYMBOL(jbd2_journal_get_undo_access); |
54 | EXPORT_SYMBOL(jbd2_journal_set_triggers); | ||
54 | EXPORT_SYMBOL(jbd2_journal_dirty_metadata); | 55 | EXPORT_SYMBOL(jbd2_journal_dirty_metadata); |
55 | EXPORT_SYMBOL(jbd2_journal_release_buffer); | 56 | EXPORT_SYMBOL(jbd2_journal_release_buffer); |
56 | EXPORT_SYMBOL(jbd2_journal_forget); | 57 | EXPORT_SYMBOL(jbd2_journal_forget); |
@@ -291,6 +292,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
291 | struct page *new_page; | 292 | struct page *new_page; |
292 | unsigned int new_offset; | 293 | unsigned int new_offset; |
293 | struct buffer_head *bh_in = jh2bh(jh_in); | 294 | struct buffer_head *bh_in = jh2bh(jh_in); |
295 | struct jbd2_buffer_trigger_type *triggers; | ||
294 | 296 | ||
295 | /* | 297 | /* |
296 | * The buffer really shouldn't be locked: only the current committing | 298 | * The buffer really shouldn't be locked: only the current committing |
@@ -315,13 +317,23 @@ repeat: | |||
315 | done_copy_out = 1; | 317 | done_copy_out = 1; |
316 | new_page = virt_to_page(jh_in->b_frozen_data); | 318 | new_page = virt_to_page(jh_in->b_frozen_data); |
317 | new_offset = offset_in_page(jh_in->b_frozen_data); | 319 | new_offset = offset_in_page(jh_in->b_frozen_data); |
320 | triggers = jh_in->b_frozen_triggers; | ||
318 | } else { | 321 | } else { |
319 | new_page = jh2bh(jh_in)->b_page; | 322 | new_page = jh2bh(jh_in)->b_page; |
320 | new_offset = offset_in_page(jh2bh(jh_in)->b_data); | 323 | new_offset = offset_in_page(jh2bh(jh_in)->b_data); |
324 | triggers = jh_in->b_triggers; | ||
321 | } | 325 | } |
322 | 326 | ||
323 | mapped_data = kmap_atomic(new_page, KM_USER0); | 327 | mapped_data = kmap_atomic(new_page, KM_USER0); |
324 | /* | 328 | /* |
329 | * Fire any commit trigger. Do this before checking for escaping, | ||
330 | * as the trigger may modify the magic offset. If a copy-out | ||
331 | * happens afterwards, it will have the correct data in the buffer. | ||
332 | */ | ||
333 | jbd2_buffer_commit_trigger(jh_in, mapped_data + new_offset, | ||
334 | triggers); | ||
335 | |||
336 | /* | ||
325 | * Check for escaping | 337 | * Check for escaping |
326 | */ | 338 | */ |
327 | if (*((__be32 *)(mapped_data + new_offset)) == | 339 | if (*((__be32 *)(mapped_data + new_offset)) == |
@@ -353,6 +365,13 @@ repeat: | |||
353 | new_page = virt_to_page(tmp); | 365 | new_page = virt_to_page(tmp); |
354 | new_offset = offset_in_page(tmp); | 366 | new_offset = offset_in_page(tmp); |
355 | done_copy_out = 1; | 367 | done_copy_out = 1; |
368 | |||
369 | /* | ||
370 | * This isn't strictly necessary, as we're using frozen | ||
371 | * data for the escaping, but it keeps consistency with | ||
372 | * b_frozen_data usage. | ||
373 | */ | ||
374 | jh_in->b_frozen_triggers = jh_in->b_triggers; | ||
356 | } | 375 | } |
357 | 376 | ||
358 | /* | 377 | /* |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 48c21bac5a56..46b4e347ed7d 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -743,6 +743,12 @@ done: | |||
743 | source = kmap_atomic(page, KM_USER0); | 743 | source = kmap_atomic(page, KM_USER0); |
744 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); | 744 | memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size); |
745 | kunmap_atomic(source, KM_USER0); | 745 | kunmap_atomic(source, KM_USER0); |
746 | |||
747 | /* | ||
748 | * Now that the frozen data is saved off, we need to store | ||
749 | * any matching triggers. | ||
750 | */ | ||
751 | jh->b_frozen_triggers = jh->b_triggers; | ||
746 | } | 752 | } |
747 | jbd_unlock_bh_state(bh); | 753 | jbd_unlock_bh_state(bh); |
748 | 754 | ||
@@ -946,6 +952,47 @@ out: | |||
946 | } | 952 | } |
947 | 953 | ||
948 | /** | 954 | /** |
955 | * void jbd2_journal_set_triggers() - Add triggers for commit writeout | ||
956 | * @bh: buffer to trigger on | ||
957 | * @type: struct jbd2_buffer_trigger_type containing the trigger(s). | ||
958 | * | ||
959 | * Set any triggers on this journal_head. This is always safe, because | ||
960 | * triggers for a committing buffer will be saved off, and triggers for | ||
961 | * a running transaction will match the buffer in that transaction. | ||
962 | * | ||
963 | * Call with NULL to clear the triggers. | ||
964 | */ | ||
965 | void jbd2_journal_set_triggers(struct buffer_head *bh, | ||
966 | struct jbd2_buffer_trigger_type *type) | ||
967 | { | ||
968 | struct journal_head *jh = bh2jh(bh); | ||
969 | |||
970 | jh->b_triggers = type; | ||
971 | } | ||
972 | |||
973 | void jbd2_buffer_commit_trigger(struct journal_head *jh, void *mapped_data, | ||
974 | struct jbd2_buffer_trigger_type *triggers) | ||
975 | { | ||
976 | struct buffer_head *bh = jh2bh(jh); | ||
977 | |||
978 | if (!triggers || !triggers->t_commit) | ||
979 | return; | ||
980 | |||
981 | triggers->t_commit(triggers, bh, mapped_data, bh->b_size); | ||
982 | } | ||
983 | |||
984 | void jbd2_buffer_abort_trigger(struct journal_head *jh, | ||
985 | struct jbd2_buffer_trigger_type *triggers) | ||
986 | { | ||
987 | if (!triggers || !triggers->t_abort) | ||
988 | return; | ||
989 | |||
990 | triggers->t_abort(triggers, jh2bh(jh)); | ||
991 | } | ||
992 | |||
993 | |||
994 | |||
995 | /** | ||
949 | * int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata | 996 | * int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata |
950 | * @handle: transaction to add buffer to. | 997 | * @handle: transaction to add buffer to. |
951 | * @bh: buffer to mark | 998 | * @bh: buffer to mark |