summaryrefslogtreecommitdiffstats
path: root/fs/ramfs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-19 13:06:57 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-19 13:06:57 -0400
commitbc7d9aee3f3ce0c0633c20ea55b81efb3ca7984d (patch)
tree24e17a197a1b84d3576a69cd8955fbf8b8a9dc76 /fs/ramfs/inode.c
parentcfb82e1df8b7c76991ea12958855897c2fb4debc (diff)
parent74983ac20aeafc88d9ceed64a8bf2a9024c488d5 (diff)
Merge branch 'work.mount2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc mount API conversions from Al Viro: "Conversions to new API for shmem and friends and for mount_mtd()-using filesystems. As for the rest of the mount API conversions in -next, some of them belong in the individual trees (e.g. binderfs one should definitely go through android folks, after getting redone on top of their changes). I'm going to drop those and send the rest (trivial ones + stuff ACKed by maintainers) in a separate series - by that point they are independent from each other. Some stuff has already migrated into individual trees (NFS conversion, for example, or FUSE stuff, etc.); those presumably will go through the regular merges from corresponding trees." * 'work.mount2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: vfs: Make fs_parse() handle fs_param_is_fd-type params better vfs: Convert ramfs, shmem, tmpfs, devtmpfs, rootfs to use the new mount API shmem_parse_one(): switch to use of fs_parse() shmem_parse_options(): take handling a single option into a helper shmem_parse_options(): don't bother with mpol in separate variable shmem_parse_options(): use a separate structure to keep the results make shmem_fill_super() static make ramfs_fill_super() static devtmpfs: don't mix {ramfs,shmem}_fill_super() with mount_single() vfs: Convert squashfs to use the new mount API mtd: Kill mount_mtd() vfs: Convert jffs2 to use the new mount API vfs: Convert cramfs to use the new mount API vfs: Convert romfs to use the new mount API vfs: Add a single-or-reconfig keying to vfs_get_super()
Diffstat (limited to 'fs/ramfs/inode.c')
-rw-r--r--fs/ramfs/inode.c99
1 files changed, 58 insertions, 41 deletions
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index 733c6b4193dc..d82636e8eb65 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -36,6 +36,8 @@
36#include <linux/magic.h> 36#include <linux/magic.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/fs_context.h>
40#include <linux/fs_parser.h>
39#include "internal.h" 41#include "internal.h"
40 42
41struct ramfs_mount_opts { 43struct ramfs_mount_opts {
@@ -175,62 +177,52 @@ static const struct super_operations ramfs_ops = {
175 .show_options = ramfs_show_options, 177 .show_options = ramfs_show_options,
176}; 178};
177 179
178enum { 180enum ramfs_param {
179 Opt_mode, 181 Opt_mode,
180 Opt_err
181}; 182};
182 183
183static const match_table_t tokens = { 184static const struct fs_parameter_spec ramfs_param_specs[] = {
184 {Opt_mode, "mode=%o"}, 185 fsparam_u32oct("mode", Opt_mode),
185 {Opt_err, NULL} 186 {}
186}; 187};
187 188
188static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts) 189const struct fs_parameter_description ramfs_fs_parameters = {
190 .name = "ramfs",
191 .specs = ramfs_param_specs,
192};
193
194static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
189{ 195{
190 substring_t args[MAX_OPT_ARGS]; 196 struct fs_parse_result result;
191 int option; 197 struct ramfs_fs_info *fsi = fc->s_fs_info;
192 int token; 198 int opt;
193 char *p; 199
194 200 opt = fs_parse(fc, &ramfs_fs_parameters, param, &result);
195 opts->mode = RAMFS_DEFAULT_MODE; 201 if (opt < 0) {
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;
208 /* 202 /*
209 * We might like to report bad mount options here; 203 * We might like to report bad mount options here;
210 * but traditionally ramfs has ignored all mount options, 204 * but traditionally ramfs has ignored all mount options,
211 * and as it is used as a !CONFIG_SHMEM simple substitute 205 * and as it is used as a !CONFIG_SHMEM simple substitute
212 * for tmpfs, better continue to ignore other mount options. 206 * for tmpfs, better continue to ignore other mount options.
213 */ 207 */
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;
215 } 217 }
216 218
217 return 0; 219 return 0;
218} 220}
219 221
220int ramfs_fill_super(struct super_block *sb, void *data, int silent) 222static int ramfs_fill_super(struct super_block *sb, struct fs_context *fc)
221{ 223{
222 struct ramfs_fs_info *fsi; 224 struct ramfs_fs_info *fsi = sb->s_fs_info;
223 struct inode *inode; 225 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;
234 226
235 sb->s_maxbytes = MAX_LFS_FILESIZE; 227 sb->s_maxbytes = MAX_LFS_FILESIZE;
236 sb->s_blocksize = PAGE_SIZE; 228 sb->s_blocksize = PAGE_SIZE;
@@ -247,10 +239,34 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent)
247 return 0; 239 return 0;
248} 240}
249 241
250struct dentry *ramfs_mount(struct file_system_type *fs_type, 242static int ramfs_get_tree(struct fs_context *fc)
251 int flags, const char *dev_name, void *data)
252{ 243{
253 return mount_nodev(fs_type, flags, data, ramfs_fill_super); 244 return get_tree_nodev(fc, ramfs_fill_super);
245}
246
247static void ramfs_free_fc(struct fs_context *fc)
248{
249 kfree(fc->s_fs_info);
250}
251
252static 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
258int 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;
254} 270}
255 271
256static void ramfs_kill_sb(struct super_block *sb) 272static void ramfs_kill_sb(struct super_block *sb)
@@ -261,7 +277,8 @@ static void ramfs_kill_sb(struct super_block *sb)
261 277
262static struct file_system_type ramfs_fs_type = { 278static struct file_system_type ramfs_fs_type = {
263 .name = "ramfs", 279 .name = "ramfs",
264 .mount = ramfs_mount, 280 .init_fs_context = ramfs_init_fs_context,
281 .parameters = &ramfs_fs_parameters,
265 .kill_sb = ramfs_kill_sb, 282 .kill_sb = ramfs_kill_sb,
266 .fs_flags = FS_USERNS_MOUNT, 283 .fs_flags = FS_USERNS_MOUNT,
267}; 284};