@@ -89,6 +89,10 @@ static void ext4_clear_request_list(void);
89
89
static struct inode * ext4_get_journal_inode (struct super_block * sb ,
90
90
unsigned int journal_inum );
91
91
static int ext4_validate_options (struct fs_context * fc );
92
+ static int ext4_check_quota_consistency (struct fs_context * fc ,
93
+ struct super_block * sb );
94
+ static void ext4_apply_quota_options (struct fs_context * fc ,
95
+ struct super_block * sb );
92
96
93
97
/*
94
98
* Lock ordering
@@ -1986,71 +1990,6 @@ static const char deprecated_msg[] =
1986
1990
"Mount option \"%s\" will be removed by %s\n"
1987
1991
"Contact [email protected] if you think we should keep it.\n" ;
1988
1992
1989
- #ifdef CONFIG_QUOTA
1990
- static int set_qf_name (struct super_block * sb , int qtype ,
1991
- struct fs_parameter * param )
1992
- {
1993
- struct ext4_sb_info * sbi = EXT4_SB (sb );
1994
- char * qname , * old_qname = get_qf_name (sb , sbi , qtype );
1995
- int ret = -1 ;
1996
-
1997
- if (sb_any_quota_loaded (sb ) && !old_qname ) {
1998
- ext4_msg (sb , KERN_ERR ,
1999
- "Cannot change journaled "
2000
- "quota options when quota turned on" );
2001
- return -1 ;
2002
- }
2003
- if (ext4_has_feature_quota (sb )) {
2004
- ext4_msg (sb , KERN_INFO , "Journaled quota options "
2005
- "ignored when QUOTA feature is enabled" );
2006
- return 1 ;
2007
- }
2008
- qname = kmemdup_nul (param -> string , param -> size , GFP_KERNEL );
2009
- if (!qname ) {
2010
- ext4_msg (sb , KERN_ERR ,
2011
- "Not enough memory for storing quotafile name" );
2012
- return -1 ;
2013
- }
2014
- if (old_qname ) {
2015
- if (strcmp (old_qname , qname ) == 0 )
2016
- ret = 1 ;
2017
- else
2018
- ext4_msg (sb , KERN_ERR ,
2019
- "%s quota file already specified" ,
2020
- QTYPE2NAME (qtype ));
2021
- goto errout ;
2022
- }
2023
- if (strchr (qname , '/' )) {
2024
- ext4_msg (sb , KERN_ERR ,
2025
- "quotafile must be on filesystem root" );
2026
- goto errout ;
2027
- }
2028
- rcu_assign_pointer (sbi -> s_qf_names [qtype ], qname );
2029
- set_opt (sb , QUOTA );
2030
- return 1 ;
2031
- errout :
2032
- kfree (qname );
2033
- return ret ;
2034
- }
2035
-
2036
- static int clear_qf_name (struct super_block * sb , int qtype )
2037
- {
2038
-
2039
- struct ext4_sb_info * sbi = EXT4_SB (sb );
2040
- char * old_qname = get_qf_name (sb , sbi , qtype );
2041
-
2042
- if (sb_any_quota_loaded (sb ) && old_qname ) {
2043
- ext4_msg (sb , KERN_ERR , "Cannot change journaled quota options"
2044
- " when quota turned on" );
2045
- return -1 ;
2046
- }
2047
- rcu_assign_pointer (sbi -> s_qf_names [qtype ], NULL );
2048
- synchronize_rcu ();
2049
- kfree (old_qname );
2050
- return 1 ;
2051
- }
2052
- #endif
2053
-
2054
1993
#define MOPT_SET 0x0001
2055
1994
#define MOPT_CLEAR 0x0002
2056
1995
#define MOPT_NOSUPPORT 0x0004
@@ -2254,11 +2193,70 @@ static int ext4_set_test_dummy_encryption(struct super_block *sb,
2254
2193
}
2255
2194
2256
2195
struct ext4_fs_context {
2257
- unsigned long journal_devnum ;
2258
- unsigned int journal_ioprio ;
2259
- int mb_optimize_scan ;
2196
+ char * s_qf_names [EXT4_MAXQUOTAS ];
2197
+ int s_jquota_fmt ; /* Format of quota to use */
2198
+ unsigned short qname_spec ;
2199
+ unsigned long journal_devnum ;
2200
+ unsigned int journal_ioprio ;
2201
+ int mb_optimize_scan ;
2260
2202
};
2261
2203
2204
+ #ifdef CONFIG_QUOTA
2205
+ /*
2206
+ * Note the name of the specified quota file.
2207
+ */
2208
+ static int note_qf_name (struct fs_context * fc , int qtype ,
2209
+ struct fs_parameter * param )
2210
+ {
2211
+ struct ext4_fs_context * ctx = fc -> fs_private ;
2212
+ char * qname ;
2213
+
2214
+ if (param -> size < 1 ) {
2215
+ ext4_msg (NULL , KERN_ERR , "Missing quota name" );
2216
+ return - EINVAL ;
2217
+ }
2218
+ if (strchr (param -> string , '/' )) {
2219
+ ext4_msg (NULL , KERN_ERR ,
2220
+ "quotafile must be on filesystem root" );
2221
+ return - EINVAL ;
2222
+ }
2223
+ if (ctx -> s_qf_names [qtype ]) {
2224
+ if (strcmp (ctx -> s_qf_names [qtype ], param -> string ) != 0 ) {
2225
+ ext4_msg (NULL , KERN_ERR ,
2226
+ "%s quota file already specified" ,
2227
+ QTYPE2NAME (qtype ));
2228
+ return - EINVAL ;
2229
+ }
2230
+ return 0 ;
2231
+ }
2232
+
2233
+ qname = kmemdup_nul (param -> string , param -> size , GFP_KERNEL );
2234
+ if (!qname ) {
2235
+ ext4_msg (NULL , KERN_ERR ,
2236
+ "Not enough memory for storing quotafile name" );
2237
+ return - ENOMEM ;
2238
+ }
2239
+ ctx -> s_qf_names [qtype ] = qname ;
2240
+ ctx -> qname_spec |= 1 << qtype ;
2241
+ return 0 ;
2242
+ }
2243
+
2244
+ /*
2245
+ * Clear the name of the specified quota file.
2246
+ */
2247
+ static int unnote_qf_name (struct fs_context * fc , int qtype )
2248
+ {
2249
+ struct ext4_fs_context * ctx = fc -> fs_private ;
2250
+
2251
+ if (ctx -> s_qf_names [qtype ])
2252
+ kfree (ctx -> s_qf_names [qtype ]);
2253
+
2254
+ ctx -> s_qf_names [qtype ] = NULL ;
2255
+ ctx -> qname_spec |= 1 << qtype ;
2256
+ return 0 ;
2257
+ }
2258
+ #endif
2259
+
2262
2260
static int handle_mount_opt (struct fs_context * fc , struct fs_parameter * param )
2263
2261
{
2264
2262
struct ext4_fs_context * ctx = fc -> fs_private ;
@@ -2279,14 +2277,14 @@ static int handle_mount_opt(struct fs_context *fc, struct fs_parameter *param)
2279
2277
#ifdef CONFIG_QUOTA
2280
2278
if (token == Opt_usrjquota ) {
2281
2279
if (!* param -> string )
2282
- return clear_qf_name ( sb , USRQUOTA );
2280
+ return unnote_qf_name ( fc , USRQUOTA );
2283
2281
else
2284
- return set_qf_name ( sb , USRQUOTA , param );
2282
+ return note_qf_name ( fc , USRQUOTA , param );
2285
2283
} else if (token == Opt_grpjquota ) {
2286
2284
if (!* param -> string )
2287
- return clear_qf_name ( sb , GRPQUOTA );
2285
+ return unnote_qf_name ( fc , GRPQUOTA );
2288
2286
else
2289
- return set_qf_name ( sb , GRPQUOTA , param );
2287
+ return note_qf_name ( fc , GRPQUOTA , param );
2290
2288
}
2291
2289
#endif
2292
2290
switch (token ) {
@@ -2360,11 +2358,6 @@ static int handle_mount_opt(struct fs_context *fc, struct fs_parameter *param)
2360
2358
}
2361
2359
if (m -> flags & MOPT_CLEAR_ERR )
2362
2360
clear_opt (sb , ERRORS_MASK );
2363
- if (token == Opt_noquota && sb_any_quota_loaded (sb )) {
2364
- ext4_msg (NULL , KERN_ERR , "Cannot change quota "
2365
- "options when quota turned on" );
2366
- return - EINVAL ;
2367
- }
2368
2361
2369
2362
if (m -> flags & MOPT_NOSUPPORT ) {
2370
2363
ext4_msg (NULL , KERN_ERR , "%s option not supported" ,
@@ -2486,19 +2479,7 @@ static int handle_mount_opt(struct fs_context *fc, struct fs_parameter *param)
2486
2479
}
2487
2480
#ifdef CONFIG_QUOTA
2488
2481
} else if (m -> flags & MOPT_QFMT ) {
2489
- if (sb_any_quota_loaded (sb ) &&
2490
- sbi -> s_jquota_fmt != m -> mount_opt ) {
2491
- ext4_msg (NULL , KERN_ERR , "Cannot change journaled "
2492
- "quota options when quota turned on" );
2493
- return - EINVAL ;
2494
- }
2495
- if (ext4_has_feature_quota (sb )) {
2496
- ext4_msg (NULL , KERN_INFO ,
2497
- "Quota format mount options ignored "
2498
- "when QUOTA feature is enabled" );
2499
- return 1 ;
2500
- }
2501
- sbi -> s_jquota_fmt = m -> mount_opt ;
2482
+ ctx -> s_jquota_fmt = m -> mount_opt ;
2502
2483
#endif
2503
2484
} else if (token == Opt_dax || token == Opt_dax_always ||
2504
2485
token == Opt_dax_inode || token == Opt_dax_never ) {
@@ -2595,7 +2576,7 @@ static int handle_mount_opt(struct fs_context *fc, struct fs_parameter *param)
2595
2576
}
2596
2577
2597
2578
static int parse_options (char * options , struct super_block * sb ,
2598
- struct ext4_fs_context * ret_opts ,
2579
+ struct ext4_fs_context * ctx ,
2599
2580
int is_remount )
2600
2581
{
2601
2582
struct fs_parameter param ;
@@ -2607,7 +2588,7 @@ static int parse_options(char *options, struct super_block *sb,
2607
2588
return 1 ;
2608
2589
2609
2590
memset (& fc , 0 , sizeof (fc ));
2610
- fc .fs_private = ret_opts ;
2591
+ fc .fs_private = ctx ;
2611
2592
fc .s_fs_info = EXT4_SB (sb );
2612
2593
2613
2594
if (is_remount )
@@ -2649,9 +2630,100 @@ static int parse_options(char *options, struct super_block *sb,
2649
2630
if (ret < 0 )
2650
2631
return 0 ;
2651
2632
2633
+ ret = ext4_check_quota_consistency (& fc , sb );
2634
+ if (ret < 0 )
2635
+ return 0 ;
2636
+
2637
+ if (ctx -> qname_spec )
2638
+ ext4_apply_quota_options (& fc , sb );
2639
+
2652
2640
return 1 ;
2653
2641
}
2654
2642
2643
+ static void ext4_apply_quota_options (struct fs_context * fc ,
2644
+ struct super_block * sb )
2645
+ {
2646
+ #ifdef CONFIG_QUOTA
2647
+ struct ext4_fs_context * ctx = fc -> fs_private ;
2648
+ struct ext4_sb_info * sbi = EXT4_SB (sb );
2649
+ char * qname ;
2650
+ int i ;
2651
+
2652
+ for (i = 0 ; i < EXT4_MAXQUOTAS ; i ++ ) {
2653
+ if (!(ctx -> qname_spec & (1 << i )))
2654
+ continue ;
2655
+ qname = ctx -> s_qf_names [i ]; /* May be NULL */
2656
+ ctx -> s_qf_names [i ] = NULL ;
2657
+ kfree (sbi -> s_qf_names [i ]);
2658
+ rcu_assign_pointer (sbi -> s_qf_names [i ], qname );
2659
+ set_opt (sb , QUOTA );
2660
+ }
2661
+ #endif
2662
+ }
2663
+
2664
+ /*
2665
+ * Check quota settings consistency.
2666
+ */
2667
+ static int ext4_check_quota_consistency (struct fs_context * fc ,
2668
+ struct super_block * sb )
2669
+ {
2670
+ #ifdef CONFIG_QUOTA
2671
+ struct ext4_fs_context * ctx = fc -> fs_private ;
2672
+ struct ext4_sb_info * sbi = EXT4_SB (sb );
2673
+ bool quota_feature = ext4_has_feature_quota (sb );
2674
+ bool quota_loaded = sb_any_quota_loaded (sb );
2675
+ int i ;
2676
+
2677
+ if (ctx -> qname_spec && quota_loaded ) {
2678
+ if (quota_feature )
2679
+ goto err_feature ;
2680
+
2681
+ for (i = 0 ; i < EXT4_MAXQUOTAS ; i ++ ) {
2682
+ if (!(ctx -> qname_spec & (1 << i )))
2683
+ continue ;
2684
+
2685
+ if (!!sbi -> s_qf_names [i ] != !!ctx -> s_qf_names [i ])
2686
+ goto err_jquota_change ;
2687
+
2688
+ if (sbi -> s_qf_names [i ] && ctx -> s_qf_names [i ] &&
2689
+ strcmp (sbi -> s_qf_names [i ],
2690
+ ctx -> s_qf_names [i ]) != 0 )
2691
+ goto err_jquota_specified ;
2692
+ }
2693
+ }
2694
+
2695
+ if (ctx -> s_jquota_fmt ) {
2696
+ if (sbi -> s_jquota_fmt != ctx -> s_jquota_fmt && quota_loaded )
2697
+ goto err_quota_change ;
2698
+ if (quota_feature ) {
2699
+ ext4_msg (NULL , KERN_INFO , "Quota format mount options "
2700
+ "ignored when QUOTA feature is enabled" );
2701
+ return 0 ;
2702
+ }
2703
+ }
2704
+ return 0 ;
2705
+
2706
+ err_quota_change :
2707
+ ext4_msg (NULL , KERN_ERR ,
2708
+ "Cannot change quota options when quota turned on" );
2709
+ return - EINVAL ;
2710
+ err_jquota_change :
2711
+ ext4_msg (NULL , KERN_ERR , "Cannot change journaled quota "
2712
+ "options when quota turned on" );
2713
+ return - EINVAL ;
2714
+ err_jquota_specified :
2715
+ ext4_msg (NULL , KERN_ERR , "%s quota file already specified" ,
2716
+ QTYPE2NAME (i ));
2717
+ return - EINVAL ;
2718
+ err_feature :
2719
+ ext4_msg (NULL , KERN_ERR , "Journaled quota options ignored "
2720
+ "when QUOTA feature is enabled" );
2721
+ return 0 ;
2722
+ #else
2723
+ return 0 ;
2724
+ #endif
2725
+ }
2726
+
2655
2727
static int ext4_validate_options (struct fs_context * fc )
2656
2728
{
2657
2729
struct ext4_sb_info * sbi = fc -> s_fs_info ;
@@ -4105,7 +4177,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
4105
4177
__u64 blocks_count ;
4106
4178
int err = 0 ;
4107
4179
ext4_group_t first_not_zeroed ;
4108
- struct ext4_fs_context parsed_opts ;
4180
+ struct ext4_fs_context parsed_opts = { 0 } ;
4109
4181
4110
4182
/* Set defaults for the variables that will be set during parsing */
4111
4183
parsed_opts .journal_ioprio = DEFAULT_JOURNAL_IOPRIO ;
0 commit comments