aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jbd2
diff options
context:
space:
mode:
authorJoseph Qi <joseph.qi@huawei.com>2015-06-15 14:36:01 -0400
committerTheodore Ts'o <tytso@mit.edu>2015-06-15 14:36:01 -0400
commit6f6a6fda294506dfe0e3e0a253bb2d2923f28f0a (patch)
tree9d91d475286c7169d37f38cb4a8afcdcbab9cd48 /fs/jbd2
parent97b4af2f7672476eedeb5cf5000b927ed4b516a4 (diff)
jbd2: fix ocfs2 corrupt when updating journal superblock fails
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> Cc: stable@vger.kernel.org
Diffstat (limited to 'fs/jbd2')
-rw-r--r--fs/jbd2/checkpoint.c5
-rw-r--r--fs/jbd2/journal.c38
2 files changed, 33 insertions, 10 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 6b7b73afef81..4227dc4f7437 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -390,7 +390,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal)
390 unsigned long blocknr; 390 unsigned long blocknr;
391 391
392 if (is_journal_aborted(journal)) 392 if (is_journal_aborted(journal))
393 return 1; 393 return -EIO;
394 394
395 if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr)) 395 if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr))
396 return 1; 396 return 1;
@@ -407,8 +407,7 @@ int jbd2_cleanup_journal_tail(journal_t *journal)
407 if (journal->j_flags & JBD2_BARRIER) 407 if (journal->j_flags & JBD2_BARRIER)
408 blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL); 408 blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL);
409 409
410 __jbd2_update_log_tail(journal, first_tid, blocknr); 410 return __jbd2_update_log_tail(journal, first_tid, blocknr);
411 return 0;
412} 411}
413 412
414 413
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 303ccd953e95..5804466b5785 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -876,9 +876,10 @@ int jbd2_journal_get_log_tail(journal_t *journal, tid_t *tid,
876 * 876 *
877 * Requires j_checkpoint_mutex 877 * Requires j_checkpoint_mutex
878 */ 878 */
879void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block) 879int __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block)
880{ 880{
881 unsigned long freed; 881 unsigned long freed;
882 int ret;
882 883
883 BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); 884 BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
884 885
@@ -888,7 +889,10 @@ void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block)
888 * space and if we lose sb update during power failure we'd replay 889 * space and if we lose sb update during power failure we'd replay
889 * old transaction with possibly newly overwritten data. 890 * old transaction with possibly newly overwritten data.
890 */ 891 */
891 jbd2_journal_update_sb_log_tail(journal, tid, block, WRITE_FUA); 892 ret = jbd2_journal_update_sb_log_tail(journal, tid, block, WRITE_FUA);
893 if (ret)
894 goto out;
895
892 write_lock(&journal->j_state_lock); 896 write_lock(&journal->j_state_lock);
893 freed = block - journal->j_tail; 897 freed = block - journal->j_tail;
894 if (block < journal->j_tail) 898 if (block < journal->j_tail)
@@ -904,6 +908,9 @@ void __jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block)
904 journal->j_tail_sequence = tid; 908 journal->j_tail_sequence = tid;
905 journal->j_tail = block; 909 journal->j_tail = block;
906 write_unlock(&journal->j_state_lock); 910 write_unlock(&journal->j_state_lock);
911
912out:
913 return ret;
907} 914}
908 915
909/* 916/*
@@ -1322,7 +1329,7 @@ static int journal_reset(journal_t *journal)
1322 return jbd2_journal_start_thread(journal); 1329 return jbd2_journal_start_thread(journal);
1323} 1330}
1324 1331
1325static void jbd2_write_superblock(journal_t *journal, int write_op) 1332static int jbd2_write_superblock(journal_t *journal, int write_op)
1326{ 1333{
1327 struct buffer_head *bh = journal->j_sb_buffer; 1334 struct buffer_head *bh = journal->j_sb_buffer;
1328 journal_superblock_t *sb = journal->j_superblock; 1335 journal_superblock_t *sb = journal->j_superblock;
@@ -1361,7 +1368,10 @@ static void jbd2_write_superblock(journal_t *journal, int write_op)
1361 printk(KERN_ERR "JBD2: Error %d detected when updating " 1368 printk(KERN_ERR "JBD2: Error %d detected when updating "
1362 "journal superblock for %s.\n", ret, 1369 "journal superblock for %s.\n", ret,
1363 journal->j_devname); 1370 journal->j_devname);
1371 jbd2_journal_abort(journal, ret);
1364 } 1372 }
1373
1374 return ret;
1365} 1375}
1366 1376
1367/** 1377/**
@@ -1374,10 +1384,11 @@ static void jbd2_write_superblock(journal_t *journal, int write_op)
1374 * Update a journal's superblock information about log tail and write it to 1384 * Update a journal's superblock information about log tail and write it to
1375 * disk, waiting for the IO to complete. 1385 * disk, waiting for the IO to complete.
1376 */ 1386 */
1377void jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid, 1387int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
1378 unsigned long tail_block, int write_op) 1388 unsigned long tail_block, int write_op)
1379{ 1389{
1380 journal_superblock_t *sb = journal->j_superblock; 1390 journal_superblock_t *sb = journal->j_superblock;
1391 int ret;
1381 1392
1382 BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex)); 1393 BUG_ON(!mutex_is_locked(&journal->j_checkpoint_mutex));
1383 jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n", 1394 jbd_debug(1, "JBD2: updating superblock (start %lu, seq %u)\n",
@@ -1386,13 +1397,18 @@ void jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
1386 sb->s_sequence = cpu_to_be32(tail_tid); 1397 sb->s_sequence = cpu_to_be32(tail_tid);
1387 sb->s_start = cpu_to_be32(tail_block); 1398 sb->s_start = cpu_to_be32(tail_block);
1388 1399
1389 jbd2_write_superblock(journal, write_op); 1400 ret = jbd2_write_superblock(journal, write_op);
1401 if (ret)
1402 goto out;
1390 1403
1391 /* Log is no longer empty */ 1404 /* Log is no longer empty */
1392 write_lock(&journal->j_state_lock); 1405 write_lock(&journal->j_state_lock);
1393 WARN_ON(!sb->s_sequence); 1406 WARN_ON(!sb->s_sequence);
1394 journal->j_flags &= ~JBD2_FLUSHED; 1407 journal->j_flags &= ~JBD2_FLUSHED;
1395 write_unlock(&journal->j_state_lock); 1408 write_unlock(&journal->j_state_lock);
1409
1410out:
1411 return ret;
1396} 1412}
1397 1413
1398/** 1414/**
@@ -1941,7 +1957,14 @@ int jbd2_journal_flush(journal_t *journal)
1941 return -EIO; 1957 return -EIO;
1942 1958
1943 mutex_lock(&journal->j_checkpoint_mutex); 1959 mutex_lock(&journal->j_checkpoint_mutex);
1944 jbd2_cleanup_journal_tail(journal); 1960 if (!err) {
1961 err = jbd2_cleanup_journal_tail(journal);
1962 if (err < 0) {
1963 mutex_unlock(&journal->j_checkpoint_mutex);
1964 goto out;
1965 }
1966 err = 0;
1967 }
1945 1968
1946 /* Finally, mark the journal as really needing no recovery. 1969 /* Finally, mark the journal as really needing no recovery.
1947 * This sets s_start==0 in the underlying superblock, which is 1970 * This sets s_start==0 in the underlying superblock, which is
@@ -1957,7 +1980,8 @@ int jbd2_journal_flush(journal_t *journal)
1957 J_ASSERT(journal->j_head == journal->j_tail); 1980 J_ASSERT(journal->j_head == journal->j_tail);
1958 J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence); 1981 J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence);
1959 write_unlock(&journal->j_state_lock); 1982 write_unlock(&journal->j_state_lock);
1960 return 0; 1983out:
1984 return err;
1961} 1985}
1962 1986
1963/** 1987/**