Skip to content

Commit ec10a24

Browse files
dhowellsAl Viro
authored and
Al Viro
committed
vfs: Convert jffs2 to use the new mount API
Convert the jffs2 filesystem to the new internal mount API as the old one will be obsoleted and removed. This allows greater flexibility in communication of mount parameters between userspace, the VFS and the filesystem. See Documentation/filesystems/mount_api.txt for more information. Signed-off-by: David Howells <dhowells@redhat.com> cc: David Woodhouse <dwmw2@infradead.org> cc: linux-mtd@lists.infradead.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 74f78fc commit ec10a24

File tree

3 files changed

+96
-101
lines changed

3 files changed

+96
-101
lines changed

Diff for: fs/jffs2/fs.c

+11-10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/sched.h>
1818
#include <linux/cred.h>
1919
#include <linux/fs.h>
20+
#include <linux/fs_context.h>
2021
#include <linux/list.h>
2122
#include <linux/mtd/mtd.h>
2223
#include <linux/pagemap.h>
@@ -184,7 +185,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
184185
if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) {
185186
truncate_setsize(inode, iattr->ia_size);
186187
inode->i_blocks = (inode->i_size + 511) >> 9;
187-
}
188+
}
188189

189190
return 0;
190191
}
@@ -391,7 +392,7 @@ void jffs2_dirty_inode(struct inode *inode, int flags)
391392
jffs2_do_setattr(inode, &iattr);
392393
}
393394

394-
int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data)
395+
int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc)
395396
{
396397
struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
397398

@@ -409,10 +410,10 @@ int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data)
409410
mutex_unlock(&c->alloc_sem);
410411
}
411412

412-
if (!(*flags & SB_RDONLY))
413+
if (!(fc->sb_flags & SB_RDONLY))
413414
jffs2_start_garbage_collect_thread(c);
414415

415-
*flags |= SB_NOATIME;
416+
fc->sb_flags |= SB_NOATIME;
416417
return 0;
417418
}
418419

@@ -509,7 +510,7 @@ static int calculate_inocache_hashsize(uint32_t flash_size)
509510
return hashsize;
510511
}
511512

512-
int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
513+
int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc)
513514
{
514515
struct jffs2_sb_info *c;
515516
struct inode *root_i;
@@ -524,11 +525,11 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
524525

525526
#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
526527
if (c->mtd->type == MTD_NANDFLASH) {
527-
pr_err("Cannot operate on NAND flash unless jffs2 NAND support is compiled in\n");
528+
errorf(fc, "Cannot operate on NAND flash unless jffs2 NAND support is compiled in");
528529
return -EINVAL;
529530
}
530531
if (c->mtd->type == MTD_DATAFLASH) {
531-
pr_err("Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in\n");
532+
errorf(fc, "Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in");
532533
return -EINVAL;
533534
}
534535
#endif
@@ -542,12 +543,12 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
542543
*/
543544
if ((c->sector_size * blocks) != c->flash_size) {
544545
c->flash_size = c->sector_size * blocks;
545-
pr_info("Flash size not aligned to erasesize, reducing to %dKiB\n",
546-
c->flash_size / 1024);
546+
infof(fc, "Flash size not aligned to erasesize, reducing to %dKiB",
547+
c->flash_size / 1024);
547548
}
548549

549550
if (c->flash_size < 5*c->sector_size) {
550-
pr_err("Too few erase blocks (%d)\n",
551+
errorf(fc, "Too few erase blocks (%d)",
551552
c->flash_size / c->sector_size);
552553
return -EINVAL;
553554
}

Diff for: fs/jffs2/os-linux.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ void jffs2_dirty_inode(struct inode *inode, int flags);
172172
struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode,
173173
struct jffs2_raw_inode *ri);
174174
int jffs2_statfs (struct dentry *, struct kstatfs *);
175-
int jffs2_do_remount_fs(struct super_block *, int *, char *);
176-
int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
175+
int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc);
176+
int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc);
177177
void jffs2_gc_release_inode(struct jffs2_sb_info *c,
178178
struct jffs2_inode_info *f);
179179
struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,

Diff for: fs/jffs2/super.c

+83-89
Original file line numberDiff line numberDiff line change
@@ -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>
@@ -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
*/
164165
enum {
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

252234
static 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

316309
static void jffs2_put_super (struct super_block *sb)
@@ -347,7 +340,8 @@ static void jffs2_kill_sb(struct super_block *sb)
347340
static 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
};
353347
MODULE_ALIAS_FS("jffs2");

0 commit comments

Comments
 (0)