summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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};