summaryrefslogtreecommitdiff
path: root/fs/jbd2/journal.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jbd2/journal.c')
-rw-r--r--fs/jbd2/journal.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 3fbf48ec2188..efa0c72a0b9f 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1483,12 +1483,15 @@ static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
void jbd2_journal_update_sb_errno(journal_t *journal)
{
journal_superblock_t *sb = journal->j_superblock;
+ int errcode;
read_lock(&journal->j_state_lock);
- jbd_debug(1, "JBD2: updating superblock error (errno %d)\n",
- journal->j_errno);
- sb->s_errno = cpu_to_be32(journal->j_errno);
+ errcode = journal->j_errno;
read_unlock(&journal->j_state_lock);
+ if (errcode == -ESHUTDOWN)
+ errcode = 0;
+ jbd_debug(1, "JBD2: updating superblock error (errno %d)\n", errcode);
+ sb->s_errno = cpu_to_be32(errcode);
jbd2_write_superblock(journal, REQ_SYNC | REQ_FUA);
}
@@ -2105,12 +2108,22 @@ void __jbd2_journal_abort_hard(journal_t *journal)
* but don't do any other IO. */
static void __journal_abort_soft (journal_t *journal, int errno)
{
- if (journal->j_flags & JBD2_ABORT)
- return;
+ int old_errno;
- if (!journal->j_errno)
+ write_lock(&journal->j_state_lock);
+ old_errno = journal->j_errno;
+ if (!journal->j_errno || errno == -ESHUTDOWN)
journal->j_errno = errno;
+ if (journal->j_flags & JBD2_ABORT) {
+ write_unlock(&journal->j_state_lock);
+ if (!old_errno && old_errno != -ESHUTDOWN &&
+ errno == -ESHUTDOWN)
+ jbd2_journal_update_sb_errno(journal);
+ return;
+ }
+ write_unlock(&journal->j_state_lock);
+
__jbd2_journal_abort_hard(journal);
if (errno) {