]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ext3/super.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[linux-2.6-omap-h63xx.git] / fs / ext3 / super.c
index 399a96a6c5561666f61c7a8f7cae3a71dbc5b52f..34b6fca765d725fdf60f0d0ee7e924a0927f39c4 100644 (file)
@@ -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);
@@ -625,6 +626,9 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
        else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
                seq_puts(seq, ",data=writeback");
 
+       if (test_opt(sb, DATA_ERR_ABORT))
+               seq_puts(seq, ",data_err=abort");
+
        ext3_show_quota_options(seq, sb);
 
        return 0;
@@ -754,6 +758,7 @@ enum {
        Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,
        Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
        Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
+       Opt_data_err_abort, Opt_data_err_ignore,
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
        Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
        Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
@@ -796,6 +801,8 @@ static const match_table_t tokens = {
        {Opt_data_journal, "data=journal"},
        {Opt_data_ordered, "data=ordered"},
        {Opt_data_writeback, "data=writeback"},
+       {Opt_data_err_abort, "data_err=abort"},
+       {Opt_data_err_ignore, "data_err=ignore"},
        {Opt_offusrjquota, "usrjquota="},
        {Opt_usrjquota, "usrjquota=%s"},
        {Opt_offgrpjquota, "grpjquota="},
@@ -1011,6 +1018,12 @@ static int parse_options (char *options, struct super_block *sb,
                                sbi->s_mount_opt |= data_opt;
                        }
                        break;
+               case Opt_data_err_abort:
+                       set_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
+                       break;
+               case Opt_data_err_ignore:
+                       clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
+                       break;
 #ifdef CONFIG_QUOTA
                case Opt_usrjquota:
                        qtype = USRQUOTA;
@@ -1986,6 +1999,10 @@ static void ext3_init_journal_params(struct super_block *sb, journal_t *journal)
                journal->j_flags |= JFS_BARRIER;
        else
                journal->j_flags &= ~JFS_BARRIER;
+       if (test_opt(sb, DATA_ERR_ABORT))
+               journal->j_flags |= JFS_ABORT_ON_SYNCDATA_ERR;
+       else
+               journal->j_flags &= ~JFS_ABORT_ON_SYNCDATA_ERR;
        spin_unlock(&journal->j_state_lock);
 }
 
@@ -2280,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) {
@@ -2289,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);
 }
 
@@ -2388,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);
@@ -2767,30 +2794,30 @@ static int ext3_quota_on_mount(struct super_block *sb, int type)
  * Standard function to be called on quota_on
  */
 static int ext3_quota_on(struct super_block *sb, int type, int format_id,
-                        char *path, int remount)
+                        char *name, int remount)
 {
        int err;
-       struct nameidata nd;
+       struct path path;
 
        if (!test_opt(sb, QUOTA))
                return -EINVAL;
-       /* When remounting, no checks are needed and in fact, path is NULL */
+       /* When remounting, no checks are needed and in fact, name is NULL */
        if (remount)
-               return vfs_quota_on(sb, type, format_id, path, remount);
+               return vfs_quota_on(sb, type, format_id, name, remount);
 
-       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+       err = kern_path(name, LOOKUP_FOLLOW, &path);
        if (err)
                return err;
 
        /* Quotafile not on the same filesystem? */
-       if (nd.path.mnt->mnt_sb != sb) {
-               path_put(&nd.path);
+       if (path.mnt->mnt_sb != sb) {
+               path_put(&path);
                return -EXDEV;
        }
        /* Journaling quota? */
        if (EXT3_SB(sb)->s_qf_names[type]) {
                /* Quotafile not of fs root? */
-               if (nd.path.dentry->d_parent->d_inode != sb->s_root->d_inode)
+               if (path.dentry->d_parent != sb->s_root)
                        printk(KERN_WARNING
                                "EXT3-fs: Quota file not on filesystem root. "
                                "Journaled quota will not work.\n");
@@ -2800,18 +2827,22 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
         * When we journal data on quota file, we have to flush journal to see
         * all updates to the file when we bypass pagecache...
         */
-       if (ext3_should_journal_data(nd.path.dentry->d_inode)) {
+       if (ext3_should_journal_data(path.dentry->d_inode)) {
                /*
                 * We don't need to lock updates but journal_flush() could
                 * 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);
-       path_put(&nd.path);
+       err = vfs_quota_on_path(sb, type, format_id, &path);
+       path_put(&path);
        return err;
 }