diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 0d0c70151642faf026c98d53b4179c6395e1b645..b7394d05ee8e9e8261d2a6e8be983b83781d2211 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c @@ -239,7 +239,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, case EXT3_IOC_GROUP_EXTEND: { ext3_fsblk_t n_blocks_count; struct super_block *sb = inode->i_sb; - int err; + int err, err2; if (!capable(CAP_SYS_RESOURCE)) return -EPERM; @@ -254,8 +254,10 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, } err = ext3_group_extend(sb, EXT3_SB(sb)->s_es, n_blocks_count); journal_lock_updates(EXT3_SB(sb)->s_journal); - journal_flush(EXT3_SB(sb)->s_journal); + err2 = journal_flush(EXT3_SB(sb)->s_journal); journal_unlock_updates(EXT3_SB(sb)->s_journal); + if (err == 0) + err = err2; group_extend_out: mnt_drop_write(filp->f_path.mnt); return err; @@ -263,7 +265,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, case EXT3_IOC_GROUP_ADD: { struct ext3_new_group_data input; struct super_block *sb = inode->i_sb; - int err; + int err, err2; if (!capable(CAP_SYS_RESOURCE)) return -EPERM; @@ -280,8 +282,10 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, err = ext3_group_add(sb, &input); journal_lock_updates(EXT3_SB(sb)->s_journal); - journal_flush(EXT3_SB(sb)->s_journal); + err2 = journal_flush(EXT3_SB(sb)->s_journal); journal_unlock_updates(EXT3_SB(sb)->s_journal); + if (err == 0) + err = err2; group_add_out: mnt_drop_write(filp->f_path.mnt); return err; diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 3a260af5544d24dfc85f0dffc03b42771c322295..cac29ee3b14ab62054b6f45d74f36adaecab5200 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -393,7 +393,8 @@ static void ext3_put_super (struct super_block * sb) int i; ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); + if (journal_destroy(sbi->s_journal) < 0) + ext3_abort(sb, __func__, "Couldn't clean up the journal"); if (!(sb->s_flags & MS_RDONLY)) { EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); es->s_state = cpu_to_le16(sbi->s_mount_state); @@ -2296,7 +2297,9 @@ static void ext3_mark_recovery_complete(struct super_block * sb, journal_t *journal = EXT3_SB(sb)->s_journal; journal_lock_updates(journal); - journal_flush(journal); + if (journal_flush(journal) < 0) + goto out; + lock_super(sb); if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER) && sb->s_flags & MS_RDONLY) { @@ -2305,6 +2308,8 @@ static void ext3_mark_recovery_complete(struct super_block * sb, ext3_commit_super(sb, es, 1); } unlock_super(sb); + +out: journal_unlock_updates(journal); } @@ -2404,7 +2409,13 @@ static void ext3_write_super_lockfs(struct super_block *sb) /* Now we set up the journal barrier. */ journal_lock_updates(journal); - journal_flush(journal); + + /* + * We don't want to clear needs_recovery flag when we failed + * to flush the journal. + */ + if (journal_flush(journal) < 0) + return; /* Journal blocked and flushed, clear needs_recovery flag. */ EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); @@ -2822,8 +2833,12 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, * otherwise be livelocked... */ journal_lock_updates(EXT3_SB(sb)->s_journal); - journal_flush(EXT3_SB(sb)->s_journal); + err = journal_flush(EXT3_SB(sb)->s_journal); journal_unlock_updates(EXT3_SB(sb)->s_journal); + if (err) { + path_put(&nd.path); + return err; + } } err = vfs_quota_on_path(sb, type, format_id, &nd.path);