|
@@ -490,23 +490,21 @@ void journal_unlock_updates (journal_t *journal)
|
|
|
*/
|
|
|
static void jbd_unexpected_dirty_buffer(struct journal_head *jh)
|
|
|
{
|
|
|
- struct buffer_head *bh = jh2bh(jh);
|
|
|
int jlist;
|
|
|
|
|
|
- if (buffer_dirty(bh)) {
|
|
|
- /* If this buffer is one which might reasonably be dirty
|
|
|
- * --- ie. data, or not part of this journal --- then
|
|
|
- * we're OK to leave it alone, but otherwise we need to
|
|
|
- * move the dirty bit to the journal's own internal
|
|
|
- * JBDDirty bit. */
|
|
|
- jlist = jh->b_jlist;
|
|
|
-
|
|
|
- if (jlist == BJ_Metadata || jlist == BJ_Reserved ||
|
|
|
- jlist == BJ_Shadow || jlist == BJ_Forget) {
|
|
|
- if (test_clear_buffer_dirty(jh2bh(jh))) {
|
|
|
- set_bit(BH_JBDDirty, &jh2bh(jh)->b_state);
|
|
|
- }
|
|
|
- }
|
|
|
+ /* If this buffer is one which might reasonably be dirty
|
|
|
+ * --- ie. data, or not part of this journal --- then
|
|
|
+ * we're OK to leave it alone, but otherwise we need to
|
|
|
+ * move the dirty bit to the journal's own internal
|
|
|
+ * JBDDirty bit. */
|
|
|
+ jlist = jh->b_jlist;
|
|
|
+
|
|
|
+ if (jlist == BJ_Metadata || jlist == BJ_Reserved ||
|
|
|
+ jlist == BJ_Shadow || jlist == BJ_Forget) {
|
|
|
+ struct buffer_head *bh = jh2bh(jh);
|
|
|
+
|
|
|
+ if (test_clear_buffer_dirty(bh))
|
|
|
+ set_buffer_jbddirty(bh);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -574,9 +572,14 @@ repeat:
|
|
|
if (jh->b_next_transaction)
|
|
|
J_ASSERT_JH(jh, jh->b_next_transaction ==
|
|
|
transaction);
|
|
|
- JBUFFER_TRACE(jh, "Unexpected dirty buffer");
|
|
|
- jbd_unexpected_dirty_buffer(jh);
|
|
|
- }
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * In any case we need to clean the dirty flag and we must
|
|
|
+ * do it under the buffer lock to be sure we don't race
|
|
|
+ * with running write-out.
|
|
|
+ */
|
|
|
+ JBUFFER_TRACE(jh, "Unexpected dirty buffer");
|
|
|
+ jbd_unexpected_dirty_buffer(jh);
|
|
|
}
|
|
|
|
|
|
unlock_buffer(bh);
|