summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorJoseph Qi <joseph.qi@huawei.com>2015-06-15 14:36:01 -0400
committerBen Hutchings <ben@decadent.org.uk>2015-08-12 16:33:15 +0200
commit9c7fafb9e156840cc352ba5cdd2145baea835de4 (patch)
tree24d1a76d7c54e85a5feca43eeadb290f1e27b511 /include/linux
parent6e94fd8d05090f570c2718331f12b24bf86162cb (diff)
downloadlwn-9c7fafb9e156840cc352ba5cdd2145baea835de4.tar.gz
lwn-9c7fafb9e156840cc352ba5cdd2145baea835de4.zip
jbd2: fix ocfs2 corrupt when updating journal superblock fails
commit 6f6a6fda294506dfe0e3e0a253bb2d2923f28f0a upstream. If updating journal superblock fails after journal data has been flushed, the error is omitted and this will mislead the caller as a normal case. In ocfs2, the checkpoint will be treated successfully and the other node can get the lock to update. Since the sb_start is still pointing to the old log block, it will rewrite the journal data during journal recovery by the other node. Thus the new updates will be overwritten and ocfs2 corrupts. So in above case we have to return the error, and ocfs2_commit_cache will take care of the error and prevent the other node to do update first. And only after recovering journal it can do the new updates. The issue discussion mail can be found at: https://oss.oracle.com/pipermail/ocfs2-devel/2015-June/010856.html http://comments.gmane.org/gmane.comp.file-systems.ext4/48841 [ Fixed bug in patch which allowed a non-negative error return from jbd2_cleanup_journal_tail() to leak out of jbd2_fjournal_flush(); this was causing xfstests ext4/306 to fail. -- Ted ] Reported-by: Yiwen Jiang <jiangyiwen@huawei.com> Signed-off-by: Joseph Qi <joseph.qi@huawei.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu> Tested-by: Yiwen Jiang <jiangyiwen@huawei.com> Cc: Junxiao Bi <junxiao.bi@oracle.com> [bwh: Backported to 3.2: - Adjust context - Don't drop j_checkpoint_mutex where we don't hold it] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/jbd2.h4
1 files changed, 2 insertions, 2 deletions
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 5e29682c4508..4920c55c7625 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -974,7 +974,7 @@ extern struct journal_head * jbd2_journal_get_descriptor_buffer(journal_t *);
int jbd2_journal_next_log_block(journal_t *, unsigned long long *);
int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid,
unsigned long *block);
-void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block);
+int __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block);
/* Commit management */
extern void jbd2_journal_commit_transaction(journal_t *);
@@ -1086,7 +1086,7 @@ extern int jbd2_journal_destroy (journal_t *);
extern int jbd2_journal_recover (journal_t *journal);
extern int jbd2_journal_wipe (journal_t *, int);
extern int jbd2_journal_skip_recovery (journal_t *);
-extern void jbd2_journal_update_sb_log_tail (journal_t *, tid_t,
+extern int jbd2_journal_update_sb_log_tail (journal_t *, tid_t,
unsigned long, int);
extern void __jbd2_journal_abort_hard (journal_t *);
extern void jbd2_journal_abort (journal_t *, int);