1919#include <linux/fs.h>
2020#include <linux/err.h>
2121#include <linux/mount.h>
22- #include <linux/parser.h>
22+ #include <linux/fs_context.h>
23+ #include <linux/fs_parser.h>
2324#include <linux/jffs2.h>
2425#include <linux/pagemap.h>
2526#include <linux/mtd/super.h>
@@ -157,96 +158,77 @@ static const struct export_operations jffs2_export_ops = {
157158/*
158159 * JFFS2 mount options.
159160 *
161+ * Opt_source: The source device
160162 * Opt_override_compr: override default compressor
161163 * Opt_rp_size: size of reserved pool in KiB
162- * Opt_err: just end of array marker
163164 */
164165enum {
166+ Opt_source ,
165167 Opt_override_compr ,
166168 Opt_rp_size ,
167- Opt_err ,
168169};
169170
170- static const match_table_t tokens = {
171- {Opt_override_compr , "compr=%s" },
172- {Opt_rp_size , "rp_size=%u" },
173- {Opt_err , NULL },
171+ static const struct fs_parameter_spec jffs2_param_specs [] = {
172+ fsparam_string ("source" , Opt_source ),
173+ fsparam_enum ("compr" , Opt_override_compr ),
174+ fsparam_u32 ("rp_size" , Opt_rp_size ),
175+ {}
174176};
175177
176- static int jffs2_parse_options (struct jffs2_sb_info * c , char * data )
177- {
178- substring_t args [MAX_OPT_ARGS ];
179- char * p , * name ;
180- unsigned int opt ;
181-
182- if (!data )
183- return 0 ;
184-
185- while ((p = strsep (& data , "," ))) {
186- int token ;
187-
188- if (!* p )
189- continue ;
190-
191- token = match_token (p , tokens , args );
192- switch (token ) {
193- case Opt_override_compr :
194- name = match_strdup (& args [0 ]);
195-
196- if (!name )
197- return - ENOMEM ;
198- if (!strcmp (name , "none" ))
199- c -> mount_opts .compr = JFFS2_COMPR_MODE_NONE ;
178+ static const struct fs_parameter_enum jffs2_param_enums [] = {
179+ { Opt_override_compr , "none" , JFFS2_COMPR_MODE_NONE },
200180#ifdef CONFIG_JFFS2_LZO
201- else if (!strcmp (name , "lzo "))
202- c -> mount_opts .compr = JFFS2_COMPR_MODE_FORCELZO ;
181+ { Opt_override_compr , "lzo" , JFFS2_COMPR_MODE_FORCELZO },
203182#endif
204183#ifdef CONFIG_JFFS2_ZLIB
205- else if (!strcmp (name , "zlib "))
206- c -> mount_opts .compr =
207- JFFS2_COMPR_MODE_FORCEZLIB ;
184+ { Opt_override_compr , "zlib" , JFFS2_COMPR_MODE_FORCEZLIB },
208185#endif
209- else {
210- pr_err ("Error: unknown compressor \"%s\"\n" ,
211- name );
212- kfree (name );
213- return - EINVAL ;
214- }
215- kfree (name );
216- c -> mount_opts .override_compr = true;
217- break ;
218- case Opt_rp_size :
219- if (match_int (& args [0 ], & opt ))
220- return - EINVAL ;
221- opt *= 1024 ;
222- if (opt > c -> mtd -> size ) {
223- pr_warn ("Too large reserve pool specified, max "
224- "is %llu KB\n" , c -> mtd -> size / 1024 );
225- return - EINVAL ;
226- }
227- c -> mount_opts .rp_size = opt ;
228- break ;
229- default :
230- pr_err ("Error: unrecognized mount option '%s' or missing value\n" ,
231- p );
232- return - EINVAL ;
233- }
186+ {}
187+ };
188+
189+ const struct fs_parameter_description jffs2_fs_parameters = {
190+ .name = "jffs2" ,
191+ .specs = jffs2_param_specs ,
192+ .enums = jffs2_param_enums ,
193+ };
194+
195+ static int jffs2_parse_param (struct fs_context * fc , struct fs_parameter * param )
196+ {
197+ struct fs_parse_result result ;
198+ struct jffs2_sb_info * c = fc -> s_fs_info ;
199+ int opt ;
200+
201+ opt = fs_parse (fc , & jffs2_fs_parameters , param , & result );
202+ if (opt < 0 )
203+ return opt ;
204+
205+ switch (opt ) {
206+ case Opt_override_compr :
207+ c -> mount_opts .compr = result .uint_32 ;
208+ c -> mount_opts .override_compr = true;
209+ break ;
210+ case Opt_rp_size :
211+ if (result .uint_32 > UINT_MAX / 1024 )
212+ return invalf (fc , "jffs2: rp_size unrepresentable" );
213+ opt = result .uint_32 * 1024 ;
214+ if (opt > c -> mtd -> size )
215+ return invalf (fc , "jffs2: Too large reserve pool specified, max is %llu KB" ,
216+ c -> mtd -> size / 1024 );
217+ c -> mount_opts .rp_size = opt ;
218+ break ;
219+ default :
220+ return - EINVAL ;
234221 }
235222
236223 return 0 ;
237224}
238225
239- static int jffs2_remount_fs (struct super_block * sb , int * flags , char * data )
226+ static int jffs2_reconfigure (struct fs_context * fc )
240227{
241- struct jffs2_sb_info * c = JFFS2_SB_INFO (sb );
242- int err ;
228+ struct super_block * sb = fc -> root -> d_sb ;
243229
244230 sync_filesystem (sb );
245- err = jffs2_parse_options (c , data );
246- if (err )
247- return - EINVAL ;
248-
249- return jffs2_do_remount_fs (sb , flags , data );
231+ return jffs2_do_remount_fs (sb , fc );
250232}
251233
252234static const struct super_operations jffs2_super_operations =
@@ -255,7 +237,6 @@ static const struct super_operations jffs2_super_operations =
255237 .free_inode = jffs2_free_inode ,
256238 .put_super = jffs2_put_super ,
257239 .statfs = jffs2_statfs ,
258- .remount_fs = jffs2_remount_fs ,
259240 .evict_inode = jffs2_evict_inode ,
260241 .dirty_inode = jffs2_dirty_inode ,
261242 .show_options = jffs2_show_options ,
@@ -265,26 +246,16 @@ static const struct super_operations jffs2_super_operations =
265246/*
266247 * fill in the superblock
267248 */
268- static int jffs2_fill_super (struct super_block * sb , void * data , int silent )
249+ static int jffs2_fill_super (struct super_block * sb , struct fs_context * fc )
269250{
270- struct jffs2_sb_info * c ;
271- int ret ;
251+ struct jffs2_sb_info * c = sb -> s_fs_info ;
272252
273253 jffs2_dbg (1 , "jffs2_get_sb_mtd():"
274254 " New superblock for device %d (\"%s\")\n" ,
275255 sb -> s_mtd -> index , sb -> s_mtd -> name );
276256
277- c = kzalloc (sizeof (* c ), GFP_KERNEL );
278- if (!c )
279- return - ENOMEM ;
280-
281257 c -> mtd = sb -> s_mtd ;
282258 c -> os_priv = sb ;
283- sb -> s_fs_info = c ;
284-
285- ret = jffs2_parse_options (c , data );
286- if (ret )
287- return - EINVAL ;
288259
289260 /* Initialize JFFS2 superblock locks, the further initialization will
290261 * be done later */
@@ -302,15 +273,37 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
302273#ifdef CONFIG_JFFS2_FS_POSIX_ACL
303274 sb -> s_flags |= SB_POSIXACL ;
304275#endif
305- ret = jffs2_do_fill_super (sb , data , silent );
306- return ret ;
276+ return jffs2_do_fill_super (sb , fc );
307277}
308278
309- static struct dentry * jffs2_mount (struct file_system_type * fs_type ,
310- int flags , const char * dev_name ,
311- void * data )
279+ static int jffs2_get_tree (struct fs_context * fc )
312280{
313- return mount_mtd (fs_type , flags , dev_name , data , jffs2_fill_super );
281+ return get_tree_mtd (fc , jffs2_fill_super );
282+ }
283+
284+ static void jffs2_free_fc (struct fs_context * fc )
285+ {
286+ kfree (fc -> s_fs_info );
287+ }
288+
289+ static const struct fs_context_operations jffs2_context_ops = {
290+ .free = jffs2_free_fc ,
291+ .parse_param = jffs2_parse_param ,
292+ .get_tree = jffs2_get_tree ,
293+ .reconfigure = jffs2_reconfigure ,
294+ };
295+
296+ static int jffs2_init_fs_context (struct fs_context * fc )
297+ {
298+ struct jffs2_sb_info * ctx ;
299+
300+ ctx = kzalloc (sizeof (struct jffs2_sb_info ), GFP_KERNEL );
301+ if (!ctx )
302+ return - ENOMEM ;
303+
304+ fc -> s_fs_info = ctx ;
305+ fc -> ops = & jffs2_context_ops ;
306+ return 0 ;
314307}
315308
316309static void jffs2_put_super (struct super_block * sb )
@@ -347,7 +340,8 @@ static void jffs2_kill_sb(struct super_block *sb)
347340static struct file_system_type jffs2_fs_type = {
348341 .owner = THIS_MODULE ,
349342 .name = "jffs2" ,
350- .mount = jffs2_mount ,
343+ .init_fs_context = jffs2_init_fs_context ,
344+ .parameters = & jffs2_fs_parameters ,
351345 .kill_sb = jffs2_kill_sb ,
352346};
353347MODULE_ALIAS_FS ("jffs2" );
0 commit comments