19
19
#include <linux/fs.h>
20
20
#include <linux/err.h>
21
21
#include <linux/mount.h>
22
- #include <linux/parser.h>
22
+ #include <linux/fs_context.h>
23
+ #include <linux/fs_parser.h>
23
24
#include <linux/jffs2.h>
24
25
#include <linux/pagemap.h>
25
26
#include <linux/mtd/super.h>
@@ -157,96 +158,77 @@ static const struct export_operations jffs2_export_ops = {
157
158
/*
158
159
* JFFS2 mount options.
159
160
*
161
+ * Opt_source: The source device
160
162
* Opt_override_compr: override default compressor
161
163
* Opt_rp_size: size of reserved pool in KiB
162
- * Opt_err: just end of array marker
163
164
*/
164
165
enum {
166
+ Opt_source ,
165
167
Opt_override_compr ,
166
168
Opt_rp_size ,
167
- Opt_err ,
168
169
};
169
170
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
+ {}
174
176
};
175
177
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 },
200
180
#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 },
203
182
#endif
204
183
#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 },
208
185
#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 ;
234
221
}
235
222
236
223
return 0 ;
237
224
}
238
225
239
- static int jffs2_remount_fs (struct super_block * sb , int * flags , char * data )
226
+ static int jffs2_reconfigure (struct fs_context * fc )
240
227
{
241
- struct jffs2_sb_info * c = JFFS2_SB_INFO (sb );
242
- int err ;
228
+ struct super_block * sb = fc -> root -> d_sb ;
243
229
244
230
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 );
250
232
}
251
233
252
234
static const struct super_operations jffs2_super_operations =
@@ -255,7 +237,6 @@ static const struct super_operations jffs2_super_operations =
255
237
.free_inode = jffs2_free_inode ,
256
238
.put_super = jffs2_put_super ,
257
239
.statfs = jffs2_statfs ,
258
- .remount_fs = jffs2_remount_fs ,
259
240
.evict_inode = jffs2_evict_inode ,
260
241
.dirty_inode = jffs2_dirty_inode ,
261
242
.show_options = jffs2_show_options ,
@@ -265,26 +246,16 @@ static const struct super_operations jffs2_super_operations =
265
246
/*
266
247
* fill in the superblock
267
248
*/
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 )
269
250
{
270
- struct jffs2_sb_info * c ;
271
- int ret ;
251
+ struct jffs2_sb_info * c = sb -> s_fs_info ;
272
252
273
253
jffs2_dbg (1 , "jffs2_get_sb_mtd():"
274
254
" New superblock for device %d (\"%s\")\n" ,
275
255
sb -> s_mtd -> index , sb -> s_mtd -> name );
276
256
277
- c = kzalloc (sizeof (* c ), GFP_KERNEL );
278
- if (!c )
279
- return - ENOMEM ;
280
-
281
257
c -> mtd = sb -> s_mtd ;
282
258
c -> os_priv = sb ;
283
- sb -> s_fs_info = c ;
284
-
285
- ret = jffs2_parse_options (c , data );
286
- if (ret )
287
- return - EINVAL ;
288
259
289
260
/* Initialize JFFS2 superblock locks, the further initialization will
290
261
* be done later */
@@ -302,15 +273,37 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
302
273
#ifdef CONFIG_JFFS2_FS_POSIX_ACL
303
274
sb -> s_flags |= SB_POSIXACL ;
304
275
#endif
305
- ret = jffs2_do_fill_super (sb , data , silent );
306
- return ret ;
276
+ return jffs2_do_fill_super (sb , fc );
307
277
}
308
278
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 )
312
280
{
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 ;
314
307
}
315
308
316
309
static void jffs2_put_super (struct super_block * sb )
@@ -347,7 +340,8 @@ static void jffs2_kill_sb(struct super_block *sb)
347
340
static struct file_system_type jffs2_fs_type = {
348
341
.owner = THIS_MODULE ,
349
342
.name = "jffs2" ,
350
- .mount = jffs2_mount ,
343
+ .init_fs_context = jffs2_init_fs_context ,
344
+ .parameters = & jffs2_fs_parameters ,
351
345
.kill_sb = jffs2_kill_sb ,
352
346
};
353
347
MODULE_ALIAS_FS ("jffs2" );
0 commit comments