hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/jffs2/super.c
....@@ -19,7 +19,8 @@
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>
....@@ -44,18 +45,12 @@
4445 return &f->vfs_inode;
4546 }
4647
47
-static void jffs2_i_callback(struct rcu_head *head)
48
+static void jffs2_free_inode(struct inode *inode)
4849 {
49
- struct inode *inode = container_of(head, struct inode, i_rcu);
5050 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
5151
5252 kfree(f->target);
5353 kmem_cache_free(jffs2_inode_cachep, f);
54
-}
55
-
56
-static void jffs2_destroy_inode(struct inode *inode)
57
-{
58
- call_rcu(&inode->i_rcu, jffs2_i_callback);
5954 }
6055
6156 static void jffs2_i_init_once(void *foo)
....@@ -93,7 +88,7 @@
9388
9489 if (opts->override_compr)
9590 seq_printf(s, ",compr=%s", jffs2_compr_name(opts->compr));
96
- if (opts->rp_size)
91
+ if (opts->set_rp_size)
9792 seq_printf(s, ",rp_size=%u", opts->rp_size / 1024);
9893
9994 return 0;
....@@ -163,105 +158,93 @@
163158 /*
164159 * JFFS2 mount options.
165160 *
161
+ * Opt_source: The source device
166162 * Opt_override_compr: override default compressor
167163 * Opt_rp_size: size of reserved pool in KiB
168
- * Opt_err: just end of array marker
169164 */
170165 enum {
171166 Opt_override_compr,
172167 Opt_rp_size,
173
- Opt_err,
174168 };
175169
176
-static const match_table_t tokens = {
177
- {Opt_override_compr, "compr=%s"},
178
- {Opt_rp_size, "rp_size=%u"},
179
- {Opt_err, NULL},
180
-};
181
-
182
-static int jffs2_parse_options(struct jffs2_sb_info *c, char *data)
183
-{
184
- substring_t args[MAX_OPT_ARGS];
185
- char *p, *name;
186
- unsigned int opt;
187
-
188
- if (!data)
189
- return 0;
190
-
191
- while ((p = strsep(&data, ","))) {
192
- int token;
193
-
194
- if (!*p)
195
- continue;
196
-
197
- token = match_token(p, tokens, args);
198
- switch (token) {
199
- case Opt_override_compr:
200
- name = match_strdup(&args[0]);
201
-
202
- if (!name)
203
- return -ENOMEM;
204
- if (!strcmp(name, "none"))
205
- c->mount_opts.compr = JFFS2_COMPR_MODE_NONE;
170
+static const struct constant_table jffs2_param_compr[] = {
171
+ {"none", JFFS2_COMPR_MODE_NONE },
206172 #ifdef CONFIG_JFFS2_LZO
207
- else if (!strcmp(name, "lzo"))
208
- c->mount_opts.compr = JFFS2_COMPR_MODE_FORCELZO;
173
+ {"lzo", JFFS2_COMPR_MODE_FORCELZO },
209174 #endif
210175 #ifdef CONFIG_JFFS2_ZLIB
211
- else if (!strcmp(name, "zlib"))
212
- c->mount_opts.compr =
213
- JFFS2_COMPR_MODE_FORCEZLIB;
176
+ {"zlib", JFFS2_COMPR_MODE_FORCEZLIB },
214177 #endif
215
- else {
216
- pr_err("Error: unknown compressor \"%s\"\n",
217
- name);
218
- kfree(name);
219
- return -EINVAL;
220
- }
221
- kfree(name);
222
- c->mount_opts.override_compr = true;
223
- break;
224
- case Opt_rp_size:
225
- if (match_int(&args[0], &opt))
226
- return -EINVAL;
227
- opt *= 1024;
228
- if (opt > c->mtd->size) {
229
- pr_warn("Too large reserve pool specified, max "
230
- "is %llu KB\n", c->mtd->size / 1024);
231
- return -EINVAL;
232
- }
233
- c->mount_opts.rp_size = opt;
234
- break;
235
- default:
236
- pr_err("Error: unrecognized mount option '%s' or missing value\n",
237
- p);
238
- return -EINVAL;
239
- }
178
+ {}
179
+};
180
+
181
+static const struct fs_parameter_spec jffs2_fs_parameters[] = {
182
+ fsparam_enum ("compr", Opt_override_compr, jffs2_param_compr),
183
+ fsparam_u32 ("rp_size", Opt_rp_size),
184
+ {}
185
+};
186
+
187
+static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
188
+{
189
+ struct fs_parse_result result;
190
+ struct jffs2_sb_info *c = fc->s_fs_info;
191
+ int opt;
192
+
193
+ opt = fs_parse(fc, jffs2_fs_parameters, param, &result);
194
+ if (opt < 0)
195
+ return opt;
196
+
197
+ switch (opt) {
198
+ case Opt_override_compr:
199
+ c->mount_opts.compr = result.uint_32;
200
+ c->mount_opts.override_compr = true;
201
+ break;
202
+ case Opt_rp_size:
203
+ if (result.uint_32 > UINT_MAX / 1024)
204
+ return invalf(fc, "jffs2: rp_size unrepresentable");
205
+ c->mount_opts.rp_size = result.uint_32 * 1024;
206
+ c->mount_opts.set_rp_size = true;
207
+ break;
208
+ default:
209
+ return -EINVAL;
240210 }
241211
242212 return 0;
243213 }
244214
245
-static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data)
215
+static inline void jffs2_update_mount_opts(struct fs_context *fc)
246216 {
247
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
248
- int err;
217
+ struct jffs2_sb_info *new_c = fc->s_fs_info;
218
+ struct jffs2_sb_info *c = JFFS2_SB_INFO(fc->root->d_sb);
219
+
220
+ mutex_lock(&c->alloc_sem);
221
+ if (new_c->mount_opts.override_compr) {
222
+ c->mount_opts.override_compr = new_c->mount_opts.override_compr;
223
+ c->mount_opts.compr = new_c->mount_opts.compr;
224
+ }
225
+ if (new_c->mount_opts.set_rp_size) {
226
+ c->mount_opts.set_rp_size = new_c->mount_opts.set_rp_size;
227
+ c->mount_opts.rp_size = new_c->mount_opts.rp_size;
228
+ }
229
+ mutex_unlock(&c->alloc_sem);
230
+}
231
+
232
+static int jffs2_reconfigure(struct fs_context *fc)
233
+{
234
+ struct super_block *sb = fc->root->d_sb;
249235
250236 sync_filesystem(sb);
251
- err = jffs2_parse_options(c, data);
252
- if (err)
253
- return -EINVAL;
237
+ jffs2_update_mount_opts(fc);
254238
255
- return jffs2_do_remount_fs(sb, flags, data);
239
+ return jffs2_do_remount_fs(sb, fc);
256240 }
257241
258242 static const struct super_operations jffs2_super_operations =
259243 {
260244 .alloc_inode = jffs2_alloc_inode,
261
- .destroy_inode =jffs2_destroy_inode,
245
+ .free_inode = jffs2_free_inode,
262246 .put_super = jffs2_put_super,
263247 .statfs = jffs2_statfs,
264
- .remount_fs = jffs2_remount_fs,
265248 .evict_inode = jffs2_evict_inode,
266249 .dirty_inode = jffs2_dirty_inode,
267250 .show_options = jffs2_show_options,
....@@ -271,26 +254,20 @@
271254 /*
272255 * fill in the superblock
273256 */
274
-static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
257
+static int jffs2_fill_super(struct super_block *sb, struct fs_context *fc)
275258 {
276
- struct jffs2_sb_info *c;
277
- int ret;
259
+ struct jffs2_sb_info *c = sb->s_fs_info;
278260
279261 jffs2_dbg(1, "jffs2_get_sb_mtd():"
280262 " New superblock for device %d (\"%s\")\n",
281263 sb->s_mtd->index, sb->s_mtd->name);
282264
283
- c = kzalloc(sizeof(*c), GFP_KERNEL);
284
- if (!c)
285
- return -ENOMEM;
286
-
287265 c->mtd = sb->s_mtd;
288266 c->os_priv = sb;
289
- sb->s_fs_info = c;
290267
291
- ret = jffs2_parse_options(c, data);
292
- if (ret)
293
- return -EINVAL;
268
+ if (c->mount_opts.rp_size > c->mtd->size)
269
+ return invalf(fc, "jffs2: Too large reserve pool specified, max is %llu KB",
270
+ c->mtd->size / 1024);
294271
295272 /* Initialize JFFS2 superblock locks, the further initialization will
296273 * be done later */
....@@ -308,15 +285,37 @@
308285 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
309286 sb->s_flags |= SB_POSIXACL;
310287 #endif
311
- ret = jffs2_do_fill_super(sb, data, silent);
312
- return ret;
288
+ return jffs2_do_fill_super(sb, fc);
313289 }
314290
315
-static struct dentry *jffs2_mount(struct file_system_type *fs_type,
316
- int flags, const char *dev_name,
317
- void *data)
291
+static int jffs2_get_tree(struct fs_context *fc)
318292 {
319
- return mount_mtd(fs_type, flags, dev_name, data, jffs2_fill_super);
293
+ return get_tree_mtd(fc, jffs2_fill_super);
294
+}
295
+
296
+static void jffs2_free_fc(struct fs_context *fc)
297
+{
298
+ kfree(fc->s_fs_info);
299
+}
300
+
301
+static const struct fs_context_operations jffs2_context_ops = {
302
+ .free = jffs2_free_fc,
303
+ .parse_param = jffs2_parse_param,
304
+ .get_tree = jffs2_get_tree,
305
+ .reconfigure = jffs2_reconfigure,
306
+};
307
+
308
+static int jffs2_init_fs_context(struct fs_context *fc)
309
+{
310
+ struct jffs2_sb_info *ctx;
311
+
312
+ ctx = kzalloc(sizeof(struct jffs2_sb_info), GFP_KERNEL);
313
+ if (!ctx)
314
+ return -ENOMEM;
315
+
316
+ fc->s_fs_info = ctx;
317
+ fc->ops = &jffs2_context_ops;
318
+ return 0;
320319 }
321320
322321 static void jffs2_put_super (struct super_block *sb)
....@@ -353,7 +352,8 @@
353352 static struct file_system_type jffs2_fs_type = {
354353 .owner = THIS_MODULE,
355354 .name = "jffs2",
356
- .mount = jffs2_mount,
355
+ .init_fs_context = jffs2_init_fs_context,
356
+ .parameters = jffs2_fs_parameters,
357357 .kill_sb = jffs2_kill_sb,
358358 };
359359 MODULE_ALIAS_FS("jffs2");
....@@ -439,3 +439,4 @@
439439 MODULE_AUTHOR("Red Hat, Inc.");
440440 MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
441441 // the sake of this tag. It's Free Software.
442
+MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY);