aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2012-04-07 05:05:19 -0400
committerJan Kara <jack@suse.cz>2012-05-15 17:34:37 -0400
commitfd2cbd4dfa3db477dd6226d387d3f1911d36a6a9 (patch)
treeb0ada946d14cdcf5db6da2d177be9590a3449e9a /include
parent1ce8486dcc00c1e095af8d155fa4451936b89013 (diff)
jbd: Write journal superblock with WRITE_FUA after checkpointing
If journal superblock is written only in disk's caches and other transaction starts reusing space of the transaction cleaned from the log, it can happen blocks of a new transaction reach the disk before journal superblock. When power failure happens in such case, subsequent journal replay would still try to replay the old transaction but some of it's blocks may be already overwritten by the new transaction. For this reason we must use WRITE_FUA when updating log tail and we must first write new log tail to disk and update in-memory information only after that. Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'include')
-rw-r--r--include/linux/jbd.h3
-rw-r--r--include/trace/events/jbd.h9
2 files changed, 8 insertions, 4 deletions
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 9716d370c501..c8f32975f0e4 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -864,7 +864,8 @@ extern int journal_destroy (journal_t *);
864extern int journal_recover (journal_t *journal); 864extern int journal_recover (journal_t *journal);
865extern int journal_wipe (journal_t *, int); 865extern int journal_wipe (journal_t *, int);
866extern int journal_skip_recovery (journal_t *); 866extern int journal_skip_recovery (journal_t *);
867extern void journal_update_sb_log_tail (journal_t *); 867extern void journal_update_sb_log_tail (journal_t *, tid_t, unsigned int,
868 int);
868extern void journal_abort (journal_t *, int); 869extern void journal_abort (journal_t *, int);
869extern int journal_errno (journal_t *); 870extern int journal_errno (journal_t *);
870extern void journal_ack_err (journal_t *); 871extern void journal_ack_err (journal_t *);
diff --git a/include/trace/events/jbd.h b/include/trace/events/jbd.h
index d9658a940a39..da6f2591c25e 100644
--- a/include/trace/events/jbd.h
+++ b/include/trace/events/jbd.h
@@ -170,19 +170,22 @@ TRACE_EVENT(jbd_cleanup_journal_tail,
170); 170);
171 171
172TRACE_EVENT(journal_write_superblock, 172TRACE_EVENT(journal_write_superblock,
173 TP_PROTO(journal_t *journal), 173 TP_PROTO(journal_t *journal, int write_op),
174 174
175 TP_ARGS(journal), 175 TP_ARGS(journal, write_op),
176 176
177 TP_STRUCT__entry( 177 TP_STRUCT__entry(
178 __field( dev_t, dev ) 178 __field( dev_t, dev )
179 __field( int, write_op )
179 ), 180 ),
180 181
181 TP_fast_assign( 182 TP_fast_assign(
182 __entry->dev = journal->j_fs_dev->bd_dev; 183 __entry->dev = journal->j_fs_dev->bd_dev;
184 __entry->write_op = write_op;
183 ), 185 ),
184 186
185 TP_printk("dev %d,%d", MAJOR(__entry->dev), MINOR(__entry->dev)) 187 TP_printk("dev %d,%d write_op %x", MAJOR(__entry->dev),
188 MINOR(__entry->dev), __entry->write_op)
186); 189);
187 190
188#endif /* _TRACE_JBD_H */ 191#endif /* _TRACE_JBD_H */