Skip to content

Commit f323562

Browse files
dhowellsAl Viro
authored andcommitted
vfs: Convert ramfs, shmem, tmpfs, devtmpfs, rootfs to use the new mount API
Convert the ramfs, shmem, tmpfs, devtmpfs and rootfs filesystems 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. Note that tmpfs is slightly tricky as it can contain embedded commas, so it can't be trivially split up using strsep() to break on commas in generic_parse_monolithic(). Instead, tmpfs has to supply its own generic parser. However, if tmpfs changes, then devtmpfs and rootfs, which are wrappers around tmpfs or ramfs, must change too - and thus so must ramfs, so these had to be converted also. [AV: rewritten] Signed-off-by: David Howells <dhowells@redhat.com> cc: Hugh Dickins <hughd@google.com> cc: linux-mm@kvack.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 626c392 commit f323562

File tree

6 files changed

+180
-139
lines changed

6 files changed

+180
-139
lines changed

drivers/base/devtmpfs.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,15 @@ static struct dentry *public_dev_mount(struct file_system_type *fs_type, int fla
6767
return dget(s->s_root);
6868
}
6969

70-
static struct dentry *dev_mount(struct file_system_type *fs_type, int flags,
71-
const char *dev_name, void *data)
72-
{
70+
static struct file_system_type internal_fs_type = {
71+
.name = "devtmpfs",
7372
#ifdef CONFIG_TMPFS
74-
return shmem_mount(fs_type, flags, dev_name, data);
73+
.init_fs_context = shmem_init_fs_context,
74+
.parameters = &shmem_fs_parameters,
7575
#else
76-
return ramfs_mount(fs_type, flags, dev_name, data);
76+
.init_fs_context = ramfs_init_fs_context,
77+
.parameters = &ramfs_fs_parameters,
7778
#endif
78-
}
79-
80-
static struct file_system_type internal_fs_type = {
81-
.name = "devtmpfs",
82-
.mount = dev_mount,
8379
.kill_sb = kill_litter_super,
8480
};
8581

fs/ramfs/inode.c

Lines changed: 58 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include <linux/magic.h>
3737
#include <linux/slab.h>
3838
#include <linux/uaccess.h>
39+
#include <linux/fs_context.h>
40+
#include <linux/fs_parser.h>
3941
#include "internal.h"
4042

4143
struct ramfs_mount_opts {
@@ -175,62 +177,52 @@ static const struct super_operations ramfs_ops = {
175177
.show_options = ramfs_show_options,
176178
};
177179

178-
enum {
180+
enum ramfs_param {
179181
Opt_mode,
180-
Opt_err
181182
};
182183

183-
static const match_table_t tokens = {
184-
{Opt_mode, "mode=%o"},
185-
{Opt_err, NULL}
184+
static const struct fs_parameter_spec ramfs_param_specs[] = {
185+
fsparam_u32oct("mode", Opt_mode),
186+
{}
186187
};
187188

188-
static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
189+
const struct fs_parameter_description ramfs_fs_parameters = {
190+
.name = "ramfs",
191+
.specs = ramfs_param_specs,
192+
};
193+
194+
static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
189195
{
190-
substring_t args[MAX_OPT_ARGS];
191-
int option;
192-
int token;
193-
char *p;
194-
195-
opts->mode = RAMFS_DEFAULT_MODE;
196-
197-
while ((p = strsep(&data, ",")) != NULL) {
198-
if (!*p)
199-
continue;
200-
201-
token = match_token(p, tokens, args);
202-
switch (token) {
203-
case Opt_mode:
204-
if (match_octal(&args[0], &option))
205-
return -EINVAL;
206-
opts->mode = option & S_IALLUGO;
207-
break;
196+
struct fs_parse_result result;
197+
struct ramfs_fs_info *fsi = fc->s_fs_info;
198+
int opt;
199+
200+
opt = fs_parse(fc, &ramfs_fs_parameters, param, &result);
201+
if (opt < 0) {
208202
/*
209203
* We might like to report bad mount options here;
210204
* but traditionally ramfs has ignored all mount options,
211205
* and as it is used as a !CONFIG_SHMEM simple substitute
212206
* for tmpfs, better continue to ignore other mount options.
213207
*/
214-
}
208+
if (opt == -ENOPARAM)
209+
opt = 0;
210+
return opt;
211+
}
212+
213+
switch (opt) {
214+
case Opt_mode:
215+
fsi->mount_opts.mode = result.uint_32 & S_IALLUGO;
216+
break;
215217
}
216218

217219
return 0;
218220
}
219221

220-
static int ramfs_fill_super(struct super_block *sb, void *data, int silent)
222+
static int ramfs_fill_super(struct super_block *sb, struct fs_context *fc)
221223
{
222-
struct ramfs_fs_info *fsi;
224+
struct ramfs_fs_info *fsi = sb->s_fs_info;
223225
struct inode *inode;
224-
int err;
225-
226-
fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
227-
sb->s_fs_info = fsi;
228-
if (!fsi)
229-
return -ENOMEM;
230-
231-
err = ramfs_parse_options(data, &fsi->mount_opts);
232-
if (err)
233-
return err;
234226

235227
sb->s_maxbytes = MAX_LFS_FILESIZE;
236228
sb->s_blocksize = PAGE_SIZE;
@@ -247,10 +239,34 @@ static int ramfs_fill_super(struct super_block *sb, void *data, int silent)
247239
return 0;
248240
}
249241

250-
struct dentry *ramfs_mount(struct file_system_type *fs_type,
251-
int flags, const char *dev_name, void *data)
242+
static int ramfs_get_tree(struct fs_context *fc)
252243
{
253-
return mount_nodev(fs_type, flags, data, ramfs_fill_super);
244+
return get_tree_nodev(fc, ramfs_fill_super);
245+
}
246+
247+
static void ramfs_free_fc(struct fs_context *fc)
248+
{
249+
kfree(fc->s_fs_info);
250+
}
251+
252+
static const struct fs_context_operations ramfs_context_ops = {
253+
.free = ramfs_free_fc,
254+
.parse_param = ramfs_parse_param,
255+
.get_tree = ramfs_get_tree,
256+
};
257+
258+
int ramfs_init_fs_context(struct fs_context *fc)
259+
{
260+
struct ramfs_fs_info *fsi;
261+
262+
fsi = kzalloc(sizeof(*fsi), GFP_KERNEL);
263+
if (!fsi)
264+
return -ENOMEM;
265+
266+
fsi->mount_opts.mode = RAMFS_DEFAULT_MODE;
267+
fc->s_fs_info = fsi;
268+
fc->ops = &ramfs_context_ops;
269+
return 0;
254270
}
255271

256272
static void ramfs_kill_sb(struct super_block *sb)
@@ -261,7 +277,8 @@ static void ramfs_kill_sb(struct super_block *sb)
261277

262278
static struct file_system_type ramfs_fs_type = {
263279
.name = "ramfs",
264-
.mount = ramfs_mount,
280+
.init_fs_context = ramfs_init_fs_context,
281+
.parameters = &ramfs_fs_parameters,
265282
.kill_sb = ramfs_kill_sb,
266283
.fs_flags = FS_USERNS_MOUNT,
267284
};

include/linux/ramfs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44

55
struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
66
umode_t mode, dev_t dev);
7-
extern struct dentry *ramfs_mount(struct file_system_type *fs_type,
8-
int flags, const char *dev_name, void *data);
7+
extern int ramfs_init_fs_context(struct fs_context *fc);
98

109
#ifdef CONFIG_MMU
1110
static inline int
@@ -17,6 +16,7 @@ ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
1716
extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
1817
#endif
1918

19+
extern const struct fs_parameter_description ramfs_fs_parameters;
2020
extern const struct file_operations ramfs_file_operations;
2121
extern const struct vm_operations_struct generic_file_vm_ops;
2222

include/linux/shmem_fs.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
4949
/*
5050
* Functions in mm/shmem.c called directly from elsewhere:
5151
*/
52+
extern const struct fs_parameter_description shmem_fs_parameters;
5253
extern int shmem_init(void);
53-
extern struct dentry *shmem_mount(struct file_system_type *fs_type,
54-
int flags, const char *dev_name, void *data);
54+
extern int shmem_init_fs_context(struct fs_context *fc);
5555
extern struct file *shmem_file_setup(const char *name,
5656
loff_t size, unsigned long flags);
5757
extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,

init/do_mounts.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -627,18 +627,17 @@ void __init prepare_namespace(void)
627627
}
628628

629629
static bool is_tmpfs;
630-
static struct dentry *rootfs_mount(struct file_system_type *fs_type,
631-
int flags, const char *dev_name, void *data)
630+
static int rootfs_init_fs_context(struct fs_context *fc)
632631
{
633632
if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
634-
return shmem_mount(fs_type, flags, dev_name, data);
633+
return shmem_init_fs_context(fc);
635634

636-
return ramfs_mount(fs_type, flags, dev_name, data);
635+
return ramfs_init_fs_context(fc);
637636
}
638637

639638
struct file_system_type rootfs_fs_type = {
640639
.name = "rootfs",
641-
.mount = rootfs_mount,
640+
.init_fs_context = rootfs_init_fs_context,
642641
.kill_sb = kill_litter_super,
643642
};
644643

0 commit comments

Comments
 (0)