aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext3/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext3/super.c')
-rw-r--r--fs/ext3/super.c110
1 files changed, 89 insertions, 21 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 9630fbfdc24a..3c3c6e399fb3 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -589,7 +589,7 @@ enum {
589 Opt_commit, Opt_journal_update, Opt_journal_inum, 589 Opt_commit, Opt_journal_update, Opt_journal_inum,
590 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback, 590 Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
591 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, 591 Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
592 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, 592 Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
593 Opt_ignore, Opt_barrier, Opt_err, Opt_resize, 593 Opt_ignore, Opt_barrier, Opt_err, Opt_resize,
594}; 594};
595 595
@@ -634,10 +634,10 @@ static match_table_t tokens = {
634 {Opt_grpjquota, "grpjquota=%s"}, 634 {Opt_grpjquota, "grpjquota=%s"},
635 {Opt_jqfmt_vfsold, "jqfmt=vfsold"}, 635 {Opt_jqfmt_vfsold, "jqfmt=vfsold"},
636 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"}, 636 {Opt_jqfmt_vfsv0, "jqfmt=vfsv0"},
637 {Opt_ignore, "grpquota"}, 637 {Opt_quota, "grpquota"},
638 {Opt_ignore, "noquota"}, 638 {Opt_noquota, "noquota"},
639 {Opt_ignore, "quota"}, 639 {Opt_quota, "quota"},
640 {Opt_ignore, "usrquota"}, 640 {Opt_quota, "usrquota"},
641 {Opt_barrier, "barrier=%u"}, 641 {Opt_barrier, "barrier=%u"},
642 {Opt_err, NULL}, 642 {Opt_err, NULL},
643 {Opt_resize, "resize"}, 643 {Opt_resize, "resize"},
@@ -876,6 +876,7 @@ set_qf_name:
876 sbi->s_qf_names[qtype] = NULL; 876 sbi->s_qf_names[qtype] = NULL;
877 return 0; 877 return 0;
878 } 878 }
879 set_opt(sbi->s_mount_opt, QUOTA);
879 break; 880 break;
880 case Opt_offusrjquota: 881 case Opt_offusrjquota:
881 qtype = USRQUOTA; 882 qtype = USRQUOTA;
@@ -889,7 +890,10 @@ clear_qf_name:
889 "quota turned on.\n"); 890 "quota turned on.\n");
890 return 0; 891 return 0;
891 } 892 }
892 kfree(sbi->s_qf_names[qtype]); 893 /*
894 * The space will be released later when all options
895 * are confirmed to be correct
896 */
893 sbi->s_qf_names[qtype] = NULL; 897 sbi->s_qf_names[qtype] = NULL;
894 break; 898 break;
895 case Opt_jqfmt_vfsold: 899 case Opt_jqfmt_vfsold:
@@ -898,6 +902,17 @@ clear_qf_name:
898 case Opt_jqfmt_vfsv0: 902 case Opt_jqfmt_vfsv0:
899 sbi->s_jquota_fmt = QFMT_VFS_V0; 903 sbi->s_jquota_fmt = QFMT_VFS_V0;
900 break; 904 break;
905 case Opt_quota:
906 set_opt(sbi->s_mount_opt, QUOTA);
907 break;
908 case Opt_noquota:
909 if (sb_any_quota_enabled(sb)) {
910 printk(KERN_ERR "EXT3-fs: Cannot change quota "
911 "options when quota turned on.\n");
912 return 0;
913 }
914 clear_opt(sbi->s_mount_opt, QUOTA);
915 break;
901#else 916#else
902 case Opt_usrjquota: 917 case Opt_usrjquota:
903 case Opt_grpjquota: 918 case Opt_grpjquota:
@@ -909,6 +924,9 @@ clear_qf_name:
909 "EXT3-fs: journalled quota options not " 924 "EXT3-fs: journalled quota options not "
910 "supported.\n"); 925 "supported.\n");
911 break; 926 break;
927 case Opt_quota:
928 case Opt_noquota:
929 break;
912#endif 930#endif
913 case Opt_abort: 931 case Opt_abort:
914 set_opt(sbi->s_mount_opt, ABORT); 932 set_opt(sbi->s_mount_opt, ABORT);
@@ -924,12 +942,13 @@ clear_qf_name:
924 case Opt_ignore: 942 case Opt_ignore:
925 break; 943 break;
926 case Opt_resize: 944 case Opt_resize:
927 if (!n_blocks_count) { 945 if (!is_remount) {
928 printk("EXT3-fs: resize option only available " 946 printk("EXT3-fs: resize option only available "
929 "for remount\n"); 947 "for remount\n");
930 return 0; 948 return 0;
931 } 949 }
932 match_int(&args[0], &option); 950 if (match_int(&args[0], &option) != 0)
951 return 0;
933 *n_blocks_count = option; 952 *n_blocks_count = option;
934 break; 953 break;
935 case Opt_nobh: 954 case Opt_nobh:
@@ -2093,14 +2112,33 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2093{ 2112{
2094 struct ext3_super_block * es; 2113 struct ext3_super_block * es;
2095 struct ext3_sb_info *sbi = EXT3_SB(sb); 2114 struct ext3_sb_info *sbi = EXT3_SB(sb);
2096 unsigned long tmp;
2097 unsigned long n_blocks_count = 0; 2115 unsigned long n_blocks_count = 0;
2116 unsigned long old_sb_flags;
2117 struct ext3_mount_options old_opts;
2118 int err;
2119#ifdef CONFIG_QUOTA
2120 int i;
2121#endif
2122
2123 /* Store the original options */
2124 old_sb_flags = sb->s_flags;
2125 old_opts.s_mount_opt = sbi->s_mount_opt;
2126 old_opts.s_resuid = sbi->s_resuid;
2127 old_opts.s_resgid = sbi->s_resgid;
2128 old_opts.s_commit_interval = sbi->s_commit_interval;
2129#ifdef CONFIG_QUOTA
2130 old_opts.s_jquota_fmt = sbi->s_jquota_fmt;
2131 for (i = 0; i < MAXQUOTAS; i++)
2132 old_opts.s_qf_names[i] = sbi->s_qf_names[i];
2133#endif
2098 2134
2099 /* 2135 /*
2100 * Allow the "check" option to be passed as a remount option. 2136 * Allow the "check" option to be passed as a remount option.
2101 */ 2137 */
2102 if (!parse_options(data, sb, &tmp, &n_blocks_count, 1)) 2138 if (!parse_options(data, sb, NULL, &n_blocks_count, 1)) {
2103 return -EINVAL; 2139 err = -EINVAL;
2140 goto restore_opts;
2141 }
2104 2142
2105 if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) 2143 if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
2106 ext3_abort(sb, __FUNCTION__, "Abort forced by user"); 2144 ext3_abort(sb, __FUNCTION__, "Abort forced by user");
@@ -2114,8 +2152,10 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2114 2152
2115 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) || 2153 if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY) ||
2116 n_blocks_count > le32_to_cpu(es->s_blocks_count)) { 2154 n_blocks_count > le32_to_cpu(es->s_blocks_count)) {
2117 if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) 2155 if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) {
2118 return -EROFS; 2156 err = -EROFS;
2157 goto restore_opts;
2158 }
2119 2159
2120 if (*flags & MS_RDONLY) { 2160 if (*flags & MS_RDONLY) {
2121 /* 2161 /*
@@ -2142,7 +2182,8 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2142 "remount RDWR because of unsupported " 2182 "remount RDWR because of unsupported "
2143 "optional features (%x).\n", 2183 "optional features (%x).\n",
2144 sb->s_id, le32_to_cpu(ret)); 2184 sb->s_id, le32_to_cpu(ret));
2145 return -EROFS; 2185 err = -EROFS;
2186 goto restore_opts;
2146 } 2187 }
2147 /* 2188 /*
2148 * Mounting a RDONLY partition read-write, so reread 2189 * Mounting a RDONLY partition read-write, so reread
@@ -2152,13 +2193,38 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
2152 */ 2193 */
2153 ext3_clear_journal_err(sb, es); 2194 ext3_clear_journal_err(sb, es);
2154 sbi->s_mount_state = le16_to_cpu(es->s_state); 2195 sbi->s_mount_state = le16_to_cpu(es->s_state);
2155 if ((ret = ext3_group_extend(sb, es, n_blocks_count))) 2196 if ((ret = ext3_group_extend(sb, es, n_blocks_count))) {
2156 return ret; 2197 err = ret;
2198 goto restore_opts;
2199 }
2157 if (!ext3_setup_super (sb, es, 0)) 2200 if (!ext3_setup_super (sb, es, 0))
2158 sb->s_flags &= ~MS_RDONLY; 2201 sb->s_flags &= ~MS_RDONLY;
2159 } 2202 }
2160 } 2203 }
2204#ifdef CONFIG_QUOTA
2205 /* Release old quota file names */
2206 for (i = 0; i < MAXQUOTAS; i++)
2207 if (old_opts.s_qf_names[i] &&
2208 old_opts.s_qf_names[i] != sbi->s_qf_names[i])
2209 kfree(old_opts.s_qf_names[i]);
2210#endif
2161 return 0; 2211 return 0;
2212restore_opts:
2213 sb->s_flags = old_sb_flags;
2214 sbi->s_mount_opt = old_opts.s_mount_opt;
2215 sbi->s_resuid = old_opts.s_resuid;
2216 sbi->s_resgid = old_opts.s_resgid;
2217 sbi->s_commit_interval = old_opts.s_commit_interval;
2218#ifdef CONFIG_QUOTA
2219 sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
2220 for (i = 0; i < MAXQUOTAS; i++) {
2221 if (sbi->s_qf_names[i] &&
2222 old_opts.s_qf_names[i] != sbi->s_qf_names[i])
2223 kfree(sbi->s_qf_names[i]);
2224 sbi->s_qf_names[i] = old_opts.s_qf_names[i];
2225 }
2226#endif
2227 return err;
2162} 2228}
2163 2229
2164static int ext3_statfs (struct super_block * sb, struct kstatfs * buf) 2230static int ext3_statfs (struct super_block * sb, struct kstatfs * buf)
@@ -2238,7 +2304,7 @@ static int ext3_dquot_initialize(struct inode *inode, int type)
2238 int ret, err; 2304 int ret, err;
2239 2305
2240 /* We may create quota structure so we need to reserve enough blocks */ 2306 /* We may create quota structure so we need to reserve enough blocks */
2241 handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS); 2307 handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb));
2242 if (IS_ERR(handle)) 2308 if (IS_ERR(handle))
2243 return PTR_ERR(handle); 2309 return PTR_ERR(handle);
2244 ret = dquot_initialize(inode, type); 2310 ret = dquot_initialize(inode, type);
@@ -2254,7 +2320,7 @@ static int ext3_dquot_drop(struct inode *inode)
2254 int ret, err; 2320 int ret, err;
2255 2321
2256 /* We may delete quota structure so we need to reserve enough blocks */ 2322 /* We may delete quota structure so we need to reserve enough blocks */
2257 handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS); 2323 handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb));
2258 if (IS_ERR(handle)) 2324 if (IS_ERR(handle))
2259 return PTR_ERR(handle); 2325 return PTR_ERR(handle);
2260 ret = dquot_drop(inode); 2326 ret = dquot_drop(inode);
@@ -2272,7 +2338,7 @@ static int ext3_write_dquot(struct dquot *dquot)
2272 2338
2273 inode = dquot_to_inode(dquot); 2339 inode = dquot_to_inode(dquot);
2274 handle = ext3_journal_start(inode, 2340 handle = ext3_journal_start(inode,
2275 EXT3_QUOTA_TRANS_BLOCKS); 2341 EXT3_QUOTA_TRANS_BLOCKS(dquot->dq_sb));
2276 if (IS_ERR(handle)) 2342 if (IS_ERR(handle))
2277 return PTR_ERR(handle); 2343 return PTR_ERR(handle);
2278 ret = dquot_commit(dquot); 2344 ret = dquot_commit(dquot);
@@ -2288,7 +2354,7 @@ static int ext3_acquire_dquot(struct dquot *dquot)
2288 handle_t *handle; 2354 handle_t *handle;
2289 2355
2290 handle = ext3_journal_start(dquot_to_inode(dquot), 2356 handle = ext3_journal_start(dquot_to_inode(dquot),
2291 EXT3_QUOTA_INIT_BLOCKS); 2357 EXT3_QUOTA_INIT_BLOCKS(dquot->dq_sb));
2292 if (IS_ERR(handle)) 2358 if (IS_ERR(handle))
2293 return PTR_ERR(handle); 2359 return PTR_ERR(handle);
2294 ret = dquot_acquire(dquot); 2360 ret = dquot_acquire(dquot);
@@ -2304,7 +2370,7 @@ static int ext3_release_dquot(struct dquot *dquot)
2304 handle_t *handle; 2370 handle_t *handle;
2305 2371
2306 handle = ext3_journal_start(dquot_to_inode(dquot), 2372 handle = ext3_journal_start(dquot_to_inode(dquot),
2307 EXT3_QUOTA_INIT_BLOCKS); 2373 EXT3_QUOTA_DEL_BLOCKS(dquot->dq_sb));
2308 if (IS_ERR(handle)) 2374 if (IS_ERR(handle))
2309 return PTR_ERR(handle); 2375 return PTR_ERR(handle);
2310 ret = dquot_release(dquot); 2376 ret = dquot_release(dquot);
@@ -2361,6 +2427,8 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
2361 int err; 2427 int err;
2362 struct nameidata nd; 2428 struct nameidata nd;
2363 2429
2430 if (!test_opt(sb, QUOTA))
2431 return -EINVAL;
2364 /* Not journalling quota? */ 2432 /* Not journalling quota? */
2365 if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] && 2433 if (!EXT3_SB(sb)->s_qf_names[USRQUOTA] &&
2366 !EXT3_SB(sb)->s_qf_names[GRPQUOTA]) 2434 !EXT3_SB(sb)->s_qf_names[GRPQUOTA])