OSDN Git Service

f2fs: update multi-dev metadata in resize_fs
[sagit-ice-cold/kernel_xiaomi_msm8998.git] / fs / ocfs2 / journal.c
index 13534f4..2301011 100644 (file)
@@ -666,23 +666,24 @@ static int __ocfs2_journal_access(handle_t *handle,
        /* we can safely remove this assertion after testing. */
        if (!buffer_uptodate(bh)) {
                mlog(ML_ERROR, "giving me a buffer that's not uptodate!\n");
-               mlog(ML_ERROR, "b_blocknr=%llu\n",
-                    (unsigned long long)bh->b_blocknr);
+               mlog(ML_ERROR, "b_blocknr=%llu, b_state=0x%lx\n",
+                    (unsigned long long)bh->b_blocknr, bh->b_state);
 
                lock_buffer(bh);
                /*
-                * A previous attempt to write this buffer head failed.
-                * Nothing we can do but to retry the write and hope for
-                * the best.
+                * A previous transaction with a couple of buffer heads fail
+                * to checkpoint, so all the bhs are marked as BH_Write_EIO.
+                * For current transaction, the bh is just among those error
+                * bhs which previous transaction handle. We can't just clear
+                * its BH_Write_EIO and reuse directly, since other bhs are
+                * not written to disk yet and that will cause metadata
+                * inconsistency. So we should set fs read-only to avoid
+                * further damage.
                 */
                if (buffer_write_io_error(bh) && !buffer_uptodate(bh)) {
-                       clear_buffer_write_io_error(bh);
-                       set_buffer_uptodate(bh);
-               }
-
-               if (!buffer_uptodate(bh)) {
                        unlock_buffer(bh);
-                       return -EIO;
+                       return ocfs2_error(osb->sb, "A previous attempt to "
+                                       "write this buffer head failed\n");
                }
                unlock_buffer(bh);
        }
@@ -1016,7 +1017,8 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
                        mlog_errno(status);
        }
 
-       if (status == 0) {
+       /* Shutdown the kernel journal system */
+       if (!jbd2_journal_destroy(journal->j_journal) && !status) {
                /*
                 * Do not toggle if flush was unsuccessful otherwise
                 * will leave dirty metadata in a "clean" journal
@@ -1025,9 +1027,6 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
                if (status < 0)
                        mlog_errno(status);
        }
-
-       /* Shutdown the kernel journal system */
-       jbd2_journal_destroy(journal->j_journal);
        journal->j_journal = NULL;
 
        OCFS2_I(inode)->ip_open_count--;