Commit a1fa32d7 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] jbd: b_transaction zeroing cleanup

Almost everywhere where JBD removes a buffer from the transaction lists the
caller then nulls out jh->b_transaction.  Sometimes, the caller does that
without holding the locks which are defined to protect b_transaction.  This
makes me queazy.

So change things so that __journal_unfile_buffer() nulls out b_transaction
inside both j_list_lock and jbd_lock_bh_state().

It cleans things up a bit, too.
parent cd5f8bb0
...@@ -259,7 +259,8 @@ void journal_commit_transaction(journal_t *journal) ...@@ -259,7 +259,8 @@ void journal_commit_transaction(journal_t *journal)
if (!inverted_lock(journal, bh)) if (!inverted_lock(journal, bh))
goto write_out_data; goto write_out_data;
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
__journal_file_buffer(jh, jh->b_transaction, BJ_Locked); __journal_file_buffer(jh, commit_transaction,
BJ_Locked);
jbd_unlock_bh_state(bh); jbd_unlock_bh_state(bh);
if (need_resched()) { if (need_resched()) {
spin_unlock(&journal->j_list_lock); spin_unlock(&journal->j_list_lock);
...@@ -284,7 +285,6 @@ void journal_commit_transaction(journal_t *journal) ...@@ -284,7 +285,6 @@ void journal_commit_transaction(journal_t *journal)
if (!inverted_lock(journal, bh)) if (!inverted_lock(journal, bh))
goto write_out_data; goto write_out_data;
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = NULL;
jbd_unlock_bh_state(bh); jbd_unlock_bh_state(bh);
journal_remove_journal_head(bh); journal_remove_journal_head(bh);
put_bh(bh); put_bh(bh);
...@@ -326,7 +326,6 @@ void journal_commit_transaction(journal_t *journal) ...@@ -326,7 +326,6 @@ void journal_commit_transaction(journal_t *journal)
} }
if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) { if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) {
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = NULL;
jbd_unlock_bh_state(bh); jbd_unlock_bh_state(bh);
journal_remove_journal_head(bh); journal_remove_journal_head(bh);
put_bh(bh); put_bh(bh);
...@@ -554,13 +553,6 @@ void journal_commit_transaction(journal_t *journal) ...@@ -554,13 +553,6 @@ void journal_commit_transaction(journal_t *journal)
JBUFFER_TRACE(jh, "ph4: unfile after journal write"); JBUFFER_TRACE(jh, "ph4: unfile after journal write");
journal_unfile_buffer(journal, jh); journal_unfile_buffer(journal, jh);
/*
* akpm: don't put back a buffer_head with stale pointers
* dangling around.
*/
J_ASSERT_JH(jh, jh->b_transaction != NULL);
jh->b_transaction = NULL;
/* /*
* ->t_iobuf_list should contain only dummy buffer_heads * ->t_iobuf_list should contain only dummy buffer_heads
* which were created by journal_write_metadata_buffer(). * which were created by journal_write_metadata_buffer().
...@@ -613,7 +605,6 @@ void journal_commit_transaction(journal_t *journal) ...@@ -613,7 +605,6 @@ void journal_commit_transaction(journal_t *journal)
BUFFER_TRACE(bh, "ph5: control buffer writeout done: unfile"); BUFFER_TRACE(bh, "ph5: control buffer writeout done: unfile");
clear_buffer_jwrite(bh); clear_buffer_jwrite(bh);
journal_unfile_buffer(journal, jh); journal_unfile_buffer(journal, jh);
jh->b_transaction = NULL;
journal_put_journal_head(jh); journal_put_journal_head(jh);
__brelse(bh); /* One for getblk */ __brelse(bh); /* One for getblk */
/* AKPM: bforget here */ /* AKPM: bforget here */
...@@ -766,7 +757,6 @@ void journal_commit_transaction(journal_t *journal) ...@@ -766,7 +757,6 @@ void journal_commit_transaction(journal_t *journal)
J_ASSERT_BH(bh, !buffer_dirty(bh)); J_ASSERT_BH(bh, !buffer_dirty(bh));
J_ASSERT_JH(jh, jh->b_next_transaction == NULL); J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = 0;
jbd_unlock_bh_state(bh); jbd_unlock_bh_state(bh);
journal_remove_journal_head(bh); /* needs a brelse */ journal_remove_journal_head(bh); /* needs a brelse */
release_buffer_page(bh); release_buffer_page(bh);
......
...@@ -1038,7 +1038,6 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh) ...@@ -1038,7 +1038,6 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
if (jh->b_transaction != NULL) { if (jh->b_transaction != NULL) {
JBUFFER_TRACE(jh, "unfile from commit"); JBUFFER_TRACE(jh, "unfile from commit");
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = NULL;
} }
/* The buffer will be refiled below */ /* The buffer will be refiled below */
...@@ -1053,7 +1052,6 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh) ...@@ -1053,7 +1052,6 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
JBUFFER_TRACE(jh, "not on correct data list: unfile"); JBUFFER_TRACE(jh, "not on correct data list: unfile");
J_ASSERT_JH(jh, jh->b_jlist != BJ_Shadow); J_ASSERT_JH(jh, jh->b_jlist != BJ_Shadow);
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = NULL;
JBUFFER_TRACE(jh, "file as data"); JBUFFER_TRACE(jh, "file as data");
__journal_file_buffer(jh, handle->h_transaction, __journal_file_buffer(jh, handle->h_transaction,
BJ_SyncData); BJ_SyncData);
...@@ -1228,7 +1226,6 @@ void journal_forget(handle_t *handle, struct buffer_head *bh) ...@@ -1228,7 +1226,6 @@ void journal_forget(handle_t *handle, struct buffer_head *bh)
J_ASSERT_JH(jh, !jh->b_committed_data); J_ASSERT_JH(jh, !jh->b_committed_data);
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = 0;
/* /*
* We are no longer going to journal this buffer. * We are no longer going to journal this buffer.
...@@ -1516,7 +1513,7 @@ void __journal_unfile_buffer(struct journal_head *jh) ...@@ -1516,7 +1513,7 @@ void __journal_unfile_buffer(struct journal_head *jh)
switch (jh->b_jlist) { switch (jh->b_jlist) {
case BJ_None: case BJ_None:
return; goto out;
case BJ_SyncData: case BJ_SyncData:
list = &transaction->t_sync_datalist; list = &transaction->t_sync_datalist;
break; break;
...@@ -1549,6 +1546,8 @@ void __journal_unfile_buffer(struct journal_head *jh) ...@@ -1549,6 +1546,8 @@ void __journal_unfile_buffer(struct journal_head *jh)
jh->b_jlist = BJ_None; jh->b_jlist = BJ_None;
if (test_clear_buffer_jbddirty(bh)) if (test_clear_buffer_jbddirty(bh))
mark_buffer_dirty(bh); /* Expose it to the VM */ mark_buffer_dirty(bh); /* Expose it to the VM */
out:
jh->b_transaction = NULL;
} }
void journal_unfile_buffer(journal_t *journal, struct journal_head *jh) void journal_unfile_buffer(journal_t *journal, struct journal_head *jh)
...@@ -1584,7 +1583,6 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) ...@@ -1584,7 +1583,6 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
/* A written-back ordered data buffer */ /* A written-back ordered data buffer */
JBUFFER_TRACE(jh, "release data"); JBUFFER_TRACE(jh, "release data");
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = 0;
journal_remove_journal_head(bh); journal_remove_journal_head(bh);
__brelse(bh); __brelse(bh);
} }
...@@ -1690,7 +1688,6 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) ...@@ -1690,7 +1688,6 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction)
struct buffer_head *bh = jh2bh(jh); struct buffer_head *bh = jh2bh(jh);
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = 0;
if (jh->b_cp_transaction) { if (jh->b_cp_transaction) {
JBUFFER_TRACE(jh, "on running+cp transaction"); JBUFFER_TRACE(jh, "on running+cp transaction");
...@@ -1959,8 +1956,7 @@ void __journal_file_buffer(struct journal_head *jh, ...@@ -1959,8 +1956,7 @@ void __journal_file_buffer(struct journal_head *jh,
if (jh->b_transaction) if (jh->b_transaction)
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
else jh->b_transaction = transaction;
jh->b_transaction = transaction;
switch (jlist) { switch (jlist) {
case BJ_None: case BJ_None:
...@@ -2033,7 +2029,6 @@ void __journal_refile_buffer(struct journal_head *jh) ...@@ -2033,7 +2029,6 @@ void __journal_refile_buffer(struct journal_head *jh)
/* If the buffer is now unused, just drop it. */ /* If the buffer is now unused, just drop it. */
if (jh->b_next_transaction == NULL) { if (jh->b_next_transaction == NULL) {
__journal_unfile_buffer(jh); __journal_unfile_buffer(jh);
jh->b_transaction = NULL;
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment