History

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()

Linus Torvalds committed 7 years ago

Commit bc7d9ae2 parents cfb82e1 74983ac17 files · +609 −594Browse files

Unified · Split

17 files
  1. drivers/base/devtmpfs.c +29 −9
  2. drivers/mtd/mtdsuper.c +0 −189
  3. fs/cramfs/inode.c +39 −30
  4. fs/fs_parser.c +16 −2
  5. fs/jffs2/fs.c +11 −10
  6. fs/jffs2/os-linux.h +2 −2
  7. fs/jffs2/super.c +83 −89
  8. fs/ramfs/inode.c +58 −41
  9. fs/romfs/super.c +28 −18
  10. fs/squashfs/super.c +55 −45
  11. fs/super.c +28 −7
  12. include/linux/fs_context.h +4 −0
  13. include/linux/mtd/super.h +0 −3
  14. include/linux/ramfs.h +2 −4
  15. include/linux/shmem_fs.h +2 −1
  16. init/do_mounts.c +4 −7
  17. mm/shmem.c +248 −137
drivers/base/devtmpfs.c+29−9
@@ -56,20 +56,32 @@ static int __init mount_param(char *str) · 55 unmodified lines
5656 }
5757 __setup("devtmpfs.mount=", mount_param);
5858
59−static struct dentry *dev_mount(struct file_system_type *fs_type, int flags,
59+static struct vfsmount *mnt;
60+
61+static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags,
6062 const char *dev_name, void *data)
6163 {
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+
70+static struct file_system_type internal_fs_type = {
71+ .name = "devtmpfs",
6272 #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,
6475 #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,
6678 #endif
67−}
79+ .kill_sb = kill_litter_super,
80+};
6881
6982 static struct file_system_type dev_fs_type = {
7083 .name = "devtmpfs",
71− .mount = dev_mount,
72− .kill_sb = kill_litter_super,
84+ .mount = public_dev_mount,
7385 };
7486
7587 #ifdef CONFIG_BLOCK
@@ -378,12 +390,11 @@ static int handle(const char *name, umode_t mode, kuid_t uid, kgid_t gid, · 302 unmodified lines
378390
379391 static int devtmpfsd(void *p)
380392 {
381− char options[] = "mode=0755";
382393 int *err = p;
383394 *err = ksys_unshare(CLONE_NEWNS);
384395 if (*err)
385396 goto out;
386− *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options);
397+ *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
387398 if (*err)
388399 goto out;
389400 ksys_chdir("/.."); /* will traverse into overmounted root */
@@ -420,7 +431,16 @@ out: · 30 unmodified lines
420431 */
421432 int __init devtmpfs_init(void)
422433 {
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);
424444 if (err) {
425445 printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
426446 "type %i\n", err);
drivers/mtd/mtdsuper.c+0−189
@@ -193,195 +193,6 @@ int get_tree_mtd(struct fs_context *fc, · 192 unmodified lines
193193 }
194194 EXPORT_SYMBOL_GPL(get_tree_mtd);
195195
196−/*
197− * compare superblocks to see if they're equivalent
198− * - they are if the underlying MTD device is the same
199− */
200−static 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− */
220−static 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− */
234−static 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 */
264−already_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−
270−out_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− */
278−static 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− */
296−struct 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−
373−not_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−
383−EXPORT_SYMBOL_GPL(mount_mtd);
384−
385196 /*
386197 * destroy an MTD-based superblock
387198 */
fs/cramfs/inode.c+39−30
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #include <linux/blkdev.h>
2525 #include <linux/mtd/mtd.h>
2626 #include <linux/mtd/super.h>
27+#include <linux/fs_context.h>
2728 #include <linux/slab.h>
2829 #include <linux/vfs.h>
2930 #include <linux/mutex.h>
@@ -506,18 +507,19 @@ static void cramfs_kill_sb(struct super_block *sb) · 476 unmodified lines
506507 kfree(sbi);
507508 }
508509
509−static int cramfs_remount(struct super_block *sb, int *flags, char *data)
510+static int cramfs_reconfigure(struct fs_context *fc)
510511 {
511− sync_filesystem(sb);
512− *flags |= SB_RDONLY;
512+ sync_filesystem(fc->root->d_sb);
513+ fc->sb_flags |= SB_RDONLY;
513514 return 0;
514515 }
515516
516−static int cramfs_read_super(struct super_block *sb,
517− struct cramfs_super *super, int silent)
517+static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
518+ struct cramfs_super *super)
518519 {
519520 struct cramfs_sb_info *sbi = CRAMFS_SB(sb);
520521 unsigned long root_offset;
522+ bool silent = fc->sb_flags & SB_SILENT;
521523
522524 /* We don't know the real size yet */
523525 sbi->size = PAGE_SIZE;
@@ -532,7 +534,7 @@ static int cramfs_read_super(struct super_block *sb, · 8 unmodified lines
532534 /* check for wrong endianness */
533535 if (super->magic == CRAMFS_MAGIC_WEND) {
534536 if (!silent)
535− pr_err("wrong endianness\n");
537+ errorf(fc, "cramfs: wrong endianness");
536538 return -EINVAL;
537539 }
538540
@@ -544,22 +546,22 @@ static int cramfs_read_super(struct super_block *sb, · 5 unmodified lines
544546 mutex_unlock(&read_mutex);
545547 if (super->magic != CRAMFS_MAGIC) {
546548 if (super->magic == CRAMFS_MAGIC_WEND && !silent)
547− pr_err("wrong endianness\n");
549+ errorf(fc, "cramfs: wrong endianness");
548550 else if (!silent)
549− pr_err("wrong magic\n");
551+ errorf(fc, "cramfs: wrong magic");
550552 return -EINVAL;
551553 }
552554 }
553555
554556 /* get feature flags first */
555557 if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) {
556− pr_err("unsupported filesystem features\n");
558+ errorf(fc, "cramfs: unsupported filesystem features");
557559 return -EINVAL;
558560 }
559561
560562 /* Check that the root inode is in a sane state */
561563 if (!S_ISDIR(super->root.mode)) {
562− pr_err("root is not a directory\n");
564+ errorf(fc, "cramfs: root is not a directory");
563565 return -EINVAL;
564566 }
565567 /* correct strange, hard-coded permissions of mkcramfs */
@@ -578,12 +580,12 @@ static int cramfs_read_super(struct super_block *sb, · 12 unmodified lines
578580 sbi->magic = super->magic;
579581 sbi->flags = super->flags;
580582 if (root_offset == 0)
581− pr_info("empty filesystem");
583+ infof(fc, "cramfs: empty filesystem");
582584 else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
583585 ((root_offset != sizeof(struct cramfs_super)) &&
584586 (root_offset != 512 + sizeof(struct cramfs_super))))
585587 {
586− pr_err("bad root offset %lu\n", root_offset);
588+ errorf(fc, "cramfs: bad root offset %lu", root_offset);
587589 return -EINVAL;
588590 }
589591
@@ -609,8 +611,7 @@ static int cramfs_finalize_super(struct super_block *sb, · 19 unmodified lines
609611 return 0;
610612 }
611613
612−static int cramfs_blkdev_fill_super(struct super_block *sb, void *data,
613− int silent)
614+static int cramfs_blkdev_fill_super(struct super_block *sb, struct fs_context *fc)
614615 {
615616 struct cramfs_sb_info *sbi;
616617 struct cramfs_super super;
@@ -625,14 +626,13 @@ static int cramfs_blkdev_fill_super(struct super_block *sb, void *data, · 8 unmodified lines
625626 for (i = 0; i < READ_BUFFERS; i++)
626627 buffer_blocknr[i] = -1;
627628
628− err = cramfs_read_super(sb, &super, silent);
629+ err = cramfs_read_super(sb, fc, &super);
629630 if (err)
630631 return err;
631632 return cramfs_finalize_super(sb, &super.root);
632633 }
633634
634−static int cramfs_mtd_fill_super(struct super_block *sb, void *data,
635− int silent)
635+static int cramfs_mtd_fill_super(struct super_block *sb, struct fs_context *fc)
636636 {
637637 struct cramfs_sb_info *sbi;
638638 struct cramfs_super super;
@@ -654,7 +654,7 @@ static int cramfs_mtd_fill_super(struct super_block *sb, void *data, · 15 unmodified lines
654654
655655 pr_info("checking physical address %pap for linear cramfs image\n",
656656 &sbi->linear_phys_addr);
657− err = cramfs_read_super(sb, &super, silent);
657+ err = cramfs_read_super(sb, fc, &super);
658658 if (err)
659659 return err;
660660
@@ -949,32 +949,41 @@ static const struct inode_operations cramfs_dir_inode_operations = { · 288 unmodified lines
949949 };
950950
951951 static const struct super_operations cramfs_ops = {
952− .remount_fs = cramfs_remount,
953952 .statfs = cramfs_statfs,
954953 };
955954
956−static struct dentry *cramfs_mount(struct file_system_type *fs_type, int flags,
957− const char *dev_name, void *data)
955+static int cramfs_get_tree(struct fs_context *fc)
958956 {
959− struct dentry *ret = ERR_PTR(-ENOPROTOOPT);
957+ int ret = -ENOPROTOOPT;
960958
961959 if (IS_ENABLED(CONFIG_CRAMFS_MTD)) {
962− ret = mount_mtd(fs_type, flags, dev_name, data,
963− cramfs_mtd_fill_super);
964− if (!IS_ERR(ret))
960+ ret = get_tree_mtd(fc, cramfs_mtd_fill_super);
961+ if (ret < 0)
965962 return ret;
966963 }
967− if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV)) {
968− ret = mount_bdev(fs_type, flags, dev_name, data,
969− cramfs_blkdev_fill_super);
970− }
964+ if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV))
965+ ret = get_tree_bdev(fc, cramfs_blkdev_fill_super);
971966 return ret;
972967 }
973968
969+static 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+ */
977+static int cramfs_init_fs_context(struct fs_context *fc)
978+{
979+ fc->ops = &cramfs_context_ops;
980+ return 0;
981+}
982+
974983 static struct file_system_type cramfs_fs_type = {
975984 .owner = THIS_MODULE,
976985 .name = "cramfs",
977− .mount = cramfs_mount,
986+ .init_fs_context = cramfs_init_fs_context,
978987 .kill_sb = cramfs_kill_sb,
979988 .fs_flags = FS_REQUIRES_DEV,
980989 };
fs/fs_parser.c+16−2
@@ -204,9 +204,23 @@ int fs_parse(struct fs_context *fc, · 203 unmodified lines
204204 goto okay;
205205
206206 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:
208218 goto bad_value;
209− goto okay;
219+ }
220+
221+ if (result->uint_32 > INT_MAX)
222+ goto bad_value;
223+ goto maybe_okay;
210224 }
211225
212226 case fs_param_is_blockdev:
fs/jffs2/fs.c+11−10
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #include <linux/sched.h>
1818 #include <linux/cred.h>
1919 #include <linux/fs.h>
20+#include <linux/fs_context.h>
2021 #include <linux/list.h>
2122 #include <linux/mtd/mtd.h>
2223 #include <linux/pagemap.h>
@@ -184,7 +185,7 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr) · 161 unmodified lines
184185 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) {
185186 truncate_setsize(inode, iattr->ia_size);
186187 inode->i_blocks = (inode->i_size + 511) >> 9;
187− }
188+ }
188189
189190 return 0;
190191 }
@@ -391,7 +392,7 @@ void jffs2_dirty_inode(struct inode *inode, int flags) · 200 unmodified lines
391392 jffs2_do_setattr(inode, &iattr);
392393 }
393394
394−int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data)
395+int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc)
395396 {
396397 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
397398
@@ -409,10 +410,10 @@ int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data) · 11 unmodified lines
409410 mutex_unlock(&c->alloc_sem);
410411 }
411412
412− if (!(*flags & SB_RDONLY))
413+ if (!(fc->sb_flags & SB_RDONLY))
413414 jffs2_start_garbage_collect_thread(c);
414415
415− *flags |= SB_NOATIME;
416+ fc->sb_flags |= SB_NOATIME;
416417 return 0;
417418 }
418419
@@ -509,7 +510,7 @@ static int calculate_inocache_hashsize(uint32_t flash_size) · 90 unmodified lines
509510 return hashsize;
510511 }
511512
512−int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
513+int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc)
513514 {
514515 struct jffs2_sb_info *c;
515516 struct inode *root_i;
@@ -524,11 +525,11 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) · 8 unmodified lines
524525
525526 #ifndef CONFIG_JFFS2_FS_WRITEBUFFER
526527 if (c->mtd->type == MTD_NANDFLASH) {
527− pr_err("Cannot operate on NAND flash unless jffs2 NAND support is compiled in\n");
528+ errorf(fc, "Cannot operate on NAND flash unless jffs2 NAND support is compiled in");
528529 return -EINVAL;
529530 }
530531 if (c->mtd->type == MTD_DATAFLASH) {
531− pr_err("Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in\n");
532+ errorf(fc, "Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in");
532533 return -EINVAL;
533534 }
534535 #endif
@@ -542,12 +543,12 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) · 7 unmodified lines
542543 */
543544 if ((c->sector_size * blocks) != c->flash_size) {
544545 c->flash_size = c->sector_size * blocks;
545− pr_info("Flash size not aligned to erasesize, reducing to %dKiB\n",
546− c->flash_size / 1024);
546+ infof(fc, "Flash size not aligned to erasesize, reducing to %dKiB",
547+ c->flash_size / 1024);
547548 }
548549
549550 if (c->flash_size < 5*c->sector_size) {
550− pr_err("Too few erase blocks (%d)\n",
551+ errorf(fc, "Too few erase blocks (%d)",
551552 c->flash_size / c->sector_size);
552553 return -EINVAL;
553554 }
fs/jffs2/os-linux.h+2−2
@@ -172,8 +172,8 @@ void jffs2_dirty_inode(struct inode *inode, int flags); · 171 unmodified lines
172172 struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode,
173173 struct jffs2_raw_inode *ri);
174174 int jffs2_statfs (struct dentry *, struct kstatfs *);
175−int jffs2_do_remount_fs(struct super_block *, int *, char *);
176−int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
175+int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc);
176+int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc);
177177 void jffs2_gc_release_inode(struct jffs2_sb_info *c,
178178 struct jffs2_inode_info *f);
179179 struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
fs/jffs2/super.c+83−89
@@ -19,7 +19,8 @@ · 18 unmodified lines
1919 #include <linux/fs.h>
2020 #include <linux/err.h>
2121 #include <linux/mount.h>
22−#include <linux/parser.h>
22+#include <linux/fs_context.h>
23+#include <linux/fs_parser.h>
2324 #include <linux/jffs2.h>
2425 #include <linux/pagemap.h>
2526 #include <linux/mtd/super.h>
@@ -157,96 +158,77 @@ static const struct export_operations jffs2_export_ops = { · 131 unmodified lines
157158 /*
158159 * JFFS2 mount options.
159160 *
161+ * Opt_source: The source device
160162 * Opt_override_compr: override default compressor
161163 * Opt_rp_size: size of reserved pool in KiB
162− * Opt_err: just end of array marker
163164 */
164165 enum {
166+ Opt_source,
165167 Opt_override_compr,
166168 Opt_rp_size,
167− Opt_err,
168169 };
169170
170−static const match_table_t tokens = {
171− {Opt_override_compr, "compr=%s"},
172− {Opt_rp_size, "rp_size=%u"},
173− {Opt_err, NULL},
171+static const struct fs_parameter_spec jffs2_param_specs[] = {
172+ fsparam_string ("source", Opt_source),
173+ fsparam_enum ("compr", Opt_override_compr),
174+ fsparam_u32 ("rp_size", Opt_rp_size),
175+ {}
174176 };
175177
176−static int jffs2_parse_options(struct jffs2_sb_info *c, char *data)
177−{
178− substring_t args[MAX_OPT_ARGS];
179− char *p, *name;
180− unsigned int opt;
181−
182− if (!data)
183− return 0;
184−
185− while ((p = strsep(&data, ","))) {
186− int token;
187−
188− if (!*p)
189− continue;
190−
191− token = match_token(p, tokens, args);
192− switch (token) {
193− case Opt_override_compr:
194− name = match_strdup(&args[0]);
195−
196− if (!name)
197− return -ENOMEM;
198− if (!strcmp(name, "none"))
199− c->mount_opts.compr = JFFS2_COMPR_MODE_NONE;
178+static const struct fs_parameter_enum jffs2_param_enums[] = {
179+ { Opt_override_compr, "none", JFFS2_COMPR_MODE_NONE },
200180 #ifdef CONFIG_JFFS2_LZO
201− else if (!strcmp(name, "lzo"))
202− c->mount_opts.compr = JFFS2_COMPR_MODE_FORCELZO;
181+ { Opt_override_compr, "lzo", JFFS2_COMPR_MODE_FORCELZO },
203182 #endif
204183 #ifdef CONFIG_JFFS2_ZLIB
205− else if (!strcmp(name, "zlib"))
206− c->mount_opts.compr =
207− JFFS2_COMPR_MODE_FORCEZLIB;
184+ { Opt_override_compr, "zlib", JFFS2_COMPR_MODE_FORCEZLIB },
208185 #endif
209− else {
210− pr_err("Error: unknown compressor \"%s\"\n",
211− name);
212− kfree(name);
213− return -EINVAL;
214− }
215− kfree(name);
216− c->mount_opts.override_compr = true;
217− break;
218− case Opt_rp_size:
219− if (match_int(&args[0], &opt))
220− return -EINVAL;
221− opt *= 1024;
222− if (opt > c->mtd->size) {
223− pr_warn("Too large reserve pool specified, max "
224− "is %llu KB\n", c->mtd->size / 1024);
225− return -EINVAL;
226− }
227− c->mount_opts.rp_size = opt;
228− break;
229− default:
230− pr_err("Error: unrecognized mount option '%s' or missing value\n",
231− p);
232− return -EINVAL;
233− }
186+ {}
187+};
188+
189+const struct fs_parameter_description jffs2_fs_parameters = {
190+ .name = "jffs2",
191+ .specs = jffs2_param_specs,
192+ .enums = jffs2_param_enums,
193+};
194+
195+static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
196+{
197+ struct fs_parse_result result;
198+ struct jffs2_sb_info *c = fc->s_fs_info;
199+ int opt;
200+
201+ opt = fs_parse(fc, &jffs2_fs_parameters, param, &result);
202+ if (opt < 0)
203+ return opt;
204+
205+ switch (opt) {
206+ case Opt_override_compr:
207+ c->mount_opts.compr = result.uint_32;
208+ c->mount_opts.override_compr = true;
209+ break;
210+ case Opt_rp_size:
211+ if (result.uint_32 > UINT_MAX / 1024)
212+ return invalf(fc, "jffs2: rp_size unrepresentable");
213+ opt = result.uint_32 * 1024;
214+ if (opt > c->mtd->size)
215+ return invalf(fc, "jffs2: Too large reserve pool specified, max is %llu KB",
216+ c->mtd->size / 1024);
217+ c->mount_opts.rp_size = opt;
218+ break;
219+ default:
220+ return -EINVAL;
234221 }
235222
236223 return 0;
237224 }
238225
239−static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data)
226+static int jffs2_reconfigure(struct fs_context *fc)
240227 {
241− struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
242− int err;
228+ struct super_block *sb = fc->root->d_sb;
243229
244230 sync_filesystem(sb);
245− err = jffs2_parse_options(c, data);
246− if (err)
247− return -EINVAL;
248−
249− return jffs2_do_remount_fs(sb, flags, data);
231+ return jffs2_do_remount_fs(sb, fc);
250232 }
251233
252234 static const struct super_operations jffs2_super_operations =
@@ -255,7 +237,6 @@ static const struct super_operations jffs2_super_operations = · 2 unmodified lines
255237 .free_inode = jffs2_free_inode,
256238 .put_super = jffs2_put_super,
257239 .statfs = jffs2_statfs,
258− .remount_fs = jffs2_remount_fs,
259240 .evict_inode = jffs2_evict_inode,
260241 .dirty_inode = jffs2_dirty_inode,
261242 .show_options = jffs2_show_options,
@@ -265,26 +246,16 @@ static const struct super_operations jffs2_super_operations = · 3 unmodified lines
265246 /*
266247 * fill in the superblock
267248 */
268−static int jffs2_fill_super(struct super_block *sb, void *data, int silent)
249+static int jffs2_fill_super(struct super_block *sb, struct fs_context *fc)
269250 {
270− struct jffs2_sb_info *c;
271− int ret;
251+ struct jffs2_sb_info *c = sb->s_fs_info;
272252
273253 jffs2_dbg(1, "jffs2_get_sb_mtd():"
274254 " New superblock for device %d (\"%s\")\n",
275255 sb->s_mtd->index, sb->s_mtd->name);
276256
277− c = kzalloc(sizeof(*c), GFP_KERNEL);
278− if (!c)
279− return -ENOMEM;
280−
281257 c->mtd = sb->s_mtd;
282258 c->os_priv = sb;
283− sb->s_fs_info = c;
284−
285− ret = jffs2_parse_options(c, data);
286− if (ret)
287− return -EINVAL;
288259
289260 /* Initialize JFFS2 superblock locks, the further initialization will
290261 * be done later */
@@ -302,15 +273,37 @@ static int jffs2_fill_super(struct super_block *sb, void *data, int silent) · 11 unmodified lines
302273 #ifdef CONFIG_JFFS2_FS_POSIX_ACL
303274 sb->s_flags |= SB_POSIXACL;
304275 #endif
305− ret = jffs2_do_fill_super(sb, data, silent);
306− return ret;
276+ return jffs2_do_fill_super(sb, fc);
307277 }
308278
309−static struct dentry *jffs2_mount(struct file_system_type *fs_type,
310− int flags, const char *dev_name,
311− void *data)
279+static int jffs2_get_tree(struct fs_context *fc)
312280 {
313− return mount_mtd(fs_type, flags, dev_name, data, jffs2_fill_super);
281+ return get_tree_mtd(fc, jffs2_fill_super);
282+}
283+
284+static void jffs2_free_fc(struct fs_context *fc)
285+{
286+ kfree(fc->s_fs_info);
287+}
288+
289+static const struct fs_context_operations jffs2_context_ops = {
290+ .free = jffs2_free_fc,
291+ .parse_param = jffs2_parse_param,
292+ .get_tree = jffs2_get_tree,
293+ .reconfigure = jffs2_reconfigure,
294+};
295+
296+static int jffs2_init_fs_context(struct fs_context *fc)
297+{
298+ struct jffs2_sb_info *ctx;
299+
300+ ctx = kzalloc(sizeof(struct jffs2_sb_info), GFP_KERNEL);
301+ if (!ctx)
302+ return -ENOMEM;
303+
304+ fc->s_fs_info = ctx;
305+ fc->ops = &jffs2_context_ops;
306+ return 0;
314307 }
315308
316309 static void jffs2_put_super (struct super_block *sb)
@@ -347,7 +340,8 @@ static void jffs2_kill_sb(struct super_block *sb) · 30 unmodified lines
347340 static struct file_system_type jffs2_fs_type = {
348341 .owner = THIS_MODULE,
349342 .name = "jffs2",
350− .mount = jffs2_mount,
343+ .init_fs_context = jffs2_init_fs_context,
344+ .parameters = &jffs2_fs_parameters,
351345 .kill_sb = jffs2_kill_sb,
352346 };
353347 MODULE_ALIAS_FS("jffs2");
fs/ramfs/inode.c+58−41
@@ -36,6 +36,8 @@ · 35 unmodified lines
3636 #include <linux/magic.h>
3737 #include <linux/slab.h>
3838 #include <linux/uaccess.h>
39+#include <linux/fs_context.h>
40+#include <linux/fs_parser.h>
3941 #include "internal.h"
4042
4143 struct ramfs_mount_opts {
@@ -175,62 +177,52 @@ static const struct super_operations ramfs_ops = { · 133 unmodified lines
175177 .show_options = ramfs_show_options,
176178 };
177179
178−enum {
180+enum ramfs_param {
179181 Opt_mode,
180− Opt_err
181182 };
182183
183−static const match_table_t tokens = {
184− {Opt_mode, "mode=%o"},
185− {Opt_err, NULL}
184+static const struct fs_parameter_spec ramfs_param_specs[] = {
185+ fsparam_u32oct("mode", Opt_mode),
186+ {}
186187 };
187188
188−static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
189+const struct fs_parameter_description ramfs_fs_parameters = {
190+ .name = "ramfs",
191+ .specs = ramfs_param_specs,
192+};
193+
194+static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
189195 {
190− substring_t args[MAX_OPT_ARGS];
191− int option;
192− int token;
193− char *p;
194−
195− opts->mode = RAMFS_DEFAULT_MODE;
196−
197− while ((p = strsep(&data, ",")) != NULL) {
198− if (!*p)
199− continue;
200−
201− token = match_token(p, tokens, args);
202− switch (token) {
203− case Opt_mode:
204− if (match_octal(&args[0], &option))
205− return -EINVAL;
206− opts->mode = option & S_IALLUGO;
207− break;
196+ struct fs_parse_result result;
197+ struct ramfs_fs_info *fsi = fc->s_fs_info;
198+ int opt;
199+
200+ opt = fs_parse(fc, &ramfs_fs_parameters, param, &result);
201+ if (opt < 0) {
208202 /*
209203 * We might like to report bad mount options here;
210204 * but traditionally ramfs has ignored all mount options,
211205 * and as it is used as a !CONFIG_SHMEM simple substitute
212206 * for tmpfs, better continue to ignore other mount options.
213207 */
214− }
208+ if (opt == -ENOPARAM)
209+ opt = 0;
210+ return opt;
211+ }
212+
213+ switch (opt) {
214+ case Opt_mode:
215+ fsi->mount_opts.mode = result.uint_32 & S_IALLUGO;
216+ break;
215217 }
216218
217219 return 0;
218220 }
219221
220−int ramfs_fill_super(struct super_block *sb, void *data, int silent)
222+static int ramfs_fill_super(struct super_block *sb, struct fs_context *fc)
221223 {
222− struct ramfs_fs_info *fsi;
224+ struct ramfs_fs_info *fsi = sb->s_fs_info;
223225 struct inode *inode;
224− int err;
225−
226− fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
227− sb->s_fs_info = fsi;
228− if (!fsi)
229− return -ENOMEM;
230−
231− err = ramfs_parse_options(data, &fsi->mount_opts);
232− if (err)
233− return err;
234226
235227 sb->s_maxbytes = MAX_LFS_FILESIZE;
236228 sb->s_blocksize = PAGE_SIZE;
@@ -247,10 +239,34 @@ int ramfs_fill_super(struct super_block *sb, void *data, int silent) · 10 unmodified lines
247239 return 0;
248240 }
249241
250−struct dentry *ramfs_mount(struct file_system_type *fs_type,
251− int flags, const char *dev_name, void *data)
242+static int ramfs_get_tree(struct fs_context *fc)
252243 {
253− return mount_nodev(fs_type, flags, data, ramfs_fill_super);
244+ return get_tree_nodev(fc, ramfs_fill_super);
245+}
246+
247+static void ramfs_free_fc(struct fs_context *fc)
248+{
249+ kfree(fc->s_fs_info);
250+}
251+
252+static const struct fs_context_operations ramfs_context_ops = {
253+ .free = ramfs_free_fc,
254+ .parse_param = ramfs_parse_param,
255+ .get_tree = ramfs_get_tree,
256+};
257+
258+int ramfs_init_fs_context(struct fs_context *fc)
259+{
260+ struct ramfs_fs_info *fsi;
261+
262+ fsi = kzalloc(sizeof(*fsi), GFP_KERNEL);
263+ if (!fsi)
264+ return -ENOMEM;
265+
266+ fsi->mount_opts.mode = RAMFS_DEFAULT_MODE;
267+ fc->s_fs_info = fsi;
268+ fc->ops = &ramfs_context_ops;
269+ return 0;
254270 }
255271
256272 static void ramfs_kill_sb(struct super_block *sb)
@@ -261,7 +277,8 @@ static void ramfs_kill_sb(struct super_block *sb) · 4 unmodified lines
261277
262278 static struct file_system_type ramfs_fs_type = {
263279 .name = "ramfs",
264− .mount = ramfs_mount,
280+ .init_fs_context = ramfs_init_fs_context,
281+ .parameters = &ramfs_fs_parameters,
265282 .kill_sb = ramfs_kill_sb,
266283 .fs_flags = FS_USERNS_MOUNT,
267284 };
fs/romfs/super.c+28−18
@@ -65,7 +65,7 @@ · 64 unmodified lines
6565 #include <linux/slab.h>
6666 #include <linux/init.h>
6767 #include <linux/blkdev.h>
68−#include <linux/parser.h>
68+#include <linux/fs_context.h>
6969 #include <linux/mount.h>
7070 #include <linux/namei.h>
7171 #include <linux/statfs.h>
@@ -423,10 +423,10 @@ static int romfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 351 unmodified lines
423423 /*
424424 * remounting must involve read-only
425425 */
426−static int romfs_remount(struct super_block *sb, int *flags, char *data)
426+static int romfs_reconfigure(struct fs_context *fc)
427427 {
428− sync_filesystem(sb);
429− *flags |= SB_RDONLY;
428+ sync_filesystem(fc->root->d_sb);
429+ fc->sb_flags |= SB_RDONLY;
430430 return 0;
431431 }
432432
@@ -434,7 +434,6 @@ static const struct super_operations romfs_super_ops = { · 1 unmodified line
434434 .alloc_inode = romfs_alloc_inode,
435435 .free_inode = romfs_free_inode,
436436 .statfs = romfs_statfs,
437− .remount_fs = romfs_remount,
438437 };
439438
440439 /*
@@ -457,7 +456,7 @@ static __u32 romfs_checksum(const void *data, int size) · 16 unmodified lines
457456 /*
458457 * fill in the superblock
459458 */
460−static int romfs_fill_super(struct super_block *sb, void *data, int silent)
459+static int romfs_fill_super(struct super_block *sb, struct fs_context *fc)
461460 {
462461 struct romfs_super_block *rsb;
463462 struct inode *root;
@@ -506,8 +505,8 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent) · 42 unmodified lines
506505
507506 if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1 ||
508507 img_size < ROMFH_SIZE) {
509− if (!silent)
510− pr_warn("VFS: Can't find a romfs filesystem on dev %s.\n",
508+ if (!(fc->sb_flags & SB_SILENT))
509+ errorf(fc, "VFS: Can't find a romfs filesystem on dev %s.\n",
511510 sb->s_id);
512511 goto error_rsb_inval;
513512 }
@@ -520,7 +519,7 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent) · 6 unmodified lines
520519 storage = sb->s_mtd ? "MTD" : "the block layer";
521520
522521 len = strnlen(rsb->name, ROMFS_MAXFN);
523− if (!silent)
522+ if (!(fc->sb_flags & SB_SILENT))
524523 pr_notice("Mounting image '%*.*s' through %s\n",
525524 (unsigned) len, (unsigned) len, rsb->name, storage);
526525
@@ -550,23 +549,34 @@ error_rsb: · 23 unmodified lines
550549 /*
551550 * get a superblock for mounting
552551 */
553−static struct dentry *romfs_mount(struct file_system_type *fs_type,
554− int flags, const char *dev_name,
555− void *data)
552+static int romfs_get_tree(struct fs_context *fc)
556553 {
557− struct dentry *ret = ERR_PTR(-EINVAL);
554+ int ret = -EINVAL;
558555
559556 #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);
561558 #endif
562559 #ifdef CONFIG_ROMFS_ON_BLOCK
563− if (ret == ERR_PTR(-EINVAL))
564− ret = mount_bdev(fs_type, flags, dev_name, data,
565− romfs_fill_super);
560+ if (ret == -EINVAL)
561+ ret = get_tree_bdev(fc, romfs_fill_super);
566562 #endif
567563 return ret;
568564 }
569565
566+static 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+ */
574+static int romfs_init_fs_context(struct fs_context *fc)
575+{
576+ fc->ops = &romfs_context_ops;
577+ return 0;
578+}
579+
570580 /*
571581 * destroy a romfs superblock in the appropriate manner
572582 */
@@ -589,7 +599,7 @@ static void romfs_kill_sb(struct super_block *sb) · 16 unmodified lines
589599 static struct file_system_type romfs_fs_type = {
590600 .owner = THIS_MODULE,
591601 .name = "romfs",
592− .mount = romfs_mount,
602+ .init_fs_context = romfs_init_fs_context,
593603 .kill_sb = romfs_kill_sb,
594604 .fs_flags = FS_REQUIRES_DEV,
595605 };
fs/squashfs/super.c+55−45
@@ -17,6 +17,7 @@ · 16 unmodified lines
1717 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1818
1919 #include <linux/fs.h>
20+#include <linux/fs_context.h>
2021 #include <linux/vfs.h>
2122 #include <linux/slab.h>
2223 #include <linux/mutex.h>
@@ -36,26 +37,27 @@ · 13 unmodified lines
3637 static struct file_system_type squashfs_fs_type;
3738 static const struct super_operations squashfs_super_ops;
3839
39−static const struct squashfs_decompressor *supported_squashfs_filesystem(short
40− major, short minor, short id)
40+static const struct squashfs_decompressor *supported_squashfs_filesystem(
41+ struct fs_context *fc,
42+ short major, short minor, short id)
4143 {
4244 const struct squashfs_decompressor *decompressor;
4345
4446 if (major < SQUASHFS_MAJOR) {
45− ERROR("Major/Minor mismatch, older Squashfs %d.%d "
46− "filesystems are unsupported\n", major, minor);
47+ errorf(fc, "Major/Minor mismatch, older Squashfs %d.%d "
48+ "filesystems are unsupported", major, minor);
4749 return NULL;
4850 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) {
49− ERROR("Major/Minor mismatch, trying to mount newer "
50− "%d.%d filesystem\n", major, minor);
51− ERROR("Please update your kernel\n");
51+ errorf(fc, "Major/Minor mismatch, trying to mount newer "
52+ "%d.%d filesystem", major, minor);
53+ errorf(fc, "Please update your kernel");
5254 return NULL;
5355 }
5456
5557 decompressor = squashfs_lookup_decompressor(id);
5658 if (!decompressor->supported) {
57− ERROR("Filesystem uses \"%s\" compression. This is not "
58− "supported\n", decompressor->name);
59+ errorf(fc, "Filesystem uses \"%s\" compression. This is not supported",
60+ decompressor->name);
5961 return NULL;
6062 }
6163
@@ -63,7 +65,7 @@ static const struct squashfs_decompressor *supported_squashfs_filesystem(short · 1 unmodified line
6365 }
6466
6567
66−static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
68+static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc)
6769 {
6870 struct squashfs_sb_info *msblk;
6971 struct squashfs_super_block *sblk = NULL;
@@ -98,7 +100,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) · 28 unmodified lines
98100 sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk));
99101
100102 if (IS_ERR(sblk)) {
101− ERROR("unable to read squashfs_super_block\n");
103+ errorf(fc, "unable to read squashfs_super_block");
102104 err = PTR_ERR(sblk);
103105 sblk = NULL;
104106 goto failed_mount;
@@ -109,14 +111,15 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) · 4 unmodified lines
109111 /* Check it is a SQUASHFS superblock */
110112 sb->s_magic = le32_to_cpu(sblk->s_magic);
111113 if (sb->s_magic != SQUASHFS_MAGIC) {
112− if (!silent)
113− ERROR("Can't find a SQUASHFS superblock on %pg\n",
114− sb->s_bdev);
114+ if (!(fc->sb_flags & SB_SILENT))
115+ errorf(fc, "Can't find a SQUASHFS superblock on %pg",
116+ sb->s_bdev);
115117 goto failed_mount;
116118 }
117119
118120 /* Check the MAJOR & MINOR versions and lookup compression type */
119121 msblk->decompressor = supported_squashfs_filesystem(
122+ fc,
120123 le16_to_cpu(sblk->s_major),
121124 le16_to_cpu(sblk->s_minor),
122125 le16_to_cpu(sblk->compression));
@@ -133,15 +136,15 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) · 10 unmodified lines
133136 /* Check block size for sanity */
134137 msblk->block_size = le32_to_cpu(sblk->block_size);
135138 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE)
136− goto failed_mount;
139+ goto insanity;
137140
138141 /*
139142 * Check the system page size is not larger than the filesystem
140143 * block size (by default 128K). This is currently not supported.
141144 */
142145 if (PAGE_SIZE > msblk->block_size) {
143− ERROR("Page size > filesystem block size (%d). This is "
144− "currently not supported!\n", msblk->block_size);
146+ errorf(fc, "Page size > filesystem block size (%d). This is "
147+ "currently not supported!", msblk->block_size);
145148 goto failed_mount;
146149 }
147150
@@ -152,12 +155,12 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) · 4 unmodified lines
152155
153156 /* Check that block_size and block_log match */
154157 if (msblk->block_size != (1 << msblk->block_log))
155− goto failed_mount;
158+ goto insanity;
156159
157160 /* Check the root inode for sanity */
158161 root_inode = le64_to_cpu(sblk->root_inode);
159162 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE)
160− goto failed_mount;
163+ goto insanity;
161164
162165 msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
163166 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) · 35 unmodified lines
199202 msblk->read_page = squashfs_cache_init("data",
200203 squashfs_max_decompressors(), msblk->block_size);
201204 if (msblk->read_page == NULL) {
202− ERROR("Failed to allocate read_page block\n");
205+ errorf(fc, "Failed to allocate read_page block");
203206 goto failed_mount;
204207 }
205208
@@ -207,7 +210,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) · 1 unmodified line
207210 if (IS_ERR(msblk->stream)) {
208211 err = PTR_ERR(msblk->stream);
209212 msblk->stream = NULL;
210− goto failed_mount;
213+ goto insanity;
211214 }
212215
213216 /* Handle xattrs */
@@ -222,7 +225,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) · 8 unmodified lines
222225 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb,
223226 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids);
224227 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");
226229 err = PTR_ERR(msblk->xattr_id_table);
227230 msblk->xattr_id_table = NULL;
228231 if (err != -ENOTSUPP)
@@ -236,7 +239,7 @@ allocate_id_index_table: · 7 unmodified lines
236239 le64_to_cpu(sblk->id_table_start), next_table,
237240 le16_to_cpu(sblk->no_ids));
238241 if (IS_ERR(msblk->id_table)) {
239− ERROR("unable to read id index table\n");
242+ errorf(fc, "unable to read id index table");
240243 err = PTR_ERR(msblk->id_table);
241244 msblk->id_table = NULL;
242245 goto failed_mount;
@@ -252,7 +255,7 @@ allocate_id_index_table: · 9 unmodified lines
252255 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb,
253256 lookup_table_start, next_table, msblk->inodes);
254257 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");
256259 err = PTR_ERR(msblk->inode_lookup_table);
257260 msblk->inode_lookup_table = NULL;
258261 goto failed_mount;
@@ -277,7 +280,7 @@ handle_fragments: · 18 unmodified lines
277280 msblk->fragment_index = squashfs_read_fragment_index_table(sb,
278281 le64_to_cpu(sblk->fragment_table_start), next_table, fragments);
279282 if (IS_ERR(msblk->fragment_index)) {
280− ERROR("unable to read fragment index table\n");
283+ errorf(fc, "unable to read fragment index table");
281284 err = PTR_ERR(msblk->fragment_index);
282285 msblk->fragment_index = NULL;
283286 goto failed_mount;
@@ -288,13 +291,13 @@ check_directory_table: · 4 unmodified lines
288291 /* Sanity check directory_table */
289292 if (msblk->directory_table > next_table) {
290293 err = -EINVAL;
291− goto failed_mount;
294+ goto insanity;
292295 }
293296
294297 /* Sanity check inode_table */
295298 if (msblk->inode_table >= msblk->directory_table) {
296299 err = -EINVAL;
297− goto failed_mount;
300+ goto insanity;
298301 }
299302
300303 /* allocate root */
@@ -323,6 +326,8 @@ check_directory_table: · 22 unmodified lines
323326 kfree(sblk);
324327 return 0;
325328
329+insanity:
330+ errorf(fc, "squashfs image failed sanity check");
326331 failed_mount:
327332 squashfs_cache_delete(msblk->block_cache);
328333 squashfs_cache_delete(msblk->fragment_cache);
@@ -338,6 +343,28 @@ failed_mount: · 9 unmodified lines
338343 return err;
339344 }
340345
346+static int squashfs_get_tree(struct fs_context *fc)
347+{
348+ return get_tree_bdev(fc, squashfs_fill_super);
349+}
350+
351+static 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+
358+static const struct fs_context_operations squashfs_context_ops = {
359+ .get_tree = squashfs_get_tree,
360+ .reconfigure = squashfs_reconfigure,
361+};
362+
363+static int squashfs_init_fs_context(struct fs_context *fc)
364+{
365+ fc->ops = &squashfs_context_ops;
366+ return 0;
367+}
341368
342369 static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
343370 {
@@ -360,14 +387,6 @@ static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) · 16 unmodified lines
360387 }
361388
362389
363−static 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−
371390 static void squashfs_put_super(struct super_block *sb)
372391 {
373392 if (sb->s_fs_info) {
@@ -386,14 +405,6 @@ static void squashfs_put_super(struct super_block *sb) · 12 unmodified lines
386405 }
387406 }
388407
389−
390−static 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−
397408 static struct kmem_cache *squashfs_inode_cachep;
398409
399410
@@ -470,7 +481,7 @@ static void squashfs_free_inode(struct inode *inode) · 70 unmodified lines
470481 static struct file_system_type squashfs_fs_type = {
471482 .owner = THIS_MODULE,
472483 .name = "squashfs",
473− .mount = squashfs_mount,
484+ .init_fs_context = squashfs_init_fs_context,
474485 .kill_sb = kill_block_super,
475486 .fs_flags = FS_REQUIRES_DEV
476487 };
@@ -481,7 +492,6 @@ static const struct super_operations squashfs_super_ops = { · 4 unmodified lines
481492 .free_inode = squashfs_free_inode,
482493 .statfs = squashfs_statfs,
483494 .put_super = squashfs_put_super,
484− .remount_fs = squashfs_remount
485495 };
486496
487497 module_init(init_squashfs_fs);
fs/super.c+28−7
@@ -1164,9 +1164,11 @@ int vfs_get_super(struct fs_context *fc, · 1163 unmodified lines
11641164 {
11651165 int (*test)(struct super_block *, struct fs_context *);
11661166 struct super_block *sb;
1167+ int err;
11671168
11681169 switch (keying) {
11691170 case vfs_get_single_super:
1171+ case vfs_get_single_reconf_super:
11701172 test = test_single_super;
11711173 break;
11721174 case vfs_get_keyed_super:
@@ -1184,18 +1186,29 @@ int vfs_get_super(struct fs_context *fc, · 11 unmodified lines
11841186 return PTR_ERR(sb);
11851187
11861188 if (!sb->s_root) {
1187− int err = fill_super(sb, fc);
1188− if (err) {
1189− deactivate_locked_super(sb);
1190− return err;
1191− }
1189+ err = fill_super(sb, fc);
1190+ if (err)
1191+ goto error;
11921192
11931193 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+ }
11941205 }
11951206
1196− BUG_ON(fc->root);
1197− fc->root = dget(sb->s_root);
11981207 return 0;
1208+
1209+error:
1210+ deactivate_locked_super(sb);
1211+ return err;
11991212 }
12001213 EXPORT_SYMBOL(vfs_get_super);
12011214
@@ -1215,6 +1228,14 @@ int get_tree_single(struct fs_context *fc, · 13 unmodified lines
12151228 }
12161229 EXPORT_SYMBOL(get_tree_single);
12171230
1231+int 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+}
1237+EXPORT_SYMBOL(get_tree_single_reconf);
1238+
12181239 int get_tree_keyed(struct fs_context *fc,
12191240 int (*fill_super)(struct super_block *sb,
12201241 struct fs_context *fc),
include/linux/fs_context.h+4−0
@@ -141,6 +141,7 @@ extern void put_fs_context(struct fs_context *fc); · 140 unmodified lines
141141 */
142142 enum vfs_get_super_keying {
143143 vfs_get_single_super, /* Only one such superblock may exist */
144+ vfs_get_single_reconf_super, /* As above, but reconfigure if it exists */
144145 vfs_get_keyed_super, /* Superblocks with different s_fs_info keys may exist */
145146 vfs_get_independent_super, /* Multiple independent superblocks may exist */
146147 };
@@ -155,6 +156,9 @@ extern int get_tree_nodev(struct fs_context *fc, · 8 unmodified lines
155156 extern int get_tree_single(struct fs_context *fc,
156157 int (*fill_super)(struct super_block *sb,
157158 struct fs_context *fc));
159+extern int get_tree_single_reconf(struct fs_context *fc,
160+ int (*fill_super)(struct super_block *sb,
161+ struct fs_context *fc));
158162 extern int get_tree_keyed(struct fs_context *fc,
159163 int (*fill_super)(struct super_block *sb,
160164 struct fs_context *fc),
include/linux/mtd/super.h+0−3
@@ -17,9 +17,6 @@ · 16 unmodified lines
1717 extern int get_tree_mtd(struct fs_context *fc,
1818 int (*fill_super)(struct super_block *sb,
1919 struct fs_context *fc));
20−extern 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));
2320 extern void kill_mtd_super(struct super_block *sb);
2421
2522
include/linux/ramfs.h+2−4
@@ -4,8 +4,7 @@ · 3 unmodified lines
44
55 struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
66 umode_t mode, dev_t dev);
7−extern struct dentry *ramfs_mount(struct file_system_type *fs_type,
8− int flags, const char *dev_name, void *data);
7+extern int ramfs_init_fs_context(struct fs_context *fc);
98
109 #ifdef CONFIG_MMU
1110 static inline int
@@ -17,9 +16,8 @@ ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) · 5 unmodified lines
1716 extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
1817 #endif
1918
19+extern const struct fs_parameter_description ramfs_fs_parameters;
2020 extern const struct file_operations ramfs_file_operations;
2121 extern const struct vm_operations_struct generic_file_vm_ops;
2222
23−int ramfs_fill_super(struct super_block *sb, void *data, int silent);
24−
2523 #endif
include/linux/shmem_fs.h+2−1
@@ -49,8 +49,9 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) · 48 unmodified lines
4949 /*
5050 * Functions in mm/shmem.c called directly from elsewhere:
5151 */
52+extern const struct fs_parameter_description shmem_fs_parameters;
5253 extern int shmem_init(void);
53−extern int shmem_fill_super(struct super_block *sb, void *data, int silent);
54+extern int shmem_init_fs_context(struct fs_context *fc);
5455 extern struct file *shmem_file_setup(const char *name,
5556 loff_t size, unsigned long flags);
5657 extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
init/do_mounts.c+4−7
@@ -627,20 +627,17 @@ out: · 626 unmodified lines
627627 }
628628
629629 static bool is_tmpfs;
630−static struct dentry *rootfs_mount(struct file_system_type *fs_type,
631− int flags, const char *dev_name, void *data)
630+static int rootfs_init_fs_context(struct fs_context *fc)
632631 {
633− void *fill = ramfs_fill_super;
634−
635632 if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs)
636− fill = shmem_fill_super;
633+ return shmem_init_fs_context(fc);
637634
638− return mount_nodev(fs_type, flags, data, fill);
635+ return ramfs_init_fs_context(fc);
639636 }
640637
641638 struct file_system_type rootfs_fs_type = {
642639 .name = "rootfs",
643− .mount = rootfs_mount,
640+ .init_fs_context = rootfs_init_fs_context,
644641 .kill_sb = kill_litter_super,
645642 };
646643
mm/shmem.c+248−137
@@ -37,6 +37,7 @@ · 36 unmodified lines
3737 #include <linux/khugepaged.h>
3838 #include <linux/hugetlb.h>
3939 #include <linux/frontswap.h>
40+#include <linux/fs_parser.h>
4041
4142 #include <asm/tlbflush.h> /* for arch/microblaze update_mmu_cache() */
4243
@@ -107,6 +108,20 @@ struct shmem_falloc { · 64 unmodified lines
107108 pgoff_t nr_unswapped; /* how often writepage refused to swap out */
108109 };
109110
111+struct 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+
110125 #ifdef CONFIG_TMPFS
111126 static unsigned long shmem_default_max_blocks(void)
112127 {
@@ -3349,16 +3364,126 @@ static const struct export_operations shmem_export_ops = { · 3236 unmodified lines
33493364 .fh_to_dentry = shmem_fh_to_dentry,
33503365 };
33513366
3352−static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo,
3353− bool remount)
3367+enum shmem_param {
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+
3378+static 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+
3390+static 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+
3398+const struct fs_parameter_description shmem_fs_parameters = {
3399+ .name = "tmpfs",
3400+ .specs = shmem_param_specs,
3401+ .enums = shmem_param_enums,
3402+};
3403+
3404+static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
33543405 {
3355− char *this_char, *value, *rest;
3356− struct mempolicy *mpol = NULL;
3357− uid_t uid;
3358− gid_t gid;
3406+ struct shmem_options *ctx = fc->fs_private;
3407+ struct fs_parse_result result;
3408+ unsigned long long size;
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+
3475+unsupported_parameter:
3476+ return invalf(fc, "tmpfs: Unsupported parameter '%s'", param->key);
3477+bad_value:
3478+ return invalf(fc, "tmpfs: Bad value for '%s'", param->key);
3479+}
3480+
3481+static int shmem_parse_options(struct fs_context *fc, void *data)
3482+{
3483+ char *options = data;
33593484
33603485 while (options != NULL) {
3361− this_char = options;
3486+ char *this_char = options;
33623487 for (;;) {
33633488 /*
33643489 * NUL-terminate this option: unfortunately,
@@ -3374,139 +3499,83 @@ static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo, · 9 unmodified lines
33743499 break;
33753500 }
33763501 }
3377− if (!*this_char)
3378− continue;
3379− if ((value = strchr(this_char,'=')) != NULL) {
3380− *value++ = 0;
3381− } else {
3382− pr_err("tmpfs: No value for mount option '%s'\n",
3383− this_char);
3384− goto error;
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++;
3502+ if (*this_char) {
3503+ char *value = strchr(this_char,'=');
3504+ size_t len = 0;
3505+ int err;
3506+
3507+ if (value) {
3508+ *value++ = '\0';
3509+ len = strlen(value);
33953510 }
3396− if (*rest)
3397− goto bad_val;
3398− sbinfo->max_blocks =
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;
3511+ err = vfs_parse_fs_string(fc, this_char, value, len);
3512+ if (err < 0)
3513+ return err;
34533514 }
34543515 }
3455− sbinfo->mpol = mpol;
34563516 return 0;
3457−
3458−bad_val:
3459− pr_err("tmpfs: Bad value '%s' for mount option '%s'\n",
3460− value, this_char);
3461−error:
3462− mpol_put(mpol);
3463− return 1;
3464−
34653517 }
34663518
3467−static 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+ */
3526+static int shmem_reconfigure(struct fs_context *fc)
34683527 {
3469− struct shmem_sb_info *sbinfo = SHMEM_SB(sb);
3470− struct shmem_sb_info config = *sbinfo;
3528+ struct shmem_options *ctx = fc->fs_private;
3529+ struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb);
34713530 unsigned long inodes;
3472− int error = -EINVAL;
3473−
3474− config.mpol = NULL;
3475− if (shmem_parse_options(data, &config, true))
3476− return error;
3531+ const char *err;
34773532
34783533 spin_lock(&sbinfo->stat_lock);
34793534 inodes = sbinfo->max_inodes - sbinfo->free_inodes;
3480− if (percpu_counter_compare(&sbinfo->used_blocks, config.max_blocks) > 0)
3481− goto out;
3482− if (config.max_inodes < inodes)
3483− goto out;
3484− /*
3485− * Those tests disallow limited->unlimited while any are in use;
3486− * but we must separately disallow unlimited->limited, because
3487− * in that case we have no record of how much is already in use.
3488− */
3489− if (config.max_blocks && !sbinfo->max_blocks)
3490− goto out;
3491− if (config.max_inodes && !sbinfo->max_inodes)
3492− goto out;
3535+ if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) {
3536+ if (!sbinfo->max_blocks) {
3537+ err = "Cannot retroactively limit size";
3538+ goto out;
3539+ }
3540+ if (percpu_counter_compare(&sbinfo->used_blocks,
3541+ ctx->blocks) > 0) {
3542+ err = "Too small a size for current use";
3543+ goto out;
3544+ }
3545+ }
3546+ if ((ctx->seen & SHMEM_SEEN_INODES) && ctx->inodes) {
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+ }
34933556
3494− error = 0;
3495− sbinfo->huge = config.huge;
3496− sbinfo->max_blocks = config.max_blocks;
3497− sbinfo->max_inodes = config.max_inodes;
3498− sbinfo->free_inodes = config.max_inodes - inodes;
3557+ if (ctx->seen & SHMEM_SEEN_HUGE)
3558+ sbinfo->huge = ctx->huge;
3559+ if (ctx->seen & SHMEM_SEEN_BLOCKS)
3560+ sbinfo->max_blocks = ctx->blocks;
3561+ if (ctx->seen & SHMEM_SEEN_INODES) {
3562+ sbinfo->max_inodes = ctx->inodes;
3563+ sbinfo->free_inodes = ctx->inodes - inodes;
3564+ }
34993565
35003566 /*
35013567 * Preserve previous mempolicy unless mpol remount option was specified.
35023568 */
3503− if (config.mpol) {
3569+ if (ctx->mpol) {
35043570 mpol_put(sbinfo->mpol);
3505− sbinfo->mpol = config.mpol; /* transfers initial ref */
3571+ sbinfo->mpol = ctx->mpol; /* transfers initial ref */
3572+ ctx->mpol = NULL;
35063573 }
3574+ spin_unlock(&sbinfo->stat_lock);
3575+ return 0;
35073576 out:
35083577 spin_unlock(&sbinfo->stat_lock);
3509− return error;
3578+ return invalf(fc, "tmpfs: %s", err);
35103579 }
35113580
35123581 static int shmem_show_options(struct seq_file *seq, struct dentry *root)
@@ -3547,8 +3616,9 @@ static void shmem_put_super(struct super_block *sb) · 34 unmodified lines
35473616 sb->s_fs_info = NULL;
35483617 }
35493618
3550−int shmem_fill_super(struct super_block *sb, void *data, int silent)
3619+static int shmem_fill_super(struct super_block *sb, struct fs_context *fc)
35513620 {
3621+ struct shmem_options *ctx = fc->fs_private;
35523622 struct inode *inode;
35533623 struct shmem_sb_info *sbinfo;
35543624 int err = -ENOMEM;
@@ -3559,9 +3629,6 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) · 4 unmodified lines
35593629 if (!sbinfo)
35603630 return -ENOMEM;
35613631
3562− sbinfo->mode = 0777 | S_ISVTX;
3563− sbinfo->uid = current_fsuid();
3564− sbinfo->gid = current_fsgid();
35653632 sb->s_fs_info = sbinfo;
35663633
35673634 #ifdef CONFIG_TMPFS
@@ -3571,12 +3638,10 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) · 3 unmodified lines
35713638 * but the internal instance is left unlimited.
35723639 */
35733640 if (!(sb->s_flags & SB_KERNMOUNT)) {
3574− sbinfo->max_blocks = shmem_default_max_blocks();
3575− sbinfo->max_inodes = shmem_default_max_inodes();
3576− if (shmem_parse_options(data, sbinfo, false)) {
3577− err = -EINVAL;
3578− goto failed;
3579− }
3641+ if (!(ctx->seen & SHMEM_SEEN_BLOCKS))
3642+ ctx->blocks = shmem_default_max_blocks();
3643+ if (!(ctx->seen & SHMEM_SEEN_INODES))
3644+ ctx->inodes = shmem_default_max_inodes();
35803645 } else {
35813646 sb->s_flags |= SB_NOUSER;
35823647 }
@@ -3585,11 +3650,18 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) · 2 unmodified lines
35853650 #else
35863651 sb->s_flags |= SB_NOUSER;
35873652 #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;
35883661
35893662 spin_lock_init(&sbinfo->stat_lock);
35903663 if (percpu_counter_init(&sbinfo->used_blocks, 0, GFP_KERNEL))
35913664 goto failed;
3592− sbinfo->free_inodes = sbinfo->max_inodes;
35933665 spin_lock_init(&sbinfo->shrinklist_lock);
35943666 INIT_LIST_HEAD(&sbinfo->shrinklist);
35953667
@@ -3622,6 +3694,31 @@ failed: · 26 unmodified lines
36223694 return err;
36233695 }
36243696
3697+static int shmem_get_tree(struct fs_context *fc)
3698+{
3699+ return get_tree_nodev(fc, shmem_fill_super);
3700+}
3701+
3702+static 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+
3712+static 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+
36253722 static struct kmem_cache *shmem_inode_cachep;
36263723
36273724 static struct inode *shmem_alloc_inode(struct super_block *sb)
@@ -3738,7 +3835,6 @@ static const struct super_operations shmem_ops = { · 110 unmodified lines
37383835 .destroy_inode = shmem_destroy_inode,
37393836 #ifdef CONFIG_TMPFS
37403837 .statfs = shmem_statfs,
3741− .remount_fs = shmem_remount_fs,
37423838 .show_options = shmem_show_options,
37433839 #endif
37443840 .evict_inode = shmem_evict_inode,
@@ -3759,16 +3855,30 @@ static const struct vm_operations_struct shmem_vm_ops = { · 14 unmodified lines
37593855 #endif
37603856 };
37613857
3762−static struct dentry *shmem_mount(struct file_system_type *fs_type,
3763− int flags, const char *dev_name, void *data)
3858+int shmem_init_fs_context(struct fs_context *fc)
37643859 {
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;
37663873 }
37673874
37683875 static struct file_system_type shmem_fs_type = {
37693876 .owner = THIS_MODULE,
37703877 .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
37723882 .kill_sb = kill_litter_super,
37733883 .fs_flags = FS_USERNS_MOUNT,
37743884 };
@@ -3912,7 +4022,8 @@ bool shmem_huge_enabled(struct vm_area_struct *vma) · 137 unmodified lines
39124022
39134023 static struct file_system_type shmem_fs_type = {
39144024 .name = "tmpfs",
3915− .mount = ramfs_mount,
4025+ .init_fs_context = ramfs_init_fs_context,
4026+ .parameters = &ramfs_fs_parameters,
39164027 .kill_sb = kill_litter_super,
39174028 .fs_flags = FS_USERNS_MOUNT,
39184029 };

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t