Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 125872
b: refs/heads/master
c: e06c822
h: refs/heads/master
v: v3
  • Loading branch information
Joel Becker authored and Mark Fasheh committed Jan 5, 2009
1 parent 741a869 commit a4dca05
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 754938c142ae0c28360426c43f965ddc5164b21e
refs/heads/master: e06c8227fd94ec181849ba206bf032be31c4295c
9 changes: 9 additions & 0 deletions trunk/fs/jbd2/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,10 @@ void jbd2_journal_commit_transaction(journal_t *journal)
if (is_journal_aborted(journal)) {
clear_buffer_jbddirty(jh2bh(jh));
JBUFFER_TRACE(jh, "journal is aborting: refile");
jbd2_buffer_abort_trigger(jh,
jh->b_frozen_data ?
jh->b_frozen_triggers :
jh->b_triggers);
jbd2_journal_refile_buffer(journal, jh);
/* If that was the last one, we need to clean up
* any descriptor buffers which may have been
Expand Down Expand Up @@ -844,17 +848,22 @@ void jbd2_journal_commit_transaction(journal_t *journal)
* data.
*
* Otherwise, we can just throw away the frozen data now.
*
* We also know that the frozen data has already fired
* its triggers if they exist, so we can clear that too.
*/
if (jh->b_committed_data) {
jbd2_free(jh->b_committed_data, bh->b_size);
jh->b_committed_data = NULL;
if (jh->b_frozen_data) {
jh->b_committed_data = jh->b_frozen_data;
jh->b_frozen_data = NULL;
jh->b_frozen_triggers = NULL;
}
} else if (jh->b_frozen_data) {
jbd2_free(jh->b_frozen_data, bh->b_size);
jh->b_frozen_data = NULL;
jh->b_frozen_triggers = NULL;
}

spin_lock(&journal->j_list_lock);
Expand Down
19 changes: 19 additions & 0 deletions trunk/fs/jbd2/journal.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ EXPORT_SYMBOL(jbd2_journal_unlock_updates);
EXPORT_SYMBOL(jbd2_journal_get_write_access);
EXPORT_SYMBOL(jbd2_journal_get_create_access);
EXPORT_SYMBOL(jbd2_journal_get_undo_access);
EXPORT_SYMBOL(jbd2_journal_set_triggers);
EXPORT_SYMBOL(jbd2_journal_dirty_metadata);
EXPORT_SYMBOL(jbd2_journal_release_buffer);
EXPORT_SYMBOL(jbd2_journal_forget);
Expand Down Expand Up @@ -290,6 +291,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
struct page *new_page;
unsigned int new_offset;
struct buffer_head *bh_in = jh2bh(jh_in);
struct jbd2_buffer_trigger_type *triggers;

/*
* The buffer really shouldn't be locked: only the current committing
Expand All @@ -314,12 +316,22 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
done_copy_out = 1;
new_page = virt_to_page(jh_in->b_frozen_data);
new_offset = offset_in_page(jh_in->b_frozen_data);
triggers = jh_in->b_frozen_triggers;
} else {
new_page = jh2bh(jh_in)->b_page;
new_offset = offset_in_page(jh2bh(jh_in)->b_data);
triggers = jh_in->b_triggers;
}

mapped_data = kmap_atomic(new_page, KM_USER0);
/*
* Fire any commit trigger. Do this before checking for escaping,
* as the trigger may modify the magic offset. If a copy-out
* happens afterwards, it will have the correct data in the buffer.
*/
jbd2_buffer_commit_trigger(jh_in, mapped_data + new_offset,
triggers);

/*
* Check for escaping
*/
Expand Down Expand Up @@ -352,6 +364,13 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction,
new_page = virt_to_page(tmp);
new_offset = offset_in_page(tmp);
done_copy_out = 1;

/*
* This isn't strictly necessary, as we're using frozen
* data for the escaping, but it keeps consistency with
* b_frozen_data usage.
*/
jh_in->b_frozen_triggers = jh_in->b_triggers;
}

/*
Expand Down
47 changes: 47 additions & 0 deletions trunk/fs/jbd2/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,12 @@ do_get_write_access(handle_t *handle, struct journal_head *jh,
source = kmap_atomic(page, KM_USER0);
memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size);
kunmap_atomic(source, KM_USER0);

/*
* Now that the frozen data is saved off, we need to store
* any matching triggers.
*/
jh->b_frozen_triggers = jh->b_triggers;
}
jbd_unlock_bh_state(bh);

Expand Down Expand Up @@ -943,6 +949,47 @@ int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh)
return err;
}

/**
* void jbd2_journal_set_triggers() - Add triggers for commit writeout
* @bh: buffer to trigger on
* @type: struct jbd2_buffer_trigger_type containing the trigger(s).
*
* Set any triggers on this journal_head. This is always safe, because
* triggers for a committing buffer will be saved off, and triggers for
* a running transaction will match the buffer in that transaction.
*
* Call with NULL to clear the triggers.
*/
void jbd2_journal_set_triggers(struct buffer_head *bh,
struct jbd2_buffer_trigger_type *type)
{
struct journal_head *jh = bh2jh(bh);

jh->b_triggers = type;
}

void jbd2_buffer_commit_trigger(struct journal_head *jh, void *mapped_data,
struct jbd2_buffer_trigger_type *triggers)
{
struct buffer_head *bh = jh2bh(jh);

if (!triggers || !triggers->t_commit)
return;

triggers->t_commit(triggers, bh, mapped_data, bh->b_size);
}

void jbd2_buffer_abort_trigger(struct journal_head *jh,
struct jbd2_buffer_trigger_type *triggers)
{
if (!triggers || !triggers->t_abort)
return;

triggers->t_abort(triggers, jh2bh(jh));
}



/**
* int jbd2_journal_dirty_metadata() - mark a buffer as containing dirty metadata
* @handle: transaction to add buffer to.
Expand Down
31 changes: 31 additions & 0 deletions trunk/include/linux/jbd2.h
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,35 @@ int __jbd2_journal_clean_checkpoint_list(journal_t *journal);
int __jbd2_journal_remove_checkpoint(struct journal_head *);
void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *);


/*
* Triggers
*/

struct jbd2_buffer_trigger_type {
/*
* Fired just before a buffer is written to the journal.
* mapped_data is a mapped buffer that is the frozen data for
* commit.
*/
void (*t_commit)(struct jbd2_buffer_trigger_type *type,
struct buffer_head *bh, void *mapped_data,
size_t size);

/*
* Fired during journal abort for dirty buffers that will not be
* committed.
*/
void (*t_abort)(struct jbd2_buffer_trigger_type *type,
struct buffer_head *bh);
};

extern void jbd2_buffer_commit_trigger(struct journal_head *jh,
void *mapped_data,
struct jbd2_buffer_trigger_type *triggers);
extern void jbd2_buffer_abort_trigger(struct journal_head *jh,
struct jbd2_buffer_trigger_type *triggers);

/* Buffer IO */
extern int
jbd2_journal_write_metadata_buffer(transaction_t *transaction,
Expand Down Expand Up @@ -1046,6 +1075,8 @@ extern int jbd2_journal_extend (handle_t *, int nblocks);
extern int jbd2_journal_get_write_access(handle_t *, struct buffer_head *);
extern int jbd2_journal_get_create_access (handle_t *, struct buffer_head *);
extern int jbd2_journal_get_undo_access(handle_t *, struct buffer_head *);
void jbd2_journal_set_triggers(struct buffer_head *,
struct jbd2_buffer_trigger_type *type);
extern int jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *);
extern void jbd2_journal_release_buffer (handle_t *, struct buffer_head *);
extern int jbd2_journal_forget (handle_t *, struct buffer_head *);
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/linux/journal-head.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

typedef unsigned int tid_t; /* Unique transaction ID */
typedef struct transaction_s transaction_t; /* Compound transaction type */


struct buffer_head;

struct journal_head {
Expand Down Expand Up @@ -87,6 +89,12 @@ struct journal_head {
* [j_list_lock]
*/
struct journal_head *b_cpnext, *b_cpprev;

/* Trigger type */
struct jbd2_buffer_trigger_type *b_triggers;

/* Trigger type for the committing transaction's frozen data */
struct jbd2_buffer_trigger_type *b_frozen_triggers;
};

#endif /* JOURNAL_HEAD_H_INCLUDED */

0 comments on commit a4dca05

Please sign in to comment.