int retries = 0;
 
        retry:
-               handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
+               handle = ext3_journal_start(inode,
+                               EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
                if (IS_ERR(handle)) {
                        error = PTR_ERR(handle);
                        ext3_std_error(inode->i_sb, error);
                acl = NULL;
 
 retry:
-       handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
+       handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
        error = ext3_set_acl(handle, inode, type, acl);
 
        if (needed > EXT3_MAX_TRANS_DATA) 
                needed = EXT3_MAX_TRANS_DATA;
 
-       return EXT3_DATA_TRANS_BLOCKS + needed;
+       return EXT3_DATA_TRANS_BLOCKS(inode->i_sb) + needed;
 }
 
 /* 
 
                /* (user+group)*(old+new) structure, inode write (sb,
                 * inode block, ? - but truncate inode update has it) */
-               handle = ext3_journal_start(inode, 4*EXT3_QUOTA_INIT_BLOCKS+3);
+               handle = ext3_journal_start(inode, 2*(EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)+
+                                       EXT3_QUOTA_DEL_BLOCKS(inode->i_sb))+3);
                if (IS_ERR(handle)) {
                        error = PTR_ERR(handle);
                        goto err_out;
 #ifdef CONFIG_QUOTA
        /* We know that structure was already allocated during DQUOT_INIT so
         * we will be updating only the data blocks + inodes */
-       ret += 2*EXT3_QUOTA_TRANS_BLOCKS;
+       ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb);
 #endif
 
        return ret;
 
        int err, retries = 0;
 
 retry:
-       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-                                       2*EXT3_QUOTA_INIT_BLOCKS);
+                                       2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
                return -EINVAL;
 
 retry:
-       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-                                       2*EXT3_QUOTA_INIT_BLOCKS);
+                                       2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
                return -EMLINK;
 
 retry:
-       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3 +
-                                       2*EXT3_QUOTA_INIT_BLOCKS);
+                                       2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
        /* Initialize quotas before so that eventual writes go in
         * separate transaction */
        DQUOT_INIT(dentry->d_inode);
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
        /* Initialize quotas before so that eventual writes go
         * in separate transaction */
        DQUOT_INIT(dentry->d_inode);
-       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
+       handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
                return -ENAMETOOLONG;
 
 retry:
-       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5 +
-                                       2*EXT3_QUOTA_INIT_BLOCKS);
+                                       2*EXT3_QUOTA_INIT_BLOCKS(dir->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
                return -EMLINK;
 
 retry:
-       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
+       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS(dir->i_sb) +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS);
        if (IS_ERR(handle))
                return PTR_ERR(handle);
         * in separate transaction */
        if (new_dentry->d_inode)
                DQUOT_INIT(new_dentry->d_inode);
-       handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
+       handle = ext3_journal_start(old_dir, 2 *
+                                       EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) +
                                        EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
        if (IS_ERR(handle))
                return PTR_ERR(handle);
 
        Opt_commit, Opt_journal_update, Opt_journal_inum,
        Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
        Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
-       Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0,
+       Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
        Opt_ignore, Opt_barrier, Opt_err, Opt_resize,
 };
 
        {Opt_grpjquota, "grpjquota=%s"},
        {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
        {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
-       {Opt_ignore, "grpquota"},
-       {Opt_ignore, "noquota"},
-       {Opt_ignore, "quota"},
-       {Opt_ignore, "usrquota"},
+       {Opt_quota, "grpquota"},
+       {Opt_noquota, "noquota"},
+       {Opt_quota, "quota"},
+       {Opt_quota, "usrquota"},
        {Opt_barrier, "barrier=%u"},
        {Opt_err, NULL},
        {Opt_resize, "resize"},
                                sbi->s_qf_names[qtype] = NULL;
                                return 0;
                        }
+                       set_opt(sbi->s_mount_opt, QUOTA);
                        break;
                case Opt_offusrjquota:
                        qtype = USRQUOTA;
                case Opt_jqfmt_vfsv0:
                        sbi->s_jquota_fmt = QFMT_VFS_V0;
                        break;
+               case Opt_quota:
+                       set_opt(sbi->s_mount_opt, QUOTA);
+                       break;
+               case Opt_noquota:
+                       if (sb_any_quota_enabled(sb)) {
+                               printk(KERN_ERR "EXT3-fs: Cannot change quota "
+                                       "options when quota turned on.\n");
+                               return 0;
+                       }
+                       clear_opt(sbi->s_mount_opt, QUOTA);
+                       break;
 #else
                case Opt_usrjquota:
                case Opt_grpjquota:
                                "EXT3-fs: journalled quota options not "
                                "supported.\n");
                        break;
+               case Opt_quota:
+               case Opt_noquota:
+                       break;
 #endif
                case Opt_abort:
                        set_opt(sbi->s_mount_opt, ABORT);
        int ret, err;
 
        /* We may create quota structure so we need to reserve enough blocks */
-       handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS);
+       handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
        ret = dquot_initialize(inode, type);
        int ret, err;
 
        /* We may delete quota structure so we need to reserve enough blocks */
-       handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS);
+       handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
        ret = dquot_drop(inode);
 
        inode = dquot_to_inode(dquot);
        handle = ext3_journal_start(inode,
-                                       EXT3_QUOTA_TRANS_BLOCKS);
+                                       EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
        ret = dquot_commit(dquot);
        handle_t *handle;
 
        handle = ext3_journal_start(dquot_to_inode(dquot),
-                                       EXT3_QUOTA_INIT_BLOCKS);
+                                       EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
        ret = dquot_acquire(dquot);
        handle_t *handle;
 
        handle = ext3_journal_start(dquot_to_inode(dquot),
-                                       EXT3_QUOTA_INIT_BLOCKS);
+                                       EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
        if (IS_ERR(handle))
                return PTR_ERR(handle);
        ret = dquot_release(dquot);
        int err;
        struct nameidata nd;
 
+       if (!test_opt(sb, QUOTA))
+               return -EINVAL;
        /* Not journalling quota? */
        if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] &&
            !EXT3_SB(sb)->s_qf_names[GRPQUOTA])
 
        int error, retries = 0;
 
 retry:
-       handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS);
+       handle = ext3_journal_start(inode, EXT3_DATA_TRANS_BLOCKS(inode->i_sb));
        if (IS_ERR(handle)) {
                error = PTR_ERR(handle);
        } else {
 
 #define EXT3_MOUNT_RESERVATION         0x10000 /* Preallocation */
 #define EXT3_MOUNT_BARRIER             0x20000 /* Use block barriers */
 #define EXT3_MOUNT_NOBH                        0x40000 /* No bufferheads */
+#define EXT3_MOUNT_QUOTA               0x80000 /* Some quota option set */
 
 /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
 #ifndef _LINUX_EXT2_FS_H
 
  * superblock only gets updated once, of course, so don't bother
  * counting that again for the quota updates. */
 
-#define EXT3_DATA_TRANS_BLOCKS         (EXT3_SINGLEDATA_TRANS_BLOCKS + \
+#define EXT3_DATA_TRANS_BLOCKS(sb)     (EXT3_SINGLEDATA_TRANS_BLOCKS + \
                                         EXT3_XATTR_TRANS_BLOCKS - 2 + \
-                                        2*EXT3_QUOTA_TRANS_BLOCKS)
+                                        2*EXT3_QUOTA_TRANS_BLOCKS(sb))
 
 /* Delete operations potentially hit one directory's namespace plus an
  * entire inode, plus arbitrary amounts of bitmap/indirection data.  Be
  * generous.  We can grow the delete transaction later if necessary. */
 
-#define EXT3_DELETE_TRANS_BLOCKS       (2 * EXT3_DATA_TRANS_BLOCKS + 64)
+#define EXT3_DELETE_TRANS_BLOCKS(sb)   (2 * EXT3_DATA_TRANS_BLOCKS(sb) + 64)
 
 /* Define an arbitrary limit for the amount of data we will anticipate
  * writing to any given transaction.  For unbounded transactions such as
 #ifdef CONFIG_QUOTA
 /* Amount of blocks needed for quota update - we know that the structure was
  * allocated so we need to update only inode+data */
-#define EXT3_QUOTA_TRANS_BLOCKS 2
+#define EXT3_QUOTA_TRANS_BLOCKS(sb) (test_opt(sb, QUOTA) ? 2 : 0)
 /* Amount of blocks needed for quota insert/delete - we do some block writes
  * but inode, sb and group updates are done only once */
-#define EXT3_QUOTA_INIT_BLOCKS (DQUOT_MAX_WRITES*\
-                               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3)
+#define EXT3_QUOTA_INIT_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_INIT_ALLOC*\
+               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_INIT_REWRITE) : 0)
+#define EXT3_QUOTA_DEL_BLOCKS(sb) (test_opt(sb, QUOTA) ? (DQUOT_DEL_ALLOC*\
+               (EXT3_SINGLEDATA_TRANS_BLOCKS-3)+3+DQUOT_DEL_REWRITE) : 0)
 #else
-#define EXT3_QUOTA_TRANS_BLOCKS 0
-#define EXT3_QUOTA_INIT_BLOCKS 0
+#define EXT3_QUOTA_TRANS_BLOCKS(sb) 0
+#define EXT3_QUOTA_INIT_BLOCKS(sb) 0
+#define EXT3_QUOTA_DEL_BLOCKS(sb) 0
 #endif
 
 int