summaryrefslogtreecommitdiffstats
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
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()
-rw-r--r--drivers/base/devtmpfs.c38
-rw-r--r--drivers/mtd/mtdsuper.c189
-rw-r--r--fs/cramfs/inode.c69
-rw-r--r--fs/fs_parser.c18
-rw-r--r--fs/jffs2/fs.c21
-rw-r--r--fs/jffs2/os-linux.h4
-rw-r--r--fs/jffs2/super.c172
-rw-r--r--fs/ramfs/inode.c99
-rw-r--r--fs/romfs/super.c46
-rw-r--r--fs/squashfs/super.c100
-rw-r--r--fs/super.c35
-rw-r--r--include/linux/fs_context.h4
-rw-r--r--include/linux/mtd/super.h3
-rw-r--r--include/linux/ramfs.h6
-rw-r--r--include/linux/shmem_fs.h3
-rw-r--r--init/do_mounts.c11
-rw-r--r--mm/shmem.c385
17 files changed, 609 insertions, 594 deletions
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index ba5c80903efe..30d0523014e0 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -56,20 +56,32 @@ static int __init mount_param(char *str)
56} 56}
57__setup("devtmpfs.mount=", mount_param); 57__setup("devtmpfs.mount=", mount_param);
58 58
59static struct dentry *dev_mount(struct file_system_type *fs_type, int flags, 59static struct vfsmount *mnt;
60
61static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags,
60 const char *dev_name, void *data) 62 const char *dev_name, void *data)
61{ 63{
64 struct super_block *s = mnt->mnt_sb;
65 atomic_inc(&s->s_active);
66 down_write(&s->s_umount);
67 return dget(s->s_root);
68}
69
70static struct file_system_type internal_fs_type = {
71 .name = "devtmpfs",
62#ifdef CONFIG_TMPFS 72#ifdef CONFIG_TMPFS
63 return mount_single(fs_type, flags, data, shmem_fill_super); 73 .init_fs_context = shmem_init_fs_context,
74 .parameters = &shmem_fs_parameters,
64#else 75#else
65 return mount_single(fs_type, flags, data, ramfs_fill_super); 76 .init_fs_context = ramfs_init_fs_context,
77 .parameters = &ramfs_fs_parameters,
66#endif 78#endif
67} 79 .kill_sb = kill_litter_super,
80};
68 81
69static struct file_system_type dev_fs_type = { 82static struct file_system_type dev_fs_type = {
70 .name = "devtmpfs", 83 .name = "devtmpfs",
71 .mount = dev_mount, 84 .mount = public_dev_mount,
72 .kill_sb = kill_litter_super,
73}; 85};
74 86
75#ifdef CONFIG_BLOCK 87#ifdef CONFIG_BLOCK
@@ -378,12 +390,11 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid,
378 390
379static int devtmpfsd(void *p) 391static int devtmpfsd(void *p)
380{ 392{
381 char options[] = "mode=0755";
382 int *err = p; 393 int *err = p;
383 *err = ksys_unshare(CLONE_NEWNS); 394 *err = ksys_unshare(CLONE_NEWNS);
384 if (*err) 395 if (*err)
385 goto out; 396 goto out;
386 *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); 397 *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
387 if (*err) 398 if (*err)
388 goto out; 399 goto out;
389 ksys_chdir("/.."); /* will traverse into overmounted root */ 400 ksys_chdir("/.."); /* will traverse into overmounted root */
@@ -420,7 +431,16 @@ out:
420 */ 431 */
421int __init devtmpfs_init(void) 432int __init devtmpfs_init(void)
422{ 433{
423 int err = register_filesystem(&dev_fs_type); 434 char opts[] = "mode=0755";
435 int err;
436
437 mnt = vfs_kern_mount(&internal_fs_type, 0, "devtmpfs", opts);
438 if (IS_ERR(mnt)) {
439 printk(KERN_ERR "devtmpfs: unable to create devtmpfs %ld\n",
440 PTR_ERR(mnt));
441 return PTR_ERR(mnt);
442 }
443 err = register_filesystem(&dev_fs_type);
424 if (err) { 444 if (err) {
425 printk(KERN_ERR "devtmpfs: unable to register devtmpfs " 445 printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
426 "type %i\n", err); 446 "type %i\n", err);
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c
index 3f9a3b7b12c5..c3e2098372f2 100644
--- a/drivers/mtd/mtdsuper.c
+++ b/drivers/mtd/mtdsuper.c
@@ -194,195 +194,6 @@ int get_tree_mtd(struct fs_context *fc,
194EXPORT_SYMBOL_GPL(get_tree_mtd); 194EXPORT_SYMBOL_GPL(get_tree_mtd);
195 195
196/* 196/*
197 * compare superblocks to see if they're equivalent
198 * - they are if the underlying MTD device is the same
199 */
200static int get_sb_mtd_compare(struct super_block *sb, void *_mtd)
201{
202 struct mtd_info *mtd = _mtd;
203
204 if (sb->s_mtd == mtd) {
205 pr_debug("MTDSB: Match on device %d (\"%s\")\n",
206 mtd->index, mtd->name);
207 return 1;
208 }
209
210 pr_debug("MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n",
211 sb->s_mtd->index, sb->s_mtd->name, mtd->index, mtd->name);
212 return 0;
213}
214
215/*
216 * mark the superblock by the MTD device it is using
217 * - set the device number to be the correct MTD block device for pesuperstence
218 * of NFS exports
219 */
220static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
221{
222 struct mtd_info *mtd = _mtd;
223
224 sb->s_mtd = mtd;
225 sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
226 sb->s_bdi = bdi_get(mtd_bdi);
227
228 return 0;
229}
230
231/*
232 * get a superblock on an MTD-backed filesystem
233 */
234static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags,
235 const char *dev_name, void *data,
236 struct mtd_info *mtd,
237 int (*fill_super)(struct super_block *, void *, int))
238{
239 struct super_block *sb;
240 int ret;
241
242 sb = sget(fs_type, get_sb_mtd_compare, get_sb_mtd_set, flags, mtd);
243 if (IS_ERR(sb))
244 goto out_error;
245
246 if (sb->s_root)
247 goto already_mounted;
248
249 /* fresh new superblock */
250 pr_debug("MTDSB: New superblock for device %d (\"%s\")\n",
251 mtd->index, mtd->name);
252
253 ret = fill_super(sb, data, flags & SB_SILENT ? 1 : 0);
254 if (ret < 0) {
255 deactivate_locked_super(sb);
256 return ERR_PTR(ret);
257 }
258
259 /* go */
260 sb->s_flags |= SB_ACTIVE;
261 return dget(sb->s_root);
262
263 /* new mountpoint for an already mounted superblock */
264already_mounted:
265 pr_debug("MTDSB: Device %d (\"%s\") is already mounted\n",
266 mtd->index, mtd->name);
267 put_mtd_device(mtd);
268 return dget(sb->s_root);
269
270out_error:
271 put_mtd_device(mtd);
272 return ERR_CAST(sb);
273}
274
275/*
276 * get a superblock on an MTD-backed filesystem by MTD device number
277 */
278static struct dentry *mount_mtd_nr(struct file_system_type *fs_type, int flags,
279 const char *dev_name, void *data, int mtdnr,
280 int (*fill_super)(struct super_block *, void *, int))
281{
282 struct mtd_info *mtd;
283
284 mtd = get_mtd_device(NULL, mtdnr);
285 if (IS_ERR(mtd)) {
286 pr_debug("MTDSB: Device #%u doesn't appear to exist\n", mtdnr);
287 return ERR_CAST(mtd);
288 }
289
290 return mount_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super);
291}
292
293/*
294 * set up an MTD-based superblock
295 */
296struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
297 const char *dev_name, void *data,
298 int (*fill_super)(struct super_block *, void *, int))
299{
300#ifdef CONFIG_BLOCK
301 struct block_device *bdev;
302 int ret, major;
303#endif
304 int mtdnr;
305
306 if (!dev_name)
307 return ERR_PTR(-EINVAL);
308
309 pr_debug("MTDSB: dev_name \"%s\"\n", dev_name);
310
311 /* the preferred way of mounting in future; especially when
312 * CONFIG_BLOCK=n - we specify the underlying MTD device by number or
313 * by name, so that we don't require block device support to be present
314 * in the kernel. */
315 if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
316 if (dev_name[3] == ':') {
317 struct mtd_info *mtd;
318
319 /* mount by MTD device name */
320 pr_debug("MTDSB: mtd:%%s, name \"%s\"\n",
321 dev_name + 4);
322
323 mtd = get_mtd_device_nm(dev_name + 4);
324 if (!IS_ERR(mtd))
325 return mount_mtd_aux(
326 fs_type, flags,
327 dev_name, data, mtd,
328 fill_super);
329
330 printk(KERN_NOTICE "MTD:"
331 " MTD device with name \"%s\" not found.\n",
332 dev_name + 4);
333
334 } else if (isdigit(dev_name[3])) {
335 /* mount by MTD device number name */
336 char *endptr;
337
338 mtdnr = simple_strtoul(dev_name + 3, &endptr, 0);
339 if (!*endptr) {
340 /* It was a valid number */
341 pr_debug("MTDSB: mtd%%d, mtdnr %d\n",
342 mtdnr);
343 return mount_mtd_nr(fs_type, flags,
344 dev_name, data,
345 mtdnr, fill_super);
346 }
347 }
348 }
349
350#ifdef CONFIG_BLOCK
351 /* try the old way - the hack where we allowed users to mount
352 * /dev/mtdblock$(n) but didn't actually _use_ the blockdev
353 */
354 bdev = lookup_bdev(dev_name);
355 if (IS_ERR(bdev)) {
356 ret = PTR_ERR(bdev);
357 pr_debug("MTDSB: lookup_bdev() returned %d\n", ret);
358 return ERR_PTR(ret);
359 }
360 pr_debug("MTDSB: lookup_bdev() returned 0\n");
361
362 ret = -EINVAL;
363
364 major = MAJOR(bdev->bd_dev);
365 mtdnr = MINOR(bdev->bd_dev);
366 bdput(bdev);
367
368 if (major != MTD_BLOCK_MAJOR)
369 goto not_an_MTD_device;
370
371 return mount_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super);
372
373not_an_MTD_device:
374#endif /* CONFIG_BLOCK */
375
376 if (!(flags & SB_SILENT))
377 printk(KERN_NOTICE
378 "MTD: Attempt to mount non-MTD device \"%s\"\n",
379 dev_name);
380 return ERR_PTR(-EINVAL);
381}
382
383EXPORT_SYMBOL_GPL(mount_mtd);
384
385/*
386 * destroy an MTD-based superblock 197 * destroy an MTD-based superblock
387 */ 198 */
388void kill_mtd_super(struct super_block *sb) 199void kill_mtd_super(struct super_block *sb)
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 4d1d8b7761ed..d12ea28836a5 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -24,6 +24,7 @@
24#include <linux/blkdev.h> 24#include <linux/blkdev.h>
25#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
26#include <linux/mtd/super.h> 26#include <linux/mtd/super.h>
27#include <linux/fs_context.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
28#include <linux/vfs.h> 29#include <linux/vfs.h>
29#include <linux/mutex.h> 30#include <linux/mutex.h>
@@ -506,18 +507,19 @@ static void cramfs_kill_sb(struct super_block *sb)
506 kfree(sbi); 507 kfree(sbi);
507} 508}
508 509
509static int cramfs_remount(struct super_block *sb, int *flags, char *data) 510static int cramfs_reconfigure(struct fs_context *fc)
510{ 511{
511 sync_filesystem(sb); 512 sync_filesystem(fc->root->d_sb);
512 *flags |= SB_RDONLY; 513 fc->sb_flags |= SB_RDONLY;
513 return 0; 514 return 0;
514} 515}
515 516
516static int cramfs_read_super(struct super_block *sb, 517static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
517 struct cramfs_super *super, int silent) 518 struct cramfs_super *super)
518{ 519{
519 struct cramfs_sb_info *sbi = CRAMFS_SB(sb); 520 struct cramfs_sb_info *sbi = CRAMFS_SB(sb);
520 unsigned long root_offset; 521 unsigned long root_offset;
522 bool silent = fc->sb_flags & SB_SILENT;
521 523
522 /* We don't know the real size yet */ 524 /* We don't know the real size yet */
523 sbi->size = PAGE_SIZE; 525 sbi->size = PAGE_SIZE;
@@ -532,7 +534,7 @@ static int cramfs_read_super(struct super_block *sb,
532 /* check for wrong endianness */ 534 /* check for wrong endianness */
533 if (super->magic == CRAMFS_MAGIC_WEND) { 535 if (super->magic == CRAMFS_MAGIC_WEND) {
534 if (!silent) 536 if (!silent)
535 pr_err("wrong endianness\n"); 537 errorf(fc, "cramfs: wrong endianness");
536 return -EINVAL; 538 return -EINVAL;
537 } 539 }
538 540
@@ -544,22 +546,22 @@ static int cramfs_read_super(struct super_block *sb,
544 mutex_unlock(&read_mutex); 546 mutex_unlock(&read_mutex);
545 if (super->magic != CRAMFS_MAGIC) { 547 if (super->magic != CRAMFS_MAGIC) {
546 if (super->magic == CRAMFS_MAGIC_WEND && !silent) 548 if (super->magic == CRAMFS_MAGIC_WEND && !silent)
547 pr_err("wrong endianness\n"); 549 errorf(fc, "cramfs: wrong endianness");
548 else if (!silent) 550 else if (!silent)
549 pr_err("wrong magic\n"); 551 errorf(fc, "cramfs: wrong magic");
550 return -EINVAL; 552 return -EINVAL;
551 } 553 }
552 } 554 }
553 555
554 /* get feature flags first */ 556 /* get feature flags first */
555 if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) { 557 if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) {
556 pr_err("unsupported filesystem features\n"); 558 errorf(fc, "cramfs: unsupported filesystem features");
557 return -EINVAL; 559 return -EINVAL;
558 } 560 }
559 561
560 /* Check that the root inode is in a sane state */ 562 /* Check that the root inode is in a sane state */
561 if (!S_ISDIR(super->root.mode)) { 563 if (!S_ISDIR(super->root.mode)) {
562 pr_err("root is not a directory\n"); 564 errorf(fc, "cramfs: root is not a directory");
563 return -EINVAL; 565 return -EINVAL;
564 } 566 }
565 /* correct strange, hard-coded permissions of mkcramfs */ 567 /* correct strange, hard-coded permissions of mkcramfs */
@@ -578,12 +580,12 @@ static int cramfs_read_super(struct super_block *sb,
578 sbi->magic = super->magic; 580 sbi->magic = super->magic;
579 sbi->flags = super->flags; 581 sbi->flags = super->flags;
580 if (root_offset == 0) 582 if (root_offset == 0)
581 pr_info("empty filesystem"); 583 infof(fc, "cramfs: empty filesystem");
582 else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && 584 else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
583 ((root_offset != sizeof(struct cramfs_super)) && 585 ((root_offset != sizeof(struct cramfs_super)) &&
584 (root_offset != 512 + sizeof(struct cramfs_super)))) 586 (root_offset != 512 + sizeof(struct cramfs_super))))
585 { 587 {
586 pr_err("bad root offset %lu\n", root_offset); 588 errorf(fc, "cramfs: bad root offset %lu", root_offset);
587 return -EINVAL; 589 return -EINVAL;
588 } 590 }
589 591
@@ -609,8 +611,7 @@ static int cramfs_finalize_super(struct super_block *sb,
609 return 0; 611 return 0;
610} 612}
611 613
612static int cramfs_blkdev_fill_super(struct super_block *sb, void *data, 614static int cramfs_blkdev_fill_super(struct super_block *sb, struct fs_context *fc)
613 int silent)
614{ 615{
615 struct cramfs_sb_info *sbi; 616 struct cramfs_sb_info *sbi;
616 struct cramfs_super super; 617 struct cramfs_super super;
@@ -625,14 +626,13 @@ static int cramfs_blkdev_fill_super(struct super_block *sb, void *data,
625 for (i = 0; i < READ_BUFFERS; i++) 626 for (i = 0; i < READ_BUFFERS; i++)
626 buffer_blocknr[i] = -1; 627 buffer_blocknr[i] = -1;
627 628
628 err = cramfs_read_super(sb, &super, silent); 629 err = cramfs_read_super(sb, fc, &super);
629 if (err) 630 if (err)
630 return err; 631 return err;
631 return cramfs_finalize_super(sb, &super.root); 632 return cramfs_finalize_super(sb, &super.root);
632} 633}
633 634
634static int cramfs_mtd_fill_super(struct super_block *sb, void *data, 635static int cramfs_mtd_fill_super(struct super_block *sb, struct fs_context *fc)
635 int silent)
636{ 636{
637 struct cramfs_sb_info *sbi; 637 struct cramfs_sb_info *sbi;
638 struct cramfs_super super; 638 struct cramfs_super super;
@@ -654,7 +654,7 @@ static int cramfs_mtd_fill_super(struct super_block *sb, void *data,
654 654
655 pr_info("checking physical address %pap for linear cramfs image\n", 655 pr_info("checking physical address %pap for linear cramfs image\n",
656 &sbi->linear_phys_addr); 656 &sbi->linear_phys_addr);
657 err = cramfs_read_super(sb, &super, silent); 657 err = cramfs_read_super(sb, fc, &super);
658 if (err) 658 if (err)
659 return err; 659 return err;
660 660
@@ -949,32 +949,41 @@ static const struct inode_operations cramfs_dir_inode_operations = {
949}; 949};
950 950
951static const struct super_operations cramfs_ops = { 951static const struct super_operations cramfs_ops = {
952 .remount_fs = cramfs_remount,
953 .statfs = cramfs_statfs, 952 .statfs = cramfs_statfs,
954}; 953};
955 954
956static struct dentry *cramfs_mount(struct file_system_type *fs_type, int flags, 955static int cramfs_get_tree(struct fs_context *fc)
957 const char *dev_name, void *data)
958{ 956{
959 struct dentry *ret = ERR_PTR(-ENOPROTOOPT); 957 int ret = -ENOPROTOOPT;
960 958
961 if (IS_ENABLED(CONFIG_CRAMFS_MTD)) { 959 if (IS_ENABLED(CONFIG_CRAMFS_MTD)) {
962 ret = mount_mtd(fs_type, flags, dev_name, data, 960 ret = get_tree_mtd(fc, cramfs_mtd_fill_super);
963 cramfs_mtd_fill_super); 961 if (ret < 0)
964 if (!IS_ERR(ret))
965 return ret; 962 return ret;
966 } 963 }
967 if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV)) { 964 if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV))
968 ret = mount_bdev(fs_type, flags, dev_name, data, 965 ret = get_tree_bdev(fc, cramfs_blkdev_fill_super);
969 cramfs_blkdev_fill_super);
970 }
971 return ret; 966 return ret;
972} 967}
973 968
969static const struct fs_context_operations cramfs_context_ops = {
970 .get_tree = cramfs_get_tree,
971 .reconfigure = cramfs_reconfigure,
972};
973
974/*
975 * Set up the filesystem mount context.
976 */
977static int cramfs_init_fs_context(struct fs_context *fc)
978{
979 fc->ops = &cramfs_context_ops;
980 return 0;
981}
982
974static struct file_system_type cramfs_fs_type = { 983static struct file_system_type cramfs_fs_type = {
975 .owner = THIS_MODULE, 984 .owner = THIS_MODULE,
976 .name = "cramfs", 985 .name = "cramfs",
977 .mount = cramfs_mount, 986 .init_fs_context = cramfs_init_fs_context,
978 .kill_sb = cramfs_kill_sb, 987 .kill_sb = cramfs_kill_sb,
979 .fs_flags = FS_REQUIRES_DEV, 988 .fs_flags = FS_REQUIRES_DEV,
980}; 989};
diff --git a/fs/fs_parser.c b/fs/fs_parser.c
index 460ea4206fa2..d1930adce68d 100644
--- a/fs/fs_parser.c
+++ b/fs/fs_parser.c
@@ -204,9 +204,23 @@ int fs_parse(struct fs_context *fc,
204 goto okay; 204 goto okay;
205 205
206 case fs_param_is_fd: { 206 case fs_param_is_fd: {
207 if (param->type != fs_value_is_file) 207 switch (param->type) {
208 case fs_value_is_string:
209 if (!result->has_value)
210 goto bad_value;
211
212 ret = kstrtouint(param->string, 0, &result->uint_32);
213 break;
214 case fs_value_is_file:
215 result->uint_32 = param->dirfd;
216 ret = 0;
217 default:
208 goto bad_value; 218 goto bad_value;
209 goto okay; 219 }
220
221 if (result->uint_32 > INT_MAX)
222 goto bad_value;
223 goto maybe_okay;
210 } 224 }
211 225
212 case fs_param_is_blockdev: 226 case fs_param_is_blockdev:
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index d0b59d03a7a9..05fe6cf5f1ac 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -17,6 +17,7 @@
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/cred.h> 18#include <linux/cred.h>
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/fs_context.h>
20#include <linux/list.h> 21#include <linux/list.h>
21#include <linux/mtd/mtd.h> 22#include <linux/mtd/mtd.h>
22#include <linux/pagemap.h> 23#include <linux/pagemap.h>
@@ -184,7 +185,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
184 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) { 185 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) {
185 truncate_setsize(inode, iattr->ia_size); 186 truncate_setsize(inode, iattr->ia_size);
186 inode->i_blocks = (inode->i_size + 511) >> 9; 187 inode->i_blocks = (inode->i_size + 511) >> 9;
187 } 188 }
188 189
189 return 0; 190 return 0;
190} 191}
@@ -391,7 +392,7 @@ void jffs2_dirty_inode(struct inode *inode, int flags)
391 jffs2_do_setattr(inode, &iattr); 392 jffs2_do_setattr(inode, &iattr);
392} 393}
393 394
394int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data) 395int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc)
395{ 396{
396 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 397 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
397 398
@@ -409,10 +410,10 @@ int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data)
409 mutex_unlock(&c->alloc_sem); 410 mutex_unlock(&c->alloc_sem);
410 } 411 }
411 412
412 if (!(*flags & SB_RDONLY)) 413 if (!(fc->sb_flags & SB_RDONLY))
413 jffs2_start_garbage_collect_thread(c); 414 jffs2_start_garbage_collect_thread(c);
414 415
415 *flags |= SB_NOATIME; 416 fc->sb_flags |= SB_NOATIME;
416 return 0; 417 return 0;
417} 418}
418 419
@@ -509,7 +510,7 @@ static int calculate_inocache_hashsize(uint32_t flash_size)
509 return hashsize; 510 return hashsize;
510} 511}
511 512
512int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) 513int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc)
513{ 514{
514 struct jffs2_sb_info *c; 515 struct jffs2_sb_info *c;
515 struct inode *root_i; 516 struct inode *root_i;
@@ -524,11 +525,11 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
524 525
525#ifndef CONFIG_JFFS2_FS_WRITEBUFFER 526#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
526 if (c->mtd->type == MTD_NANDFLASH) { 527 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");
528 return -EINVAL; 529 return -EINVAL;
529 } 530 }
530 if (c->mtd->type == MTD_DATAFLASH) { 531 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");
532 return -EINVAL; 533 return -EINVAL;
533 } 534 }
534#endif 535#endif
@@ -542,12 +543,12 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
542 */ 543 */
543 if ((c->sector_size * blocks) != c->flash_size) { 544 if ((c->sector_size * blocks) != c->flash_size) {
544 c->flash_size = c->sector_size * blocks; 545 c->flash_size = c->sector_size * blocks;
545 pr_info("Flash size not aligned to erasesize, reducing to %dKiB\n", 546 infof(fc, "Flash size not aligned to erasesize, reducing to %dKiB",
546 c->flash_size / 1024); 547 c->flash_size / 1024);
547 } 548 }
548 549
549 if (c->flash_size < 5*c->sector_size) { 550 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)",
551 c->flash_size / c->sector_size); 552 c->flash_size / c->sector_size);
552 return -EINVAL; 553 return -EINVAL;
553 } 554 }
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index bd3d5f0ddc34..21071fc2975d 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -172,8 +172,8 @@ void jffs2_dirty_inode(struct inode *inode, int flags);
172struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, 172struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode,
173 struct jffs2_raw_inode *ri); 173 struct jffs2_raw_inode *ri);
174int jffs2_statfs (struct dentry *, struct kstatfs *); 174int jffs2_statfs (struct dentry *, struct kstatfs *);
175int jffs2_do_remount_fs(struct super_block *, int *, char *); 175int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc);
176int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); 176int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc);
177void jffs2_gc_release_inode(struct jffs2_sb_info *c, 177void jffs2_gc_release_inode(struct jffs2_sb_info *c,
178 struct jffs2_inode_info *f); 178 struct jffs2_inode_info *f);
179struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, 179struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index af4aa6599473..cbe70637c117 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -19,7 +19,8 @@
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/mount.h> 21#include <linux/mount.h>
22#include <linux/parser.h> 22#include <linux/fs_context.h>
23#include <linux/fs_parser.h>
23#include <linux/jffs2.h> 24#include <linux/jffs2.h>
24#include <linux/pagemap.h> 25#include <linux/pagemap.h>
25#include <linux/mtd/super.h> 26#include <linux/mtd/super.h>
@@ -157,96 +158,77 @@ static const struct export_operations jffs2_export_ops = {
157/* 158/*
158 * JFFS2 mount options. 159 * JFFS2 mount options.
159 * 160 *
161 * Opt_source: The source device
160 * Opt_override_compr: override default compressor 162 * Opt_override_compr: override default compressor
161 * Opt_rp_size: size of reserved pool in KiB 163 * Opt_rp_size: size of reserved pool in KiB
162 * Opt_err: just end of array marker
163 */ 164 */
164enum { 165enum {
166 Opt_source,
165 Opt_override_compr, 167 Opt_override_compr,
166 Opt_rp_size, 168 Opt_rp_size,
167 Opt_err,
168}; 169};
169 170
170static const match_table_t tokens = { 171static const struct fs_parameter_spec jffs2_param_specs[] = {
171 {Opt_override_compr, "compr=%s"}, 172 fsparam_string ("source", Opt_source),
172 {Opt_rp_size, "rp_size=%u"}, 173 fsparam_enum ("compr", Opt_override_compr),
173 {Opt_err, NULL}, 174 fsparam_u32 ("rp_size", Opt_rp_size),
175 {}
174}; 176};
175 177
176static int jffs2_parse_options(struct jffs2_sb_info *c, char *data) 178static const struct fs_parameter_enum jffs2_param_enums[] = {
177{ 179 { Opt_override_compr, "none", JFFS2_COMPR_MODE_NONE },
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;
200#ifdef CONFIG_JFFS2_LZO 180#ifdef CONFIG_JFFS2_LZO
201 else if (!strcmp(name, "lzo")) 181 { Opt_override_compr, "lzo", JFFS2_COMPR_MODE_FORCELZO },
202 c->mount_opts.compr = JFFS2_COMPR_MODE_FORCELZO;
203#endif 182#endif
204#ifdef CONFIG_JFFS2_ZLIB 183#ifdef CONFIG_JFFS2_ZLIB
205 else if (!strcmp(name, "zlib")) 184 { Opt_override_compr, "zlib", JFFS2_COMPR_MODE_FORCEZLIB },
206 c->mount_opts.compr =
207 JFFS2_COMPR_MODE_FORCEZLIB;
208#endif 185#endif
209 else { 186 {}
210 pr_err("Error: unknown compressor \"%s\"\n", 187};
211 name); 188
212 kfree(name); 189const struct fs_parameter_description jffs2_fs_parameters = {
213 return -EINVAL; 190 .name = "jffs2",
214 } 191 .specs = jffs2_param_specs,
215 kfree(name); 192 .enums = jffs2_param_enums,
216 c->mount_opts.override_compr = true; 193};
217 break; 194
218 case Opt_rp_size: 195static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
219 if (match_int(&args[0], &opt)) 196{
220 return -EINVAL; 197 struct fs_parse_result result;
221 opt *= 1024; 198 struct jffs2_sb_info *c = fc->s_fs_info;
222 if (opt > c->mtd->size) { 199 int opt;
223 pr_warn("Too large reserve pool specified, max " 200
224 "is %llu KB\n", c->mtd->size / 1024); 201 opt = fs_parse(fc, &jffs2_fs_parameters, param, &result);
225 return -EINVAL; 202 if (opt < 0)
226 } 203 return opt;
227 c->mount_opts.rp_size = opt; 204
228 break; 205 switch (opt) {
229 default: 206 case Opt_override_compr:
230 pr_err("Error: unrecognized mount option '%s' or missing value\n", 207 c->mount_opts.compr = result.uint_32;
231 p); 208 c->mount_opts.override_compr = true;
232 return -EINVAL; 209 break;
233 } 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 return 0; 223 return 0;
237} 224}
238 225
239static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data) 226static int jffs2_reconfigure(struct fs_context *fc)
240{ 227{
241 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 228 struct super_block *sb = fc->root->d_sb;
242 int err;
243 229
244 sync_filesystem(sb); 230 sync_filesystem(sb);
245 err = jffs2_parse_options(c, data); 231 return jffs2_do_remount_fs(sb, fc);
246 if (err)
247 return -EINVAL;
248
249 return jffs2_do_remount_fs(sb, flags, data);
250} 232}
251 233
252static const struct super_operations jffs2_super_operations = 234static const struct super_operations jffs2_super_operations =
@@ -255,7 +237,6 @@ static const struct super_operations jffs2_super_operations =
255 .free_inode = jffs2_free_inode, 237 .free_inode = jffs2_free_inode,
256 .put_super = jffs2_put_super, 238 .put_super = jffs2_put_super,
257 .statfs = jffs2_statfs, 239 .statfs = jffs2_statfs,
258 .remount_fs = jffs2_remount_fs,
259 .evict_inode = jffs2_evict_inode, 240 .evict_inode = jffs2_evict_inode,
260 .dirty_inode = jffs2_dirty_inode, 241 .dirty_inode = jffs2_dirty_inode,
261 .show_options = jffs2_show_options, 242 .show_options = jffs2_show_options,
@@ -265,26 +246,16 @@ static const struct super_operations jffs2_super_operations =
265/* 246/*
266 * fill in the superblock 247 * fill in the superblock
267 */ 248 */
268static int jffs2_fill_super(struct super_block *sb, void *data, int silent) 249static int jffs2_fill_super(struct super_block *sb, struct fs_context *fc)
269{ 250{
270 struct jffs2_sb_info *c; 251 struct jffs2_sb_info *c = sb->s_fs_info;
271 int ret;
272 252
273 jffs2_dbg(1, "jffs2_get_sb_mtd():" 253 jffs2_dbg(1, "jffs2_get_sb_mtd():"
274 " New superblock for device %d (\"%s\")\n", 254 " New superblock for device %d (\"%s\")\n",
275 sb->s_mtd->index, sb->s_mtd->name); 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 c->mtd = sb->s_mtd; 257 c->mtd = sb->s_mtd;
282 c->os_priv = sb; 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 /* Initialize JFFS2 superblock locks, the further initialization will 260 /* Initialize JFFS2 superblock locks, the further initialization will
290 * be done later */ 261 * be done later */
@@ -302,15 +273,37 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
302#ifdef CONFIG_JFFS2_FS_POSIX_ACL 273#ifdef CONFIG_JFFS2_FS_POSIX_ACL
303 sb->s_flags |= SB_POSIXACL; 274 sb->s_flags |= SB_POSIXACL;
304#endif 275#endif
305 ret = jffs2_do_fill_super(sb, data, silent); 276 return jffs2_do_fill_super(sb, fc);
306 return ret;
307} 277}
308 278
309static struct dentry *jffs2_mount(struct file_system_type *fs_type, 279static int jffs2_get_tree(struct fs_context *fc)
310 int flags, const char *dev_name,
311 void *data)
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
284static void jffs2_free_fc(struct fs_context *fc)
285{
286 kfree(fc->s_fs_info);
287}
288
289static 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
296static 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
316static void jffs2_put_super (struct super_block *sb) 309static void jffs2_put_super (struct super_block *sb)
@@ -347,7 +340,8 @@ static void jffs2_kill_sb(struct super_block *sb)
347static struct file_system_type jffs2_fs_type = { 340static struct file_system_type jffs2_fs_type = {
348 .owner = THIS_MODULE, 341 .owner = THIS_MODULE,
349 .name = "jffs2", 342 .name = "jffs2",
350 .mount = jffs2_mount, 343 .init_fs_context = jffs2_init_fs_context,
344 .parameters = &jffs2_fs_parameters,
351 .kill_sb = jffs2_kill_sb, 345 .kill_sb = jffs2_kill_sb,
352}; 346};
353MODULE_ALIAS_FS("jffs2"); 347MODULE_ALIAS_FS("jffs2");
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};
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index a42c0e3079dc..e582d001f792 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -65,7 +65,7 @@
65#include <linux/slab.h> 65#include <linux/slab.h>
66#include <linux/init.h> 66#include <linux/init.h>
67#include <linux/blkdev.h> 67#include <linux/blkdev.h>
68#include <linux/parser.h> 68#include <linux/fs_context.h>
69#include <linux/mount.h> 69#include <linux/mount.h>
70#include <linux/namei.h> 70#include <linux/namei.h>
71#include <linux/statfs.h> 71#include <linux/statfs.h>
@@ -423,10 +423,10 @@ static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf)
423/* 423/*
424 * remounting must involve read-only 424 * remounting must involve read-only
425 */ 425 */
426static int romfs_remount(struct super_block *sb, int *flags, char *data) 426static int romfs_reconfigure(struct fs_context *fc)
427{ 427{
428 sync_filesystem(sb); 428 sync_filesystem(fc->root->d_sb);
429 *flags |= SB_RDONLY; 429 fc->sb_flags |= SB_RDONLY;
430 return 0; 430 return 0;
431} 431}
432 432
@@ -434,7 +434,6 @@ static const struct super_operations romfs_super_ops = {
434 .alloc_inode = romfs_alloc_inode, 434 .alloc_inode = romfs_alloc_inode,
435 .free_inode = romfs_free_inode, 435 .free_inode = romfs_free_inode,
436 .statfs = romfs_statfs, 436 .statfs = romfs_statfs,
437 .remount_fs = romfs_remount,
438}; 437};
439 438
440/* 439/*
@@ -457,7 +456,7 @@ static __u32 romfs_checksum(const void *data, int size)
457/* 456/*
458 * fill in the superblock 457 * fill in the superblock
459 */ 458 */
460static int romfs_fill_super(struct super_block *sb, void *data, int silent) 459static int romfs_fill_super(struct super_block *sb, struct fs_context *fc)
461{ 460{
462 struct romfs_super_block *rsb; 461 struct romfs_super_block *rsb;
463 struct inode *root; 462 struct inode *root;
@@ -506,8 +505,8 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent)
506 505
507 if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1 || 506 if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1 ||
508 img_size < ROMFH_SIZE) { 507 img_size < ROMFH_SIZE) {
509 if (!silent) 508 if (!(fc->sb_flags & SB_SILENT))
510 pr_warn("VFS: Can't find a romfs filesystem on dev %s.\n", 509 errorf(fc, "VFS: Can't find a romfs filesystem on dev %s.\n",
511 sb->s_id); 510 sb->s_id);
512 goto error_rsb_inval; 511 goto error_rsb_inval;
513 } 512 }
@@ -520,7 +519,7 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent)
520 storage = sb->s_mtd ? "MTD" : "the block layer"; 519 storage = sb->s_mtd ? "MTD" : "the block layer";
521 520
522 len = strnlen(rsb->name, ROMFS_MAXFN); 521 len = strnlen(rsb->name, ROMFS_MAXFN);
523 if (!silent) 522 if (!(fc->sb_flags & SB_SILENT))
524 pr_notice("Mounting image '%*.*s' through %s\n", 523 pr_notice("Mounting image '%*.*s' through %s\n",
525 (unsigned) len, (unsigned) len, rsb->name, storage); 524 (unsigned) len, (unsigned) len, rsb->name, storage);
526 525
@@ -550,23 +549,34 @@ error_rsb:
550/* 549/*
551 * get a superblock for mounting 550 * get a superblock for mounting
552 */ 551 */
553static struct dentry *romfs_mount(struct file_system_type *fs_type, 552static int romfs_get_tree(struct fs_context *fc)
554 int flags, const char *dev_name,
555 void *data)
556{ 553{
557 struct dentry *ret = ERR_PTR(-EINVAL); 554 int ret = -EINVAL;
558 555
559#ifdef CONFIG_ROMFS_ON_MTD 556#ifdef CONFIG_ROMFS_ON_MTD
560 ret = mount_mtd(fs_type, flags, dev_name, data, romfs_fill_super); 557 ret = get_tree_mtd(fc, romfs_fill_super);
561#endif 558#endif
562#ifdef CONFIG_ROMFS_ON_BLOCK 559#ifdef CONFIG_ROMFS_ON_BLOCK
563 if (ret == ERR_PTR(-EINVAL)) 560 if (ret == -EINVAL)
564 ret = mount_bdev(fs_type, flags, dev_name, data, 561 ret = get_tree_bdev(fc, romfs_fill_super);
565 romfs_fill_super);
566#endif 562#endif
567 return ret; 563 return ret;
568} 564}
569 565
566static const struct fs_context_operations romfs_context_ops = {
567 .get_tree = romfs_get_tree,
568 .reconfigure = romfs_reconfigure,
569};
570
571/*
572 * Set up the filesystem mount context.
573 */
574static int romfs_init_fs_context(struct fs_context *fc)
575{
576 fc->ops = &romfs_context_ops;
577 return 0;
578}
579
570/* 580/*
571 * destroy a romfs superblock in the appropriate manner 581 * destroy a romfs superblock in the appropriate manner
572 */ 582 */
@@ -589,7 +599,7 @@ static void romfs_kill_sb(struct super_block *sb)
589static struct file_system_type romfs_fs_type = { 599static struct file_system_type romfs_fs_type = {
590 .owner = THIS_MODULE, 600 .owner = THIS_MODULE,
591 .name = "romfs", 601 .name = "romfs",
592 .mount = romfs_mount, 602 .init_fs_context = romfs_init_fs_context,
593 .kill_sb = romfs_kill_sb, 603 .kill_sb = romfs_kill_sb,
594 .fs_flags = FS_REQUIRES_DEV, 604 .fs_flags = FS_REQUIRES_DEV,
595}; 605};
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index a9e9837617a9..0cc4ceec0562 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -17,6 +17,7 @@
17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18 18
19#include <linux/fs.h> 19#include <linux/fs.h>
20#include <linux/fs_context.h>
20#include <linux/vfs.h> 21#include <linux/vfs.h>
21#include <linux/slab.h> 22#include <linux/slab.h>
22#include <linux/mutex.h> 23#include <linux/mutex.h>
@@ -36,26 +37,27 @@
36static struct file_system_type squashfs_fs_type; 37static struct file_system_type squashfs_fs_type;
37static const struct super_operations squashfs_super_ops; 38static const struct super_operations squashfs_super_ops;
38 39
39static const struct squashfs_decompressor *supported_squashfs_filesystem(short 40static const struct squashfs_decompressor *supported_squashfs_filesystem(
40 major, short minor, short id) 41 struct fs_context *fc,
42 short major, short minor, short id)
41{ 43{
42 const struct squashfs_decompressor *decompressor; 44 const struct squashfs_decompressor *decompressor;
43 45
44 if (major < SQUASHFS_MAJOR) { 46 if (major < SQUASHFS_MAJOR) {
45 ERROR("Major/Minor mismatch, older Squashfs %d.%d " 47 errorf(fc, "Major/Minor mismatch, older Squashfs %d.%d "
46 "filesystems are unsupported\n", major, minor); 48 "filesystems are unsupported", major, minor);
47 return NULL; 49 return NULL;
48 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { 50 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
49 ERROR("Major/Minor mismatch, trying to mount newer " 51 errorf(fc, "Major/Minor mismatch, trying to mount newer "
50 "%d.%d filesystem\n", major, minor); 52 "%d.%d filesystem", major, minor);
51 ERROR("Please update your kernel\n"); 53 errorf(fc, "Please update your kernel");
52 return NULL; 54 return NULL;
53 } 55 }
54 56
55 decompressor = squashfs_lookup_decompressor(id); 57 decompressor = squashfs_lookup_decompressor(id);
56 if (!decompressor->supported) { 58 if (!decompressor->supported) {
57 ERROR("Filesystem uses \"%s\" compression. This is not " 59 errorf(fc, "Filesystem uses \"%s\" compression. This is not supported",
58 "supported\n", decompressor->name); 60 decompressor->name);
59 return NULL; 61 return NULL;
60 } 62 }
61 63
@@ -63,7 +65,7 @@ static const struct squashfs_decompressor *supported_squashfs_filesystem(short
63} 65}
64 66
65 67
66static int squashfs_fill_super(struct super_block *sb, void *data, int silent) 68static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
67{ 69{
68 struct squashfs_sb_info *msblk; 70 struct squashfs_sb_info *msblk;
69 struct squashfs_super_block *sblk = NULL; 71 struct squashfs_super_block *sblk = NULL;
@@ -98,7 +100,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
98 sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk)); 100 sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk));
99 101
100 if (IS_ERR(sblk)) { 102 if (IS_ERR(sblk)) {
101 ERROR("unable to read squashfs_super_block\n"); 103 errorf(fc, "unable to read squashfs_super_block");
102 err = PTR_ERR(sblk); 104 err = PTR_ERR(sblk);
103 sblk = NULL; 105 sblk = NULL;
104 goto failed_mount; 106 goto failed_mount;
@@ -109,14 +111,15 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
109 /* Check it is a SQUASHFS superblock */ 111 /* Check it is a SQUASHFS superblock */
110 sb->s_magic = le32_to_cpu(sblk->s_magic); 112 sb->s_magic = le32_to_cpu(sblk->s_magic);
111 if (sb->s_magic != SQUASHFS_MAGIC) { 113 if (sb->s_magic != SQUASHFS_MAGIC) {
112 if (!silent) 114 if (!(fc->sb_flags & SB_SILENT))
113 ERROR("Can't find a SQUASHFS superblock on %pg\n", 115 errorf(fc, "Can't find a SQUASHFS superblock on %pg",
114 sb->s_bdev); 116 sb->s_bdev);
115 goto failed_mount; 117 goto failed_mount;
116 } 118 }
117 119
118 /* Check the MAJOR & MINOR versions and lookup compression type */ 120 /* Check the MAJOR & MINOR versions and lookup compression type */
119 msblk->decompressor = supported_squashfs_filesystem( 121 msblk->decompressor = supported_squashfs_filesystem(
122 fc,
120 le16_to_cpu(sblk->s_major), 123 le16_to_cpu(sblk->s_major),
121 le16_to_cpu(sblk->s_minor), 124 le16_to_cpu(sblk->s_minor),
122 le16_to_cpu(sblk->compression)); 125 le16_to_cpu(sblk->compression));
@@ -133,15 +136,15 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
133 /* Check block size for sanity */ 136 /* Check block size for sanity */
134 msblk->block_size = le32_to_cpu(sblk->block_size); 137 msblk->block_size = le32_to_cpu(sblk->block_size);
135 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE) 138 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
136 goto failed_mount; 139 goto insanity;
137 140
138 /* 141 /*
139 * Check the system page size is not larger than the filesystem 142 * Check the system page size is not larger than the filesystem
140 * block size (by default 128K). This is currently not supported. 143 * block size (by default 128K). This is currently not supported.
141 */ 144 */
142 if (PAGE_SIZE > msblk->block_size) { 145 if (PAGE_SIZE > msblk->block_size) {
143 ERROR("Page size > filesystem block size (%d). This is " 146 errorf(fc, "Page size > filesystem block size (%d). This is "
144 "currently not supported!\n", msblk->block_size); 147 "currently not supported!", msblk->block_size);
145 goto failed_mount; 148 goto failed_mount;
146 } 149 }
147 150
@@ -152,12 +155,12 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
152 155
153 /* Check that block_size and block_log match */ 156 /* Check that block_size and block_log match */
154 if (msblk->block_size != (1 << msblk->block_log)) 157 if (msblk->block_size != (1 << msblk->block_log))
155 goto failed_mount; 158 goto insanity;
156 159
157 /* Check the root inode for sanity */ 160 /* Check the root inode for sanity */
158 root_inode = le64_to_cpu(sblk->root_inode); 161 root_inode = le64_to_cpu(sblk->root_inode);
159 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE) 162 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE)
160 goto failed_mount; 163 goto insanity;
161 164
162 msblk->inode_table = le64_to_cpu(sblk->inode_table_start); 165 msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
163 msblk->directory_table = le64_to_cpu(sblk->directory_table_start); 166 msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
@@ -199,7 +202,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
199 msblk->read_page = squashfs_cache_init("data", 202 msblk->read_page = squashfs_cache_init("data",
200 squashfs_max_decompressors(), msblk->block_size); 203 squashfs_max_decompressors(), msblk->block_size);
201 if (msblk->read_page == NULL) { 204 if (msblk->read_page == NULL) {
202 ERROR("Failed to allocate read_page block\n"); 205 errorf(fc, "Failed to allocate read_page block");
203 goto failed_mount; 206 goto failed_mount;
204 } 207 }
205 208
@@ -207,7 +210,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
207 if (IS_ERR(msblk->stream)) { 210 if (IS_ERR(msblk->stream)) {
208 err = PTR_ERR(msblk->stream); 211 err = PTR_ERR(msblk->stream);
209 msblk->stream = NULL; 212 msblk->stream = NULL;
210 goto failed_mount; 213 goto insanity;
211 } 214 }
212 215
213 /* Handle xattrs */ 216 /* Handle xattrs */
@@ -222,7 +225,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
222 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb, 225 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
223 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids); 226 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
224 if (IS_ERR(msblk->xattr_id_table)) { 227 if (IS_ERR(msblk->xattr_id_table)) {
225 ERROR("unable to read xattr id index table\n"); 228 errorf(fc, "unable to read xattr id index table");
226 err = PTR_ERR(msblk->xattr_id_table); 229 err = PTR_ERR(msblk->xattr_id_table);
227 msblk->xattr_id_table = NULL; 230 msblk->xattr_id_table = NULL;
228 if (err != -ENOTSUPP) 231 if (err != -ENOTSUPP)
@@ -236,7 +239,7 @@ allocate_id_index_table:
236 le64_to_cpu(sblk->id_table_start), next_table, 239 le64_to_cpu(sblk->id_table_start), next_table,
237 le16_to_cpu(sblk->no_ids)); 240 le16_to_cpu(sblk->no_ids));
238 if (IS_ERR(msblk->id_table)) { 241 if (IS_ERR(msblk->id_table)) {
239 ERROR("unable to read id index table\n"); 242 errorf(fc, "unable to read id index table");
240 err = PTR_ERR(msblk->id_table); 243 err = PTR_ERR(msblk->id_table);
241 msblk->id_table = NULL; 244 msblk->id_table = NULL;
242 goto failed_mount; 245 goto failed_mount;
@@ -252,7 +255,7 @@ allocate_id_index_table:
252 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb, 255 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
253 lookup_table_start, next_table, msblk->inodes); 256 lookup_table_start, next_table, msblk->inodes);
254 if (IS_ERR(msblk->inode_lookup_table)) { 257 if (IS_ERR(msblk->inode_lookup_table)) {
255 ERROR("unable to read inode lookup table\n"); 258 errorf(fc, "unable to read inode lookup table");
256 err = PTR_ERR(msblk->inode_lookup_table); 259 err = PTR_ERR(msblk->inode_lookup_table);
257 msblk->inode_lookup_table = NULL; 260 msblk->inode_lookup_table = NULL;
258 goto failed_mount; 261 goto failed_mount;
@@ -277,7 +280,7 @@ handle_fragments:
277 msblk->fragment_index = squashfs_read_fragment_index_table(sb, 280 msblk->fragment_index = squashfs_read_fragment_index_table(sb,
278 le64_to_cpu(sblk->fragment_table_start), next_table, fragments); 281 le64_to_cpu(sblk->fragment_table_start), next_table, fragments);
279 if (IS_ERR(msblk->fragment_index)) { 282 if (IS_ERR(msblk->fragment_index)) {
280 ERROR("unable to read fragment index table\n"); 283 errorf(fc, "unable to read fragment index table");
281 err = PTR_ERR(msblk->fragment_index); 284 err = PTR_ERR(msblk->fragment_index);
282 msblk->fragment_index = NULL; 285 msblk->fragment_index = NULL;
283 goto failed_mount; 286 goto failed_mount;
@@ -288,13 +291,13 @@ check_directory_table:
288 /* Sanity check directory_table */ 291 /* Sanity check directory_table */
289 if (msblk->directory_table > next_table) { 292 if (msblk->directory_table > next_table) {
290 err = -EINVAL; 293 err = -EINVAL;
291 goto failed_mount; 294 goto insanity;
292 } 295 }
293 296
294 /* Sanity check inode_table */ 297 /* Sanity check inode_table */
295 if (msblk->inode_table >= msblk->directory_table) { 298 if (msblk->inode_table >= msblk->directory_table) {
296 err = -EINVAL; 299 err = -EINVAL;
297 goto failed_mount; 300 goto insanity;
298 } 301 }
299 302
300 /* allocate root */ 303 /* allocate root */
@@ -323,6 +326,8 @@ check_directory_table:
323 kfree(sblk); 326 kfree(sblk);
324 return 0; 327 return 0;
325 328
329insanity:
330 errorf(fc, "squashfs image failed sanity check");
326failed_mount: 331failed_mount:
327 squashfs_cache_delete(msblk->block_cache); 332 squashfs_cache_delete(msblk->block_cache);
328 squashfs_cache_delete(msblk->fragment_cache); 333 squashfs_cache_delete(msblk->fragment_cache);
@@ -338,6 +343,28 @@ failed_mount:
338 return err; 343 return err;
339} 344}
340 345
346static int squashfs_get_tree(struct fs_context *fc)
347{
348 return get_tree_bdev(fc, squashfs_fill_super);
349}
350
351static int squashfs_reconfigure(struct fs_context *fc)
352{
353 sync_filesystem(fc->root->d_sb);
354 fc->sb_flags |= SB_RDONLY;
355 return 0;
356}
357
358static const struct fs_context_operations squashfs_context_ops = {
359 .get_tree = squashfs_get_tree,
360 .reconfigure = squashfs_reconfigure,
361};
362
363static int squashfs_init_fs_context(struct fs_context *fc)
364{
365 fc->ops = &squashfs_context_ops;
366 return 0;
367}
341 368
342static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) 369static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
343{ 370{
@@ -360,14 +387,6 @@ static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
360} 387}
361 388
362 389
363static int squashfs_remount(struct super_block *sb, int *flags, char *data)
364{
365 sync_filesystem(sb);
366 *flags |= SB_RDONLY;
367 return 0;
368}
369
370
371static void squashfs_put_super(struct super_block *sb) 390static void squashfs_put_super(struct super_block *sb)
372{ 391{
373 if (sb->s_fs_info) { 392 if (sb->s_fs_info) {
@@ -386,14 +405,6 @@ static void squashfs_put_super(struct super_block *sb)
386 } 405 }
387} 406}
388 407
389
390static struct dentry *squashfs_mount(struct file_system_type *fs_type,
391 int flags, const char *dev_name, void *data)
392{
393 return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super);
394}
395
396
397static struct kmem_cache *squashfs_inode_cachep; 408static struct kmem_cache *squashfs_inode_cachep;
398 409
399 410
@@ -470,7 +481,7 @@ static void squashfs_free_inode(struct inode *inode)
470static struct file_system_type squashfs_fs_type = { 481static struct file_system_type squashfs_fs_type = {
471 .owner = THIS_MODULE, 482 .owner = THIS_MODULE,
472 .name = "squashfs", 483 .name = "squashfs",
473 .mount = squashfs_mount, 484 .init_fs_context = squashfs_init_fs_context,
474 .kill_sb = kill_block_super, 485 .kill_sb = kill_block_super,
475 .fs_flags = FS_REQUIRES_DEV 486 .fs_flags = FS_REQUIRES_DEV
476}; 487};
@@ -481,7 +492,6 @@ static const struct super_operations squashfs_super_ops = {
481 .free_inode = squashfs_free_inode, 492 .free_inode = squashfs_free_inode,
482 .statfs = squashfs_statfs, 493 .statfs = squashfs_statfs,
483 .put_super = squashfs_put_super, 494 .put_super = squashfs_put_super,
484 .remount_fs = squashfs_remount
485}; 495};
486 496
487module_init(init_squashfs_fs); 497module_init(init_squashfs_fs);
diff --git a/fs/super.c b/fs/super.c
index 2d679db9e8c7..8020974b2a68 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1164,9 +1164,11 @@ int vfs_get_super(struct fs_context *fc,
1164{ 1164{
1165 int (*test)(struct super_block *, struct fs_context *); 1165 int (*test)(struct super_block *, struct fs_context *);
1166 struct super_block *sb; 1166 struct super_block *sb;
1167 int err;
1167 1168
1168 switch (keying) { 1169 switch (keying) {
1169 case vfs_get_single_super: 1170 case vfs_get_single_super:
1171 case vfs_get_single_reconf_super:
1170 test = test_single_super; 1172 test = test_single_super;
1171 break; 1173 break;
1172 case vfs_get_keyed_super: 1174 case vfs_get_keyed_super:
@@ -1184,18 +1186,29 @@ int vfs_get_super(struct fs_context *fc,
1184 return PTR_ERR(sb); 1186 return PTR_ERR(sb);
1185 1187
1186 if (!sb->s_root) { 1188 if (!sb->s_root) {
1187 int err = fill_super(sb, fc); 1189 err = fill_super(sb, fc);
1188 if (err) { 1190 if (err)
1189 deactivate_locked_super(sb); 1191 goto error;
1190 return err;
1191 }
1192 1192
1193 sb->s_flags |= SB_ACTIVE; 1193 sb->s_flags |= SB_ACTIVE;
1194 fc->root = dget(sb->s_root);
1195 } else {
1196 fc->root = dget(sb->s_root);
1197 if (keying == vfs_get_single_reconf_super) {
1198 err = reconfigure_super(fc);
1199 if (err < 0) {
1200 dput(fc->root);
1201 fc->root = NULL;
1202 goto error;
1203 }
1204 }
1194 } 1205 }
1195 1206
1196 BUG_ON(fc->root);
1197 fc->root = dget(sb->s_root);
1198 return 0; 1207 return 0;
1208
1209error:
1210 deactivate_locked_super(sb);
1211 return err;
1199} 1212}
1200EXPORT_SYMBOL(vfs_get_super); 1213EXPORT_SYMBOL(vfs_get_super);
1201 1214
@@ -1215,6 +1228,14 @@ int get_tree_single(struct fs_context *fc,
1215} 1228}
1216EXPORT_SYMBOL(get_tree_single); 1229EXPORT_SYMBOL(get_tree_single);
1217 1230
1231int get_tree_single_reconf(struct fs_context *fc,
1232 int (*fill_super)(struct super_block *sb,
1233 struct fs_context *fc))
1234{
1235 return vfs_get_super(fc, vfs_get_single_reconf_super, fill_super);
1236}
1237EXPORT_SYMBOL(get_tree_single_reconf);
1238
1218int get_tree_keyed(struct fs_context *fc, 1239int get_tree_keyed(struct fs_context *fc,
1219 int (*fill_super)(struct super_block *sb, 1240 int (*fill_super)(struct super_block *sb,
1220 struct fs_context *fc), 1241 struct fs_context *fc),
diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h
index 84a5eaa09f19..0424df7f6e6b 100644
--- a/include/linux/fs_context.h
+++ b/include/linux/fs_context.h
@@ -141,6 +141,7 @@ extern void put_fs_context(struct fs_context *fc);
141 */ 141 */
142enum vfs_get_super_keying { 142enum vfs_get_super_keying {
143 vfs_get_single_super, /* Only one such superblock may exist */ 143 vfs_get_single_super, /* Only one such superblock may exist */
144 vfs_get_single_reconf_super, /* As above, but reconfigure if it exists */
144 vfs_get_keyed_super, /* Superblocks with different s_fs_info keys may exist */ 145 vfs_get_keyed_super, /* Superblocks with different s_fs_info keys may exist */
145 vfs_get_independent_super, /* Multiple independent superblocks may exist */ 146 vfs_get_independent_super, /* Multiple independent superblocks may exist */
146}; 147};
@@ -155,6 +156,9 @@ extern int get_tree_nodev(struct fs_context *fc,
155extern int get_tree_single(struct fs_context *fc, 156extern int get_tree_single(struct fs_context *fc,
156 int (*fill_super)(struct super_block *sb, 157 int (*fill_super)(struct super_block *sb,
157 struct fs_context *fc)); 158 struct fs_context *fc));
159extern int get_tree_single_reconf(struct fs_context *fc,
160 int (*fill_super)(struct super_block *sb,
161 struct fs_context *fc));
158extern int get_tree_keyed(struct fs_context *fc, 162extern int get_tree_keyed(struct fs_context *fc,
159 int (*fill_super)(struct super_block *sb, 163 int (*fill_super)(struct super_block *sb,
160 struct fs_context *fc), 164 struct fs_context *fc),
diff --git a/include/linux/mtd/super.h b/include/linux/mtd/super.h
index 42db3f8e8136..3608a6c36fac 100644
--- a/include/linux/mtd/super.h
+++ b/include/linux/mtd/super.h
@@ -17,9 +17,6 @@
17extern int get_tree_mtd(struct fs_context *fc, 17extern int get_tree_mtd(struct fs_context *fc,
18 int (*fill_super)(struct super_block *sb, 18 int (*fill_super)(struct super_block *sb,
19 struct fs_context *fc)); 19 struct fs_context *fc));
20extern struct dentry *mount_mtd(struct file_system_type *fs_type, int flags,
21 const char *dev_name, void *data,
22 int (*fill_super)(struct super_block *, void *, int));
23extern void kill_mtd_super(struct super_block *sb); 20extern void kill_mtd_super(struct super_block *sb);
24 21
25 22
diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h
index ee582bdb7fda..b806a0ff6554 100644
--- a/include/linux/ramfs.h
+++ b/include/linux/ramfs.h
@@ -4,8 +4,7 @@
4 4
5struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, 5struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
6 umode_t mode, dev_t dev); 6 umode_t mode, dev_t dev);
7extern struct dentry *ramfs_mount(struct file_system_type *fs_type, 7extern int ramfs_init_fs_context(struct fs_context *fc);
8 int flags, const char *dev_name, void *data);
9 8
10#ifdef CONFIG_MMU 9#ifdef CONFIG_MMU
11static inline int 10static inline int
@@ -17,9 +16,8 @@ ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
17extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); 16extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
18#endif 17#endif
19 18
19extern const struct fs_parameter_description ramfs_fs_parameters;
20extern const struct file_operations ramfs_file_operations; 20extern const struct file_operations ramfs_file_operations;
21extern const struct vm_operations_struct generic_file_vm_ops; 21extern const struct vm_operations_struct generic_file_vm_ops;
22 22
23int ramfs_fill_super(struct super_block *sb, void *data, int silent);
24
25#endif 23#endif
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 20d815a33145..de8e4b71e3ba 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -49,8 +49,9 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
49/* 49/*
50 * Functions in mm/shmem.c called directly from elsewhere: 50 * Functions in mm/shmem.c called directly from elsewhere:
51 */ 51 */
52extern const struct fs_parameter_description shmem_fs_parameters;
52extern int shmem_init(void); 53extern int shmem_init(void);
53extern int shmem_fill_super(struct super_block *sb, void *data, int silent); 54extern int shmem_init_fs_context(struct fs_context *fc);
54extern struct file *shmem_file_setup(const char *name, 55extern struct file *shmem_file_setup(const char *name,
55 loff_t size, unsigned long flags); 56 loff_t size, unsigned long flags);
56extern struct file *shmem_kernel_file_setup(const char *name, loff_t size, 57extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 53cb37b66227..9634ecf3743d 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -627,20 +627,17 @@ out:
627} 627}
628 628
629static bool is_tmpfs; 629static bool is_tmpfs;
630static struct dentry *rootfs_mount(struct file_system_type *fs_type, 630static int rootfs_init_fs_context(struct fs_context *fc)
631 int flags, const char *dev_name, void *data)
632{ 631{
633 void *fill = ramfs_fill_super;
634
635 if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) 632 if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
636 fill = shmem_fill_super; 633 return shmem_init_fs_context(fc);
637 634
638 return mount_nodev(fs_type, flags, data, fill); 635 return ramfs_init_fs_context(fc);
639} 636}
640 637
641struct file_system_type rootfs_fs_type = { 638struct file_system_type rootfs_fs_type = {
642 .name = "rootfs", 639 .name = "rootfs",
643 .mount = rootfs_mount, 640 .init_fs_context = rootfs_init_fs_context,
644 .kill_sb = kill_litter_super, 641 .kill_sb = kill_litter_super,
645}; 642};
646 643
diff --git a/mm/shmem.c b/mm/shmem.c
index 2bed4761f279..0f7fd4a85db6 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -37,6 +37,7 @@
37#include <linux/khugepaged.h> 37#include <linux/khugepaged.h>
38#include <linux/hugetlb.h> 38#include <linux/hugetlb.h>
39#include <linux/frontswap.h> 39#include <linux/frontswap.h>
40#include <linux/fs_parser.h>
40 41
41#include <asm/tlbflush.h> /* for arch/microblaze update_mmu_cache() */ 42#include <asm/tlbflush.h> /* for arch/microblaze update_mmu_cache() */
42 43
@@ -107,6 +108,20 @@ struct shmem_falloc {
107 pgoff_t nr_unswapped; /* how often writepage refused to swap out */ 108 pgoff_t nr_unswapped; /* how often writepage refused to swap out */
108}; 109};
109 110
111struct shmem_options {
112 unsigned long long blocks;
113 unsigned long long inodes;
114 struct mempolicy *mpol;
115 kuid_t uid;
116 kgid_t gid;
117 umode_t mode;
118 int huge;
119 int seen;
120#define SHMEM_SEEN_BLOCKS 1
121#define SHMEM_SEEN_INODES 2
122#define SHMEM_SEEN_HUGE 4
123};
124
110#ifdef CONFIG_TMPFS 125#ifdef CONFIG_TMPFS
111static unsigned long shmem_default_max_blocks(void) 126static unsigned long shmem_default_max_blocks(void)
112{ 127{
@@ -3349,16 +3364,126 @@ static const struct export_operations shmem_export_ops = {
3349 .fh_to_dentry = shmem_fh_to_dentry, 3364 .fh_to_dentry = shmem_fh_to_dentry,
3350}; 3365};
3351 3366
3352static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo, 3367enum shmem_param {
3353 bool remount) 3368 Opt_gid,
3369 Opt_huge,
3370 Opt_mode,
3371 Opt_mpol,
3372 Opt_nr_blocks,
3373 Opt_nr_inodes,
3374 Opt_size,
3375 Opt_uid,
3376};
3377
3378static const struct fs_parameter_spec shmem_param_specs[] = {
3379 fsparam_u32 ("gid", Opt_gid),
3380 fsparam_enum ("huge", Opt_huge),
3381 fsparam_u32oct("mode", Opt_mode),
3382 fsparam_string("mpol", Opt_mpol),
3383 fsparam_string("nr_blocks", Opt_nr_blocks),
3384 fsparam_string("nr_inodes", Opt_nr_inodes),
3385 fsparam_string("size", Opt_size),
3386 fsparam_u32 ("uid", Opt_uid),
3387 {}
3388};
3389
3390static const struct fs_parameter_enum shmem_param_enums[] = {
3391 { Opt_huge, "never", SHMEM_HUGE_NEVER },
3392 { Opt_huge, "always", SHMEM_HUGE_ALWAYS },
3393 { Opt_huge, "within_size", SHMEM_HUGE_WITHIN_SIZE },
3394 { Opt_huge, "advise", SHMEM_HUGE_ADVISE },
3395 {}
3396};
3397
3398const struct fs_parameter_description shmem_fs_parameters = {
3399 .name = "tmpfs",
3400 .specs = shmem_param_specs,
3401 .enums = shmem_param_enums,
3402};
3403
3404static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
3354{ 3405{
3355 char *this_char, *value, *rest; 3406 struct shmem_options *ctx = fc->fs_private;
3356 struct mempolicy *mpol = NULL; 3407 struct fs_parse_result result;
3357 uid_t uid; 3408 unsigned long long size;
3358 gid_t gid; 3409 char *rest;
3410 int opt;
3411
3412 opt = fs_parse(fc, &shmem_fs_parameters, param, &result);
3413 if (opt < 0)
3414 return opt;
3415
3416 switch (opt) {
3417 case Opt_size:
3418 size = memparse(param->string, &rest);
3419 if (*rest == '%') {
3420 size <<= PAGE_SHIFT;
3421 size *= totalram_pages();
3422 do_div(size, 100);
3423 rest++;
3424 }
3425 if (*rest)
3426 goto bad_value;
3427 ctx->blocks = DIV_ROUND_UP(size, PAGE_SIZE);
3428 ctx->seen |= SHMEM_SEEN_BLOCKS;
3429 break;
3430 case Opt_nr_blocks:
3431 ctx->blocks = memparse(param->string, &rest);
3432 if (*rest)
3433 goto bad_value;
3434 ctx->seen |= SHMEM_SEEN_BLOCKS;
3435 break;
3436 case Opt_nr_inodes:
3437 ctx->inodes = memparse(param->string, &rest);
3438 if (*rest)
3439 goto bad_value;
3440 ctx->seen |= SHMEM_SEEN_INODES;
3441 break;
3442 case Opt_mode:
3443 ctx->mode = result.uint_32 & 07777;
3444 break;
3445 case Opt_uid:
3446 ctx->uid = make_kuid(current_user_ns(), result.uint_32);
3447 if (!uid_valid(ctx->uid))
3448 goto bad_value;
3449 break;
3450 case Opt_gid:
3451 ctx->gid = make_kgid(current_user_ns(), result.uint_32);
3452 if (!gid_valid(ctx->gid))
3453 goto bad_value;
3454 break;
3455 case Opt_huge:
3456 ctx->huge = result.uint_32;
3457 if (ctx->huge != SHMEM_HUGE_NEVER &&
3458 !(IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE) &&
3459 has_transparent_hugepage()))
3460 goto unsupported_parameter;
3461 ctx->seen |= SHMEM_SEEN_HUGE;
3462 break;
3463 case Opt_mpol:
3464 if (IS_ENABLED(CONFIG_NUMA)) {
3465 mpol_put(ctx->mpol);
3466 ctx->mpol = NULL;
3467 if (mpol_parse_str(param->string, &ctx->mpol))
3468 goto bad_value;
3469 break;
3470 }
3471 goto unsupported_parameter;
3472 }
3473 return 0;
3474
3475unsupported_parameter:
3476 return invalf(fc, "tmpfs: Unsupported parameter '%s'", param->key);
3477bad_value:
3478 return invalf(fc, "tmpfs: Bad value for '%s'", param->key);
3479}
3480
3481static int shmem_parse_options(struct fs_context *fc, void *data)
3482{
3483 char *options = data;
3359 3484
3360 while (options != NULL) { 3485 while (options != NULL) {
3361 this_char = options; 3486 char *this_char = options;
3362 for (;;) { 3487 for (;;) {
3363 /* 3488 /*
3364 * NUL-terminate this option: unfortunately, 3489 * NUL-terminate this option: unfortunately,
@@ -3374,139 +3499,83 @@ static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo,
3374 break; 3499 break;
3375 } 3500 }
3376 } 3501 }
3377 if (!*this_char) 3502 if (*this_char) {
3378 continue; 3503 char *value = strchr(this_char,'=');
3379 if ((value = strchr(this_char,'=')) != NULL) { 3504 size_t len = 0;
3380 *value++ = 0; 3505 int err;
3381 } else { 3506
3382 pr_err("tmpfs: No value for mount option '%s'\n", 3507 if (value) {
3383 this_char); 3508 *value++ = '\0';
3384 goto error; 3509 len = strlen(value);
3385 }
3386
3387 if (!strcmp(this_char,"size")) {
3388 unsigned long long size;
3389 size = memparse(value,&rest);
3390 if (*rest == '%') {
3391 size <<= PAGE_SHIFT;
3392 size *= totalram_pages();
3393 do_div(size, 100);
3394 rest++;
3395 } 3510 }
3396 if (*rest) 3511 err = vfs_parse_fs_string(fc, this_char, value, len);
3397 goto bad_val; 3512 if (err < 0)
3398 sbinfo->max_blocks = 3513 return err;
3399 DIV_ROUND_UP(size, PAGE_SIZE);
3400 } else if (!strcmp(this_char,"nr_blocks")) {
3401 sbinfo->max_blocks = memparse(value, &rest);
3402 if (*rest)
3403 goto bad_val;
3404 } else if (!strcmp(this_char,"nr_inodes")) {
3405 sbinfo->max_inodes = memparse(value, &rest);
3406 if (*rest)
3407 goto bad_val;
3408 } else if (!strcmp(this_char,"mode")) {
3409 if (remount)
3410 continue;
3411 sbinfo->mode = simple_strtoul(value, &rest, 8) & 07777;
3412 if (*rest)
3413 goto bad_val;
3414 } else if (!strcmp(this_char,"uid")) {
3415 if (remount)
3416 continue;
3417 uid = simple_strtoul(value, &rest, 0);
3418 if (*rest)
3419 goto bad_val;
3420 sbinfo->uid = make_kuid(current_user_ns(), uid);
3421 if (!uid_valid(sbinfo->uid))
3422 goto bad_val;
3423 } else if (!strcmp(this_char,"gid")) {
3424 if (remount)
3425 continue;
3426 gid = simple_strtoul(value, &rest, 0);
3427 if (*rest)
3428 goto bad_val;
3429 sbinfo->gid = make_kgid(current_user_ns(), gid);
3430 if (!gid_valid(sbinfo->gid))
3431 goto bad_val;
3432#ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE
3433 } else if (!strcmp(this_char, "huge")) {
3434 int huge;
3435 huge = shmem_parse_huge(value);
3436 if (huge < 0)
3437 goto bad_val;
3438 if (!has_transparent_hugepage() &&
3439 huge != SHMEM_HUGE_NEVER)
3440 goto bad_val;
3441 sbinfo->huge = huge;
3442#endif
3443#ifdef CONFIG_NUMA
3444 } else if (!strcmp(this_char,"mpol")) {
3445 mpol_put(mpol);
3446 mpol = NULL;
3447 if (mpol_parse_str(value, &mpol))
3448 goto bad_val;
3449#endif
3450 } else {
3451 pr_err("tmpfs: Bad mount option %s\n", this_char);
3452 goto error;
3453 } 3514 }
3454 } 3515 }
3455 sbinfo->mpol = mpol;
3456 return 0; 3516 return 0;
3457
3458bad_val:
3459 pr_err("tmpfs: Bad value '%s' for mount option '%s'\n",
3460 value, this_char);
3461error:
3462 mpol_put(mpol);
3463 return 1;
3464
3465} 3517}
3466 3518
3467static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) 3519/*
3520 * Reconfigure a shmem filesystem.
3521 *
3522 * Note that we disallow change from limited->unlimited blocks/inodes while any
3523 * are in use; but we must separately disallow unlimited->limited, because in
3524 * that case we have no record of how much is already in use.
3525 */
3526static int shmem_reconfigure(struct fs_context *fc)
3468{ 3527{
3469 struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 3528 struct shmem_options *ctx = fc->fs_private;
3470 struct shmem_sb_info config = *sbinfo; 3529 struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb);
3471 unsigned long inodes; 3530 unsigned long inodes;
3472 int error = -EINVAL; 3531 const char *err;
3473
3474 config.mpol = NULL;
3475 if (shmem_parse_options(data, &config, true))
3476 return error;
3477 3532
3478 spin_lock(&sbinfo->stat_lock); 3533 spin_lock(&sbinfo->stat_lock);
3479 inodes = sbinfo->max_inodes - sbinfo->free_inodes; 3534 inodes = sbinfo->max_inodes - sbinfo->free_inodes;
3480 if (percpu_counter_compare(&sbinfo->used_blocks, config.max_blocks) > 0) 3535 if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) {
3481 goto out; 3536 if (!sbinfo->max_blocks) {
3482 if (config.max_inodes < inodes) 3537 err = "Cannot retroactively limit size";
3483 goto out; 3538 goto out;
3484 /* 3539 }
3485 * Those tests disallow limited->unlimited while any are in use; 3540 if (percpu_counter_compare(&sbinfo->used_blocks,
3486 * but we must separately disallow unlimited->limited, because 3541 ctx->blocks) > 0) {
3487 * in that case we have no record of how much is already in use. 3542 err = "Too small a size for current use";
3488 */ 3543 goto out;
3489 if (config.max_blocks && !sbinfo->max_blocks) 3544 }
3490 goto out; 3545 }
3491 if (config.max_inodes && !sbinfo->max_inodes) 3546 if ((ctx->seen & SHMEM_SEEN_INODES) && ctx->inodes) {
3492 goto out; 3547 if (!sbinfo->max_inodes) {
3548 err = "Cannot retroactively limit inodes";
3549 goto out;
3550 }
3551 if (ctx->inodes < inodes) {
3552 err = "Too few inodes for current use";
3553 goto out;
3554 }
3555 }
3493 3556
3494 error = 0; 3557 if (ctx->seen & SHMEM_SEEN_HUGE)
3495 sbinfo->huge = config.huge; 3558 sbinfo->huge = ctx->huge;
3496 sbinfo->max_blocks = config.max_blocks; 3559 if (ctx->seen & SHMEM_SEEN_BLOCKS)
3497 sbinfo->max_inodes = config.max_inodes; 3560 sbinfo->max_blocks = ctx->blocks;
3498 sbinfo->free_inodes = config.max_inodes - inodes; 3561 if (ctx->seen & SHMEM_SEEN_INODES) {
3562 sbinfo->max_inodes = ctx->inodes;
3563 sbinfo->free_inodes = ctx->inodes - inodes;
3564 }
3499 3565
3500 /* 3566 /*
3501 * Preserve previous mempolicy unless mpol remount option was specified. 3567 * Preserve previous mempolicy unless mpol remount option was specified.
3502 */ 3568 */
3503 if (config.mpol) { 3569 if (ctx->mpol) {
3504 mpol_put(sbinfo->mpol); 3570 mpol_put(sbinfo->mpol);
3505 sbinfo->mpol = config.mpol; /* transfers initial ref */ 3571 sbinfo->mpol = ctx->mpol; /* transfers initial ref */
3572 ctx->mpol = NULL;
3506 } 3573 }
3574 spin_unlock(&sbinfo->stat_lock);
3575 return 0;
3507out: 3576out:
3508 spin_unlock(&sbinfo->stat_lock); 3577 spin_unlock(&sbinfo->stat_lock);
3509 return error; 3578 return invalf(fc, "tmpfs: %s", err);
3510} 3579}
3511 3580
3512static int shmem_show_options(struct seq_file *seq, struct dentry *root) 3581static int shmem_show_options(struct seq_file *seq, struct dentry *root)
@@ -3547,8 +3616,9 @@ static void shmem_put_super(struct super_block *sb)
3547 sb->s_fs_info = NULL; 3616 sb->s_fs_info = NULL;
3548} 3617}
3549 3618
3550int shmem_fill_super(struct super_block *sb, void *data, int silent) 3619static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
3551{ 3620{
3621 struct shmem_options *ctx = fc->fs_private;
3552 struct inode *inode; 3622 struct inode *inode;
3553 struct shmem_sb_info *sbinfo; 3623 struct shmem_sb_info *sbinfo;
3554 int err = -ENOMEM; 3624 int err = -ENOMEM;
@@ -3559,9 +3629,6 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
3559 if (!sbinfo) 3629 if (!sbinfo)
3560 return -ENOMEM; 3630 return -ENOMEM;
3561 3631
3562 sbinfo->mode = 0777 | S_ISVTX;
3563 sbinfo->uid = current_fsuid();
3564 sbinfo->gid = current_fsgid();
3565 sb->s_fs_info = sbinfo; 3632 sb->s_fs_info = sbinfo;
3566 3633
3567#ifdef CONFIG_TMPFS 3634#ifdef CONFIG_TMPFS
@@ -3571,12 +3638,10 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
3571 * but the internal instance is left unlimited. 3638 * but the internal instance is left unlimited.
3572 */ 3639 */
3573 if (!(sb->s_flags & SB_KERNMOUNT)) { 3640 if (!(sb->s_flags & SB_KERNMOUNT)) {
3574 sbinfo->max_blocks = shmem_default_max_blocks(); 3641 if (!(ctx->seen & SHMEM_SEEN_BLOCKS))
3575 sbinfo->max_inodes = shmem_default_max_inodes(); 3642 ctx->blocks = shmem_default_max_blocks();
3576 if (shmem_parse_options(data, sbinfo, false)) { 3643 if (!(ctx->seen & SHMEM_SEEN_INODES))
3577 err = -EINVAL; 3644 ctx->inodes = shmem_default_max_inodes();
3578 goto failed;
3579 }
3580 } else { 3645 } else {
3581 sb->s_flags |= SB_NOUSER; 3646 sb->s_flags |= SB_NOUSER;
3582 } 3647 }
@@ -3585,11 +3650,18 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent)
3585#else 3650#else
3586 sb->s_flags |= SB_NOUSER; 3651 sb->s_flags |= SB_NOUSER;
3587#endif 3652#endif
3653 sbinfo->max_blocks = ctx->blocks;
3654 sbinfo->free_inodes = sbinfo->max_inodes = ctx->inodes;
3655 sbinfo->uid = ctx->uid;
3656 sbinfo->gid = ctx->gid;
3657 sbinfo->mode = ctx->mode;
3658 sbinfo->huge = ctx->huge;
3659 sbinfo->mpol = ctx->mpol;
3660 ctx->mpol = NULL;
3588 3661
3589 spin_lock_init(&sbinfo->stat_lock); 3662 spin_lock_init(&sbinfo->stat_lock);
3590 if (percpu_counter_init(&sbinfo->used_blocks, 0, GFP_KERNEL)) 3663 if (percpu_counter_init(&sbinfo->used_blocks, 0, GFP_KERNEL))
3591 goto failed; 3664 goto failed;
3592 sbinfo->free_inodes = sbinfo->max_inodes;
3593 spin_lock_init(&sbinfo->shrinklist_lock); 3665 spin_lock_init(&sbinfo->shrinklist_lock);
3594 INIT_LIST_HEAD(&sbinfo->shrinklist); 3666 INIT_LIST_HEAD(&sbinfo->shrinklist);
3595 3667
@@ -3622,6 +3694,31 @@ failed:
3622 return err; 3694 return err;
3623} 3695}
3624 3696
3697static int shmem_get_tree(struct fs_context *fc)
3698{
3699 return get_tree_nodev(fc, shmem_fill_super);
3700}
3701
3702static void shmem_free_fc(struct fs_context *fc)
3703{
3704 struct shmem_options *ctx = fc->fs_private;
3705
3706 if (ctx) {
3707 mpol_put(ctx->mpol);
3708 kfree(ctx);
3709 }
3710}
3711
3712static const struct fs_context_operations shmem_fs_context_ops = {
3713 .free = shmem_free_fc,
3714 .get_tree = shmem_get_tree,
3715#ifdef CONFIG_TMPFS
3716 .parse_monolithic = shmem_parse_options,
3717 .parse_param = shmem_parse_one,
3718 .reconfigure = shmem_reconfigure,
3719#endif
3720};
3721
3625static struct kmem_cache *shmem_inode_cachep; 3722static struct kmem_cache *shmem_inode_cachep;
3626 3723
3627static struct inode *shmem_alloc_inode(struct super_block *sb) 3724static struct inode *shmem_alloc_inode(struct super_block *sb)
@@ -3738,7 +3835,6 @@ static const struct super_operations shmem_ops = {
3738 .destroy_inode = shmem_destroy_inode, 3835 .destroy_inode = shmem_destroy_inode,
3739#ifdef CONFIG_TMPFS 3836#ifdef CONFIG_TMPFS
3740 .statfs = shmem_statfs, 3837 .statfs = shmem_statfs,
3741 .remount_fs = shmem_remount_fs,
3742 .show_options = shmem_show_options, 3838 .show_options = shmem_show_options,
3743#endif 3839#endif
3744 .evict_inode = shmem_evict_inode, 3840 .evict_inode = shmem_evict_inode,
@@ -3759,16 +3855,30 @@ static const struct vm_operations_struct shmem_vm_ops = {
3759#endif 3855#endif
3760}; 3856};
3761 3857
3762static struct dentry *shmem_mount(struct file_system_type *fs_type, 3858int shmem_init_fs_context(struct fs_context *fc)
3763 int flags, const char *dev_name, void *data)
3764{ 3859{
3765 return mount_nodev(fs_type, flags, data, shmem_fill_super); 3860 struct shmem_options *ctx;
3861
3862 ctx = kzalloc(sizeof(struct shmem_options), GFP_KERNEL);
3863 if (!ctx)
3864 return -ENOMEM;
3865
3866 ctx->mode = 0777 | S_ISVTX;
3867 ctx->uid = current_fsuid();
3868 ctx->gid = current_fsgid();
3869
3870 fc->fs_private = ctx;
3871 fc->ops = &shmem_fs_context_ops;
3872 return 0;
3766} 3873}
3767 3874
3768static struct file_system_type shmem_fs_type = { 3875static struct file_system_type shmem_fs_type = {
3769 .owner = THIS_MODULE, 3876 .owner = THIS_MODULE,
3770 .name = "tmpfs", 3877 .name = "tmpfs",
3771 .mount = shmem_mount, 3878 .init_fs_context = shmem_init_fs_context,
3879#ifdef CONFIG_TMPFS
3880 .parameters = &shmem_fs_parameters,
3881#endif
3772 .kill_sb = kill_litter_super, 3882 .kill_sb = kill_litter_super,
3773 .fs_flags = FS_USERNS_MOUNT, 3883 .fs_flags = FS_USERNS_MOUNT,
3774}; 3884};
@@ -3912,7 +4022,8 @@ bool shmem_huge_enabled(struct vm_area_struct *vma)
3912 4022
3913static struct file_system_type shmem_fs_type = { 4023static struct file_system_type shmem_fs_type = {
3914 .name = "tmpfs", 4024 .name = "tmpfs",
3915 .mount = ramfs_mount, 4025 .init_fs_context = ramfs_init_fs_context,
4026 .parameters = &ramfs_fs_parameters,
3916 .kill_sb = kill_litter_super, 4027 .kill_sb = kill_litter_super,
3917 .fs_flags = FS_USERNS_MOUNT, 4028 .fs_flags = FS_USERNS_MOUNT,
3918}; 4029};