aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd2')
-rw-r--r--fs/jbd2/commit.c9
-rw-r--r--fs/jbd2/journal.c19
-rw-r--r--fs/jbd2/transaction.c47
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);
51EXPORT_SYMBOL(jbd2_journal_get_write_access); 51EXPORT_SYMBOL(jbd2_journal_get_write_access);
52EXPORT_SYMBOL(jbd2_journal_get_create_access); 52EXPORT_SYMBOL(jbd2_journal_get_create_access);
53EXPORT_SYMBOL(jbd2_journal_get_undo_access); 53EXPORT_SYMBOL(jbd2_journal_get_undo_access);
54EXPORT_SYMBOL(jbd2_journal_set_triggers);
54EXPORT_SYMBOL(jbd2_journal_dirty_metadata); 55EXPORT_SYMBOL(jbd2_journal_dirty_metadata);
55EXPORT_SYMBOL(jbd2_journal_release_buffer); 56EXPORT_SYMBOL(jbd2_journal_release_buffer);
56EXPORT_SYMBOL(jbd2_journal_forget); 57EXPORT_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 */
965void 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
973void 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
984void 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