aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-09-11 18:35:47 -0400
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:30 -0500
commite06c8227fd94ec181849ba206bf032be31c4295c (patch)
tree67261cd94aa86dc6112d7de74304c2a1af5b64fb /include/linux
parent754938c142ae0c28360426c43f965ddc5164b21e (diff)
jbd2: Add buffer triggers
Filesystems often to do compute intensive operation on some metadata. If this operation is repeated many times, it can be very expensive. It would be much nicer if the operation could be performed once before a buffer goes to disk. This adds triggers to jbd2 buffer heads. Just before writing a metadata buffer to the journal, jbd2 will optionally call a commit trigger associated with the buffer. If the journal is aborted, an abort trigger will be called on any dirty buffers as they are dropped from pending transactions. ocfs2 will use this feature. Initially I tried to come up with a more generic trigger that could be used for non-buffer-related events like transaction completion. It doesn't tie nicely, because the information a buffer trigger needs (specific to a journal_head) isn't the same as what a transaction trigger needs (specific to a tranaction_t or perhaps journal_t). So I implemented a buffer set, with the understanding that journal/transaction wide triggers should be implemented separately. There is only one trigger set allowed per buffer. I can't think of any reason to attach more than one set. Contrast this with a journal or transaction in which multiple places may want to watch the entire transaction separately. The trigger sets are considered static allocation from the jbd2 perspective. ocfs2 will just have one trigger set per block type, setting the same set on every bh of the same type. Signed-off-by: Joel Becker <joel.becker@oracle.com> Cc: "Theodore Ts'o" <tytso@mit.edu> Cc: <linux-ext4@vger.kernel.org> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/jbd2.h31
-rw-r--r--include/linux/journal-head.h8
2 files changed, 39 insertions, 0 deletions
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index f36645745489..34456476e761 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1008,6 +1008,35 @@ int __jbd2_journal_clean_checkpoint_list(journal_t *journal);
1008int __jbd2_journal_remove_checkpoint(struct journal_head *); 1008int __jbd2_journal_remove_checkpoint(struct journal_head *);
1009void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *); 1009void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *);
1010 1010
1011
1012/*
1013 * Triggers
1014 */
1015
1016struct jbd2_buffer_trigger_type {
1017 /*
1018 * Fired just before a buffer is written to the journal.
1019 * mapped_data is a mapped buffer that is the frozen data for
1020 * commit.
1021 */
1022 void (*t_commit)(struct jbd2_buffer_trigger_type *type,
1023 struct buffer_head *bh, void *mapped_data,
1024 size_t size);
1025
1026 /*
1027 * Fired during journal abort for dirty buffers that will not be
1028 * committed.
1029 */
1030 void (*t_abort)(struct jbd2_buffer_trigger_type *type,
1031 struct buffer_head *bh);
1032};
1033
1034extern void jbd2_buffer_commit_trigger(struct journal_head *jh,
1035 void *mapped_data,
1036 struct jbd2_buffer_trigger_type *triggers);
1037extern void jbd2_buffer_abort_trigger(struct journal_head *jh,
1038 struct jbd2_buffer_trigger_type *triggers);
1039
1011/* Buffer IO */ 1040/* Buffer IO */
1012extern int 1041extern int
1013jbd2_journal_write_metadata_buffer(transaction_t *transaction, 1042jbd2_journal_write_metadata_buffer(transaction_t *transaction,
@@ -1046,6 +1075,8 @@ extern int jbd2_journal_extend (handle_t *, int nblocks);
1046extern int jbd2_journal_get_write_access(handle_t *, struct buffer_head *); 1075extern int jbd2_journal_get_write_access(handle_t *, struct buffer_head *);
1047extern int jbd2_journal_get_create_access (handle_t *, struct buffer_head *); 1076extern int jbd2_journal_get_create_access (handle_t *, struct buffer_head *);
1048extern int jbd2_journal_get_undo_access(handle_t *, struct buffer_head *); 1077extern int jbd2_journal_get_undo_access(handle_t *, struct buffer_head *);
1078void jbd2_journal_set_triggers(struct buffer_head *,
1079 struct jbd2_buffer_trigger_type *type);
1049extern int jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *); 1080extern int jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *);
1050extern void jbd2_journal_release_buffer (handle_t *, struct buffer_head *); 1081extern void jbd2_journal_release_buffer (handle_t *, struct buffer_head *);
1051extern int jbd2_journal_forget (handle_t *, struct buffer_head *); 1082extern int jbd2_journal_forget (handle_t *, struct buffer_head *);
diff --git a/include/linux/journal-head.h b/include/linux/journal-head.h
index bb70ebb6a2d5..525aac3c97df 100644
--- a/include/linux/journal-head.h
+++ b/include/linux/journal-head.h
@@ -12,6 +12,8 @@
12 12
13typedef unsigned int tid_t; /* Unique transaction ID */ 13typedef unsigned int tid_t; /* Unique transaction ID */
14typedef struct transaction_s transaction_t; /* Compound transaction type */ 14typedef struct transaction_s transaction_t; /* Compound transaction type */
15
16
15struct buffer_head; 17struct buffer_head;
16 18
17struct journal_head { 19struct journal_head {
@@ -87,6 +89,12 @@ struct journal_head {
87 * [j_list_lock] 89 * [j_list_lock]
88 */ 90 */
89 struct journal_head *b_cpnext, *b_cpprev; 91 struct journal_head *b_cpnext, *b_cpprev;
92
93 /* Trigger type */
94 struct jbd2_buffer_trigger_type *b_triggers;
95
96 /* Trigger type for the committing transaction's frozen data */
97 struct jbd2_buffer_trigger_type *b_frozen_triggers;
90}; 98};
91 99
92#endif /* JOURNAL_HEAD_H_INCLUDED */ 100#endif /* JOURNAL_HEAD_H_INCLUDED */