diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-19 13:42:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-19 13:42:02 -0400 |
commit | 933a90bf4f3505f8ec83bda21a3c7d70d7c2b426 (patch) | |
tree | ca81c209000a15670e3582760ad9bae1a9cde215 | |
parent | 5f4fc6d440d77a2cf74fe4ea56955674ac7e35e7 (diff) | |
parent | 037f11b4752f717201143a1dc5d6acf3cb71ddfa (diff) |
Merge branch 'work.mount0' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs mount updates from Al Viro:
"The first part of mount updates.
Convert filesystems to use the new mount API"
* 'work.mount0' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits)
mnt_init(): call shmem_init() unconditionally
constify ksys_mount() string arguments
don't bother with registering rootfs
init_rootfs(): don't bother with init_ramfs_fs()
vfs: Convert smackfs to use the new mount API
vfs: Convert selinuxfs to use the new mount API
vfs: Convert securityfs to use the new mount API
vfs: Convert apparmorfs to use the new mount API
vfs: Convert openpromfs to use the new mount API
vfs: Convert xenfs to use the new mount API
vfs: Convert gadgetfs to use the new mount API
vfs: Convert oprofilefs to use the new mount API
vfs: Convert ibmasmfs to use the new mount API
vfs: Convert qib_fs/ipathfs to use the new mount API
vfs: Convert efivarfs to use the new mount API
vfs: Convert configfs to use the new mount API
vfs: Convert binfmt_misc to use the new mount API
convenience helper: get_tree_single()
convenience helper get_tree_nodev()
vfs: Kill sget_userns()
...
60 files changed, 581 insertions, 533 deletions
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 7c52bd2695a2..a23c3938a1c4 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/smp.h> | 39 | #include <linux/smp.h> |
40 | #include <linux/pagemap.h> | 40 | #include <linux/pagemap.h> |
41 | #include <linux/mount.h> | 41 | #include <linux/mount.h> |
42 | #include <linux/pseudo_fs.h> | ||
42 | #include <linux/bitops.h> | 43 | #include <linux/bitops.h> |
43 | #include <linux/capability.h> | 44 | #include <linux/capability.h> |
44 | #include <linux/rcupdate.h> | 45 | #include <linux/rcupdate.h> |
@@ -600,17 +601,19 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f) | |||
600 | /* forward declaration */ | 601 | /* forward declaration */ |
601 | static const struct dentry_operations pfmfs_dentry_operations; | 602 | static const struct dentry_operations pfmfs_dentry_operations; |
602 | 603 | ||
603 | static struct dentry * | 604 | static int pfmfs_init_fs_context(struct fs_context *fc) |
604 | pfmfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) | ||
605 | { | 605 | { |
606 | return mount_pseudo(fs_type, "pfm:", NULL, &pfmfs_dentry_operations, | 606 | struct pseudo_fs_context *ctx = init_pseudo(fc, PFMFS_MAGIC); |
607 | PFMFS_MAGIC); | 607 | if (!ctx) |
608 | return -ENOMEM; | ||
609 | ctx->dops = &pfmfs_dentry_operations; | ||
610 | return 0; | ||
608 | } | 611 | } |
609 | 612 | ||
610 | static struct file_system_type pfm_fs_type = { | 613 | static struct file_system_type pfm_fs_type = { |
611 | .name = "pfmfs", | 614 | .name = "pfmfs", |
612 | .mount = pfmfs_mount, | 615 | .init_fs_context = pfmfs_init_fs_context, |
613 | .kill_sb = kill_anon_super, | 616 | .kill_sb = kill_anon_super, |
614 | }; | 617 | }; |
615 | MODULE_ALIAS_FS("pfmfs"); | 618 | MODULE_ALIAS_FS("pfmfs"); |
616 | 619 | ||
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index bf3034994754..a46dee8e78db 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c | |||
@@ -2104,8 +2104,7 @@ static int rdt_init_fs_context(struct fs_context *fc) | |||
2104 | ctx->kfc.magic = RDTGROUP_SUPER_MAGIC; | 2104 | ctx->kfc.magic = RDTGROUP_SUPER_MAGIC; |
2105 | fc->fs_private = &ctx->kfc; | 2105 | fc->fs_private = &ctx->kfc; |
2106 | fc->ops = &rdt_fs_context_ops; | 2106 | fc->ops = &rdt_fs_context_ops; |
2107 | if (fc->user_ns) | 2107 | put_user_ns(fc->user_ns); |
2108 | put_user_ns(fc->user_ns); | ||
2109 | fc->user_ns = get_user_ns(&init_user_ns); | 2108 | fc->user_ns = get_user_ns(&init_user_ns); |
2110 | fc->global = true; | 2109 | fc->global = true; |
2111 | return 0; | 2110 | return 0; |
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c index 0dbc43068eeb..ba5c80903efe 100644 --- a/drivers/base/devtmpfs.c +++ b/drivers/base/devtmpfs.c | |||
@@ -357,8 +357,7 @@ int devtmpfs_mount(const char *mntdir) | |||
357 | if (!thread) | 357 | if (!thread) |
358 | return 0; | 358 | return 0; |
359 | 359 | ||
360 | err = ksys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, | 360 | err = ksys_mount("devtmpfs", mntdir, "devtmpfs", MS_SILENT, NULL); |
361 | NULL); | ||
362 | if (err) | 361 | if (err) |
363 | printk(KERN_INFO "devtmpfs: error mounting %i\n", err); | 362 | printk(KERN_INFO "devtmpfs: error mounting %i\n", err); |
364 | else | 363 | else |
diff --git a/drivers/dax/super.c b/drivers/dax/super.c index 8ab12068eea3..26a654dbc69a 100644 --- a/drivers/dax/super.c +++ b/drivers/dax/super.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/pagemap.h> | 5 | #include <linux/pagemap.h> |
6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
7 | #include <linux/mount.h> | 7 | #include <linux/mount.h> |
8 | #include <linux/pseudo_fs.h> | ||
8 | #include <linux/magic.h> | 9 | #include <linux/magic.h> |
9 | #include <linux/genhd.h> | 10 | #include <linux/genhd.h> |
10 | #include <linux/pfn_t.h> | 11 | #include <linux/pfn_t.h> |
@@ -469,16 +470,19 @@ static const struct super_operations dax_sops = { | |||
469 | .drop_inode = generic_delete_inode, | 470 | .drop_inode = generic_delete_inode, |
470 | }; | 471 | }; |
471 | 472 | ||
472 | static struct dentry *dax_mount(struct file_system_type *fs_type, | 473 | static int dax_init_fs_context(struct fs_context *fc) |
473 | int flags, const char *dev_name, void *data) | ||
474 | { | 474 | { |
475 | return mount_pseudo(fs_type, "dax:", &dax_sops, NULL, DAXFS_MAGIC); | 475 | struct pseudo_fs_context *ctx = init_pseudo(fc, DAXFS_MAGIC); |
476 | if (!ctx) | ||
477 | return -ENOMEM; | ||
478 | ctx->ops = &dax_sops; | ||
479 | return 0; | ||
476 | } | 480 | } |
477 | 481 | ||
478 | static struct file_system_type dax_fs_type = { | 482 | static struct file_system_type dax_fs_type = { |
479 | .name = "dax", | 483 | .name = "dax", |
480 | .mount = dax_mount, | 484 | .init_fs_context = dax_init_fs_context, |
481 | .kill_sb = kill_anon_super, | 485 | .kill_sb = kill_anon_super, |
482 | }; | 486 | }; |
483 | 487 | ||
484 | static int dax_test(struct inode *inode, void *data) | 488 | static int dax_test(struct inode *inode, void *data) |
@@ -665,10 +669,6 @@ static int dax_fs_init(void) | |||
665 | if (!dax_cache) | 669 | if (!dax_cache) |
666 | return -ENOMEM; | 670 | return -ENOMEM; |
667 | 671 | ||
668 | rc = register_filesystem(&dax_fs_type); | ||
669 | if (rc) | ||
670 | goto err_register_fs; | ||
671 | |||
672 | dax_mnt = kern_mount(&dax_fs_type); | 672 | dax_mnt = kern_mount(&dax_fs_type); |
673 | if (IS_ERR(dax_mnt)) { | 673 | if (IS_ERR(dax_mnt)) { |
674 | rc = PTR_ERR(dax_mnt); | 674 | rc = PTR_ERR(dax_mnt); |
@@ -679,8 +679,6 @@ static int dax_fs_init(void) | |||
679 | return 0; | 679 | return 0; |
680 | 680 | ||
681 | err_mount: | 681 | err_mount: |
682 | unregister_filesystem(&dax_fs_type); | ||
683 | err_register_fs: | ||
684 | kmem_cache_destroy(dax_cache); | 682 | kmem_cache_destroy(dax_cache); |
685 | 683 | ||
686 | return rc; | 684 | return rc; |
@@ -689,7 +687,6 @@ static int dax_fs_init(void) | |||
689 | static void dax_fs_exit(void) | 687 | static void dax_fs_exit(void) |
690 | { | 688 | { |
691 | kern_unmount(dax_mnt); | 689 | kern_unmount(dax_mnt); |
692 | unregister_filesystem(&dax_fs_type); | ||
693 | kmem_cache_destroy(dax_cache); | 690 | kmem_cache_destroy(dax_cache); |
694 | } | 691 | } |
695 | 692 | ||
diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index dc4b2c521d79..f45bfb29ef96 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/reservation.h> | 24 | #include <linux/reservation.h> |
25 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
26 | #include <linux/mount.h> | 26 | #include <linux/mount.h> |
27 | #include <linux/pseudo_fs.h> | ||
27 | 28 | ||
28 | #include <uapi/linux/dma-buf.h> | 29 | #include <uapi/linux/dma-buf.h> |
29 | #include <uapi/linux/magic.h> | 30 | #include <uapi/linux/magic.h> |
@@ -59,16 +60,20 @@ static const struct dentry_operations dma_buf_dentry_ops = { | |||
59 | 60 | ||
60 | static struct vfsmount *dma_buf_mnt; | 61 | static struct vfsmount *dma_buf_mnt; |
61 | 62 | ||
62 | static struct dentry *dma_buf_fs_mount(struct file_system_type *fs_type, | 63 | static int dma_buf_fs_init_context(struct fs_context *fc) |
63 | int flags, const char *name, void *data) | ||
64 | { | 64 | { |
65 | return mount_pseudo(fs_type, "dmabuf:", NULL, &dma_buf_dentry_ops, | 65 | struct pseudo_fs_context *ctx; |
66 | DMA_BUF_MAGIC); | 66 | |
67 | ctx = init_pseudo(fc, DMA_BUF_MAGIC); | ||
68 | if (!ctx) | ||
69 | return -ENOMEM; | ||
70 | ctx->dops = &dma_buf_dentry_ops; | ||
71 | return 0; | ||
67 | } | 72 | } |
68 | 73 | ||
69 | static struct file_system_type dma_buf_fs_type = { | 74 | static struct file_system_type dma_buf_fs_type = { |
70 | .name = "dmabuf", | 75 | .name = "dmabuf", |
71 | .mount = dma_buf_fs_mount, | 76 | .init_fs_context = dma_buf_fs_init_context, |
72 | .kill_sb = kill_anon_super, | 77 | .kill_sb = kill_anon_super, |
73 | }; | 78 | }; |
74 | 79 | ||
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index fe0ce86c280f..9d00947ca447 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <linux/moduleparam.h> | 32 | #include <linux/moduleparam.h> |
33 | #include <linux/mount.h> | 33 | #include <linux/mount.h> |
34 | #include <linux/pseudo_fs.h> | ||
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | #include <linux/srcu.h> | 36 | #include <linux/srcu.h> |
36 | 37 | ||
@@ -535,28 +536,15 @@ EXPORT_SYMBOL(drm_dev_unplug); | |||
535 | static int drm_fs_cnt; | 536 | static int drm_fs_cnt; |
536 | static struct vfsmount *drm_fs_mnt; | 537 | static struct vfsmount *drm_fs_mnt; |
537 | 538 | ||
538 | static const struct dentry_operations drm_fs_dops = { | 539 | static int drm_fs_init_fs_context(struct fs_context *fc) |
539 | .d_dname = simple_dname, | ||
540 | }; | ||
541 | |||
542 | static const struct super_operations drm_fs_sops = { | ||
543 | .statfs = simple_statfs, | ||
544 | }; | ||
545 | |||
546 | static struct dentry *drm_fs_mount(struct file_system_type *fs_type, int flags, | ||
547 | const char *dev_name, void *data) | ||
548 | { | 540 | { |
549 | return mount_pseudo(fs_type, | 541 | return init_pseudo(fc, 0x010203ff) ? 0 : -ENOMEM; |
550 | "drm:", | ||
551 | &drm_fs_sops, | ||
552 | &drm_fs_dops, | ||
553 | 0x010203ff); | ||
554 | } | 542 | } |
555 | 543 | ||
556 | static struct file_system_type drm_fs_type = { | 544 | static struct file_system_type drm_fs_type = { |
557 | .name = "drm", | 545 | .name = "drm", |
558 | .owner = THIS_MODULE, | 546 | .owner = THIS_MODULE, |
559 | .mount = drm_fs_mount, | 547 | .init_fs_context = drm_fs_init_fs_context, |
560 | .kill_sb = kill_anon_super, | 548 | .kill_sb = kill_anon_super, |
561 | }; | 549 | }; |
562 | 550 | ||
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index ceb42d948412..41a569558a15 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/fs_context.h> | ||
37 | #include <linux/mount.h> | 38 | #include <linux/mount.h> |
38 | #include <linux/pagemap.h> | 39 | #include <linux/pagemap.h> |
39 | #include <linux/init.h> | 40 | #include <linux/init.h> |
@@ -506,7 +507,7 @@ bail: | |||
506 | * after device init. The direct add_cntr_files() call handles adding | 507 | * after device init. The direct add_cntr_files() call handles adding |
507 | * them from the init code, when the fs is already mounted. | 508 | * them from the init code, when the fs is already mounted. |
508 | */ | 509 | */ |
509 | static int qibfs_fill_super(struct super_block *sb, void *data, int silent) | 510 | static int qibfs_fill_super(struct super_block *sb, struct fs_context *fc) |
510 | { | 511 | { |
511 | struct qib_devdata *dd; | 512 | struct qib_devdata *dd; |
512 | unsigned long index; | 513 | unsigned long index; |
@@ -534,17 +535,24 @@ bail: | |||
534 | return ret; | 535 | return ret; |
535 | } | 536 | } |
536 | 537 | ||
537 | static struct dentry *qibfs_mount(struct file_system_type *fs_type, int flags, | 538 | static int qibfs_get_tree(struct fs_context *fc) |
538 | const char *dev_name, void *data) | ||
539 | { | 539 | { |
540 | struct dentry *ret; | 540 | int ret = get_tree_single(fc, qibfs_fill_super); |
541 | 541 | if (ret == 0) | |
542 | ret = mount_single(fs_type, flags, data, qibfs_fill_super); | 542 | qib_super = fc->root->d_sb; |
543 | if (!IS_ERR(ret)) | ||
544 | qib_super = ret->d_sb; | ||
545 | return ret; | 543 | return ret; |
546 | } | 544 | } |
547 | 545 | ||
546 | static const struct fs_context_operations qibfs_context_ops = { | ||
547 | .get_tree = qibfs_get_tree, | ||
548 | }; | ||
549 | |||
550 | static int qibfs_init_fs_context(struct fs_context *fc) | ||
551 | { | ||
552 | fc->ops = &qibfs_context_ops; | ||
553 | return 0; | ||
554 | } | ||
555 | |||
548 | static void qibfs_kill_super(struct super_block *s) | 556 | static void qibfs_kill_super(struct super_block *s) |
549 | { | 557 | { |
550 | kill_litter_super(s); | 558 | kill_litter_super(s); |
@@ -583,7 +591,7 @@ int qibfs_remove(struct qib_devdata *dd) | |||
583 | static struct file_system_type qibfs_fs_type = { | 591 | static struct file_system_type qibfs_fs_type = { |
584 | .owner = THIS_MODULE, | 592 | .owner = THIS_MODULE, |
585 | .name = "ipathfs", | 593 | .name = "ipathfs", |
586 | .mount = qibfs_mount, | 594 | .init_fs_context = qibfs_init_fs_context, |
587 | .kill_sb = qibfs_kill_super, | 595 | .kill_sb = qibfs_kill_super, |
588 | }; | 596 | }; |
589 | MODULE_ALIAS_FS("ipathfs"); | 597 | MODULE_ALIAS_FS("ipathfs"); |
diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c index a450694d5a62..b493de962153 100644 --- a/drivers/misc/cxl/api.c +++ b/drivers/misc/cxl/api.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <misc/cxl.h> | 9 | #include <misc/cxl.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/mount.h> | 11 | #include <linux/mount.h> |
12 | #include <linux/pseudo_fs.h> | ||
12 | #include <linux/sched/mm.h> | 13 | #include <linux/sched/mm.h> |
13 | #include <linux/mmu_context.h> | 14 | #include <linux/mmu_context.h> |
14 | 15 | ||
@@ -33,21 +34,15 @@ | |||
33 | static int cxl_fs_cnt; | 34 | static int cxl_fs_cnt; |
34 | static struct vfsmount *cxl_vfs_mount; | 35 | static struct vfsmount *cxl_vfs_mount; |
35 | 36 | ||
36 | static const struct dentry_operations cxl_fs_dops = { | 37 | static int cxl_fs_init_fs_context(struct fs_context *fc) |
37 | .d_dname = simple_dname, | ||
38 | }; | ||
39 | |||
40 | static struct dentry *cxl_fs_mount(struct file_system_type *fs_type, int flags, | ||
41 | const char *dev_name, void *data) | ||
42 | { | 38 | { |
43 | return mount_pseudo(fs_type, "cxl:", NULL, &cxl_fs_dops, | 39 | return init_pseudo(fc, CXL_PSEUDO_FS_MAGIC) ? 0 : -ENOMEM; |
44 | CXL_PSEUDO_FS_MAGIC); | ||
45 | } | 40 | } |
46 | 41 | ||
47 | static struct file_system_type cxl_fs_type = { | 42 | static struct file_system_type cxl_fs_type = { |
48 | .name = "cxl", | 43 | .name = "cxl", |
49 | .owner = THIS_MODULE, | 44 | .owner = THIS_MODULE, |
50 | .mount = cxl_fs_mount, | 45 | .init_fs_context = cxl_fs_init_fs_context, |
51 | .kill_sb = kill_anon_super, | 46 | .kill_sb = kill_anon_super, |
52 | }; | 47 | }; |
53 | 48 | ||
diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index 4989dcb2df14..35fec1bf1b3d 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c | |||
@@ -60,6 +60,7 @@ | |||
60 | */ | 60 | */ |
61 | 61 | ||
62 | #include <linux/fs.h> | 62 | #include <linux/fs.h> |
63 | #include <linux/fs_context.h> | ||
63 | #include <linux/pagemap.h> | 64 | #include <linux/pagemap.h> |
64 | #include <linux/slab.h> | 65 | #include <linux/slab.h> |
65 | #include <linux/uaccess.h> | 66 | #include <linux/uaccess.h> |
@@ -74,13 +75,21 @@ static LIST_HEAD(service_processors); | |||
74 | 75 | ||
75 | static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode); | 76 | static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode); |
76 | static void ibmasmfs_create_files (struct super_block *sb); | 77 | static void ibmasmfs_create_files (struct super_block *sb); |
77 | static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent); | 78 | static int ibmasmfs_fill_super(struct super_block *sb, struct fs_context *fc); |
78 | 79 | ||
80 | static int ibmasmfs_get_tree(struct fs_context *fc) | ||
81 | { | ||
82 | return get_tree_single(fc, ibmasmfs_fill_super); | ||
83 | } | ||
79 | 84 | ||
80 | static struct dentry *ibmasmfs_mount(struct file_system_type *fst, | 85 | static const struct fs_context_operations ibmasmfs_context_ops = { |
81 | int flags, const char *name, void *data) | 86 | .get_tree = ibmasmfs_get_tree, |
87 | }; | ||
88 | |||
89 | static int ibmasmfs_init_fs_context(struct fs_context *fc) | ||
82 | { | 90 | { |
83 | return mount_single(fst, flags, data, ibmasmfs_fill_super); | 91 | fc->ops = &ibmasmfs_context_ops; |
92 | return 0; | ||
84 | } | 93 | } |
85 | 94 | ||
86 | static const struct super_operations ibmasmfs_s_ops = { | 95 | static const struct super_operations ibmasmfs_s_ops = { |
@@ -93,12 +102,12 @@ static const struct file_operations *ibmasmfs_dir_ops = &simple_dir_operations; | |||
93 | static struct file_system_type ibmasmfs_type = { | 102 | static struct file_system_type ibmasmfs_type = { |
94 | .owner = THIS_MODULE, | 103 | .owner = THIS_MODULE, |
95 | .name = "ibmasmfs", | 104 | .name = "ibmasmfs", |
96 | .mount = ibmasmfs_mount, | 105 | .init_fs_context = ibmasmfs_init_fs_context, |
97 | .kill_sb = kill_litter_super, | 106 | .kill_sb = kill_litter_super, |
98 | }; | 107 | }; |
99 | MODULE_ALIAS_FS("ibmasmfs"); | 108 | MODULE_ALIAS_FS("ibmasmfs"); |
100 | 109 | ||
101 | static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent) | 110 | static int ibmasmfs_fill_super(struct super_block *sb, struct fs_context *fc) |
102 | { | 111 | { |
103 | struct inode *root; | 112 | struct inode *root; |
104 | 113 | ||
diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 97b58e7ad901..8840299420e0 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | #include <linux/mount.h> | 31 | #include <linux/mount.h> |
32 | #include <linux/pseudo_fs.h> | ||
32 | #include <linux/balloon_compaction.h> | 33 | #include <linux/balloon_compaction.h> |
33 | #include <linux/vmw_vmci_defs.h> | 34 | #include <linux/vmw_vmci_defs.h> |
34 | #include <linux/vmw_vmci_api.h> | 35 | #include <linux/vmw_vmci_api.h> |
@@ -1728,22 +1729,15 @@ static inline void vmballoon_debugfs_exit(struct vmballoon *b) | |||
1728 | 1729 | ||
1729 | #ifdef CONFIG_BALLOON_COMPACTION | 1730 | #ifdef CONFIG_BALLOON_COMPACTION |
1730 | 1731 | ||
1731 | static struct dentry *vmballoon_mount(struct file_system_type *fs_type, | 1732 | static int vmballoon_init_fs_context(struct fs_context *fc) |
1732 | int flags, const char *dev_name, | ||
1733 | void *data) | ||
1734 | { | 1733 | { |
1735 | static const struct dentry_operations ops = { | 1734 | return init_pseudo(fc, BALLOON_VMW_MAGIC) ? 0 : -ENOMEM; |
1736 | .d_dname = simple_dname, | ||
1737 | }; | ||
1738 | |||
1739 | return mount_pseudo(fs_type, "balloon-vmware:", NULL, &ops, | ||
1740 | BALLOON_VMW_MAGIC); | ||
1741 | } | 1735 | } |
1742 | 1736 | ||
1743 | static struct file_system_type vmballoon_fs = { | 1737 | static struct file_system_type vmballoon_fs = { |
1744 | .name = "balloon-vmware", | 1738 | .name = "balloon-vmware", |
1745 | .mount = vmballoon_mount, | 1739 | .init_fs_context = vmballoon_init_fs_context, |
1746 | .kill_sb = kill_anon_super, | 1740 | .kill_sb = kill_anon_super, |
1747 | }; | 1741 | }; |
1748 | 1742 | ||
1749 | static struct vfsmount *vmballoon_mnt; | 1743 | static struct vfsmount *vmballoon_mnt; |
diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index 4ea08979312c..0875f2f122b3 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/oprofile.h> | 15 | #include <linux/oprofile.h> |
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/fs_context.h> | ||
17 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
18 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
19 | 20 | ||
@@ -238,7 +239,7 @@ struct dentry *oprofilefs_mkdir(struct dentry *parent, char const *name) | |||
238 | } | 239 | } |
239 | 240 | ||
240 | 241 | ||
241 | static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent) | 242 | static int oprofilefs_fill_super(struct super_block *sb, struct fs_context *fc) |
242 | { | 243 | { |
243 | struct inode *root_inode; | 244 | struct inode *root_inode; |
244 | 245 | ||
@@ -263,18 +264,25 @@ static int oprofilefs_fill_super(struct super_block *sb, void *data, int silent) | |||
263 | return 0; | 264 | return 0; |
264 | } | 265 | } |
265 | 266 | ||
266 | 267 | static int oprofilefs_get_tree(struct fs_context *fc) | |
267 | static struct dentry *oprofilefs_mount(struct file_system_type *fs_type, | ||
268 | int flags, const char *dev_name, void *data) | ||
269 | { | 268 | { |
270 | return mount_single(fs_type, flags, data, oprofilefs_fill_super); | 269 | return get_tree_single(fc, oprofilefs_fill_super); |
271 | } | 270 | } |
272 | 271 | ||
272 | static const struct fs_context_operations oprofilefs_context_ops = { | ||
273 | .get_tree = oprofilefs_get_tree, | ||
274 | }; | ||
275 | |||
276 | static int oprofilefs_init_fs_context(struct fs_context *fc) | ||
277 | { | ||
278 | fc->ops = &oprofilefs_context_ops; | ||
279 | return 0; | ||
280 | } | ||
273 | 281 | ||
274 | static struct file_system_type oprofilefs_type = { | 282 | static struct file_system_type oprofilefs_type = { |
275 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, |
276 | .name = "oprofilefs", | 284 | .name = "oprofilefs", |
277 | .mount = oprofilefs_mount, | 285 | .init_fs_context = oprofilefs_init_fs_context, |
278 | .kill_sb = kill_litter_super, | 286 | .kill_sb = kill_litter_super, |
279 | }; | 287 | }; |
280 | MODULE_ALIAS_FS("oprofilefs"); | 288 | MODULE_ALIAS_FS("oprofilefs"); |
diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c index 96740c6fcd92..7018cd802569 100644 --- a/drivers/scsi/cxlflash/ocxl_hw.c +++ b/drivers/scsi/cxlflash/ocxl_hw.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/idr.h> | 12 | #include <linux/idr.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/mount.h> | 14 | #include <linux/mount.h> |
15 | #include <linux/pseudo_fs.h> | ||
15 | #include <linux/poll.h> | 16 | #include <linux/poll.h> |
16 | #include <linux/sched/signal.h> | 17 | #include <linux/sched/signal.h> |
17 | 18 | ||
@@ -31,31 +32,15 @@ | |||
31 | static int ocxlflash_fs_cnt; | 32 | static int ocxlflash_fs_cnt; |
32 | static struct vfsmount *ocxlflash_vfs_mount; | 33 | static struct vfsmount *ocxlflash_vfs_mount; |
33 | 34 | ||
34 | static const struct dentry_operations ocxlflash_fs_dops = { | 35 | static int ocxlflash_fs_init_fs_context(struct fs_context *fc) |
35 | .d_dname = simple_dname, | ||
36 | }; | ||
37 | |||
38 | /* | ||
39 | * ocxlflash_fs_mount() - mount the pseudo-filesystem | ||
40 | * @fs_type: File system type. | ||
41 | * @flags: Flags for the filesystem. | ||
42 | * @dev_name: Device name associated with the filesystem. | ||
43 | * @data: Data pointer. | ||
44 | * | ||
45 | * Return: pointer to the directory entry structure | ||
46 | */ | ||
47 | static struct dentry *ocxlflash_fs_mount(struct file_system_type *fs_type, | ||
48 | int flags, const char *dev_name, | ||
49 | void *data) | ||
50 | { | 36 | { |
51 | return mount_pseudo(fs_type, "ocxlflash:", NULL, &ocxlflash_fs_dops, | 37 | return init_pseudo(fc, OCXLFLASH_FS_MAGIC) ? 0 : -ENOMEM; |
52 | OCXLFLASH_FS_MAGIC); | ||
53 | } | 38 | } |
54 | 39 | ||
55 | static struct file_system_type ocxlflash_fs_type = { | 40 | static struct file_system_type ocxlflash_fs_type = { |
56 | .name = "ocxlflash", | 41 | .name = "ocxlflash", |
57 | .owner = THIS_MODULE, | 42 | .owner = THIS_MODULE, |
58 | .mount = ocxlflash_fs_mount, | 43 | .init_fs_context = ocxlflash_fs_init_fs_context, |
59 | .kill_sb = kill_anon_super, | 44 | .kill_sb = kill_anon_super, |
60 | }; | 45 | }; |
61 | 46 | ||
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 249277d0e53f..b47938dff1a2 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/fs_context.h> | ||
15 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
16 | #include <linux/uts.h> | 17 | #include <linux/uts.h> |
17 | #include <linux/wait.h> | 18 | #include <linux/wait.h> |
@@ -1990,7 +1991,7 @@ static const struct super_operations gadget_fs_operations = { | |||
1990 | }; | 1991 | }; |
1991 | 1992 | ||
1992 | static int | 1993 | static int |
1993 | gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) | 1994 | gadgetfs_fill_super (struct super_block *sb, struct fs_context *fc) |
1994 | { | 1995 | { |
1995 | struct inode *inode; | 1996 | struct inode *inode; |
1996 | struct dev_data *dev; | 1997 | struct dev_data *dev; |
@@ -2044,11 +2045,19 @@ Enomem: | |||
2044 | } | 2045 | } |
2045 | 2046 | ||
2046 | /* "mount -t gadgetfs path /dev/gadget" ends up here */ | 2047 | /* "mount -t gadgetfs path /dev/gadget" ends up here */ |
2047 | static struct dentry * | 2048 | static int gadgetfs_get_tree(struct fs_context *fc) |
2048 | gadgetfs_mount (struct file_system_type *t, int flags, | ||
2049 | const char *path, void *opts) | ||
2050 | { | 2049 | { |
2051 | return mount_single (t, flags, opts, gadgetfs_fill_super); | 2050 | return get_tree_single(fc, gadgetfs_fill_super); |
2051 | } | ||
2052 | |||
2053 | static const struct fs_context_operations gadgetfs_context_ops = { | ||
2054 | .get_tree = gadgetfs_get_tree, | ||
2055 | }; | ||
2056 | |||
2057 | static int gadgetfs_init_fs_context(struct fs_context *fc) | ||
2058 | { | ||
2059 | fc->ops = &gadgetfs_context_ops; | ||
2060 | return 0; | ||
2052 | } | 2061 | } |
2053 | 2062 | ||
2054 | static void | 2063 | static void |
@@ -2068,7 +2077,7 @@ gadgetfs_kill_sb (struct super_block *sb) | |||
2068 | static struct file_system_type gadgetfs_type = { | 2077 | static struct file_system_type gadgetfs_type = { |
2069 | .owner = THIS_MODULE, | 2078 | .owner = THIS_MODULE, |
2070 | .name = shortname, | 2079 | .name = shortname, |
2071 | .mount = gadgetfs_mount, | 2080 | .init_fs_context = gadgetfs_init_fs_context, |
2072 | .kill_sb = gadgetfs_kill_sb, | 2081 | .kill_sb = gadgetfs_kill_sb, |
2073 | }; | 2082 | }; |
2074 | MODULE_ALIAS_FS("gadgetfs"); | 2083 | MODULE_ALIAS_FS("gadgetfs"); |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 44339fc87cc7..226fbb995fb0 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
20 | #include <linux/magic.h> | 20 | #include <linux/magic.h> |
21 | #include <linux/pseudo_fs.h> | ||
21 | 22 | ||
22 | /* | 23 | /* |
23 | * Balloon device works in 4K page units. So each page is pointed to by | 24 | * Balloon device works in 4K page units. So each page is pointed to by |
@@ -745,20 +746,14 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info, | |||
745 | return MIGRATEPAGE_SUCCESS; | 746 | return MIGRATEPAGE_SUCCESS; |
746 | } | 747 | } |
747 | 748 | ||
748 | static struct dentry *balloon_mount(struct file_system_type *fs_type, | 749 | static int balloon_init_fs_context(struct fs_context *fc) |
749 | int flags, const char *dev_name, void *data) | ||
750 | { | 750 | { |
751 | static const struct dentry_operations ops = { | 751 | return init_pseudo(fc, BALLOON_KVM_MAGIC) ? 0 : -ENOMEM; |
752 | .d_dname = simple_dname, | ||
753 | }; | ||
754 | |||
755 | return mount_pseudo(fs_type, "balloon-kvm:", NULL, &ops, | ||
756 | BALLOON_KVM_MAGIC); | ||
757 | } | 752 | } |
758 | 753 | ||
759 | static struct file_system_type balloon_fs = { | 754 | static struct file_system_type balloon_fs = { |
760 | .name = "balloon-kvm", | 755 | .name = "balloon-kvm", |
761 | .mount = balloon_mount, | 756 | .init_fs_context = balloon_init_fs_context, |
762 | .kill_sb = kill_anon_super, | 757 | .kill_sb = kill_anon_super, |
763 | }; | 758 | }; |
764 | 759 | ||
diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c index 20c1448f1ce7..d7d64235010d 100644 --- a/drivers/xen/xenfs/super.c +++ b/drivers/xen/xenfs/super.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/fs_context.h> | ||
17 | #include <linux/magic.h> | 18 | #include <linux/magic.h> |
18 | 19 | ||
19 | #include <xen/xen.h> | 20 | #include <xen/xen.h> |
@@ -43,7 +44,7 @@ static const struct file_operations capabilities_file_ops = { | |||
43 | .llseek = default_llseek, | 44 | .llseek = default_llseek, |
44 | }; | 45 | }; |
45 | 46 | ||
46 | static int xenfs_fill_super(struct super_block *sb, void *data, int silent) | 47 | static int xenfs_fill_super(struct super_block *sb, struct fs_context *fc) |
47 | { | 48 | { |
48 | static const struct tree_descr xenfs_files[] = { | 49 | static const struct tree_descr xenfs_files[] = { |
49 | [2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR }, | 50 | [2] = { "xenbus", &xen_xenbus_fops, S_IRUSR|S_IWUSR }, |
@@ -68,17 +69,25 @@ static int xenfs_fill_super(struct super_block *sb, void *data, int silent) | |||
68 | xen_initial_domain() ? xenfs_init_files : xenfs_files); | 69 | xen_initial_domain() ? xenfs_init_files : xenfs_files); |
69 | } | 70 | } |
70 | 71 | ||
71 | static struct dentry *xenfs_mount(struct file_system_type *fs_type, | 72 | static int xenfs_get_tree(struct fs_context *fc) |
72 | int flags, const char *dev_name, | ||
73 | void *data) | ||
74 | { | 73 | { |
75 | return mount_single(fs_type, flags, data, xenfs_fill_super); | 74 | return get_tree_single(fc, xenfs_fill_super); |
75 | } | ||
76 | |||
77 | static const struct fs_context_operations xenfs_context_ops = { | ||
78 | .get_tree = xenfs_get_tree, | ||
79 | }; | ||
80 | |||
81 | static int xenfs_init_fs_context(struct fs_context *fc) | ||
82 | { | ||
83 | fc->ops = &xenfs_context_ops; | ||
84 | return 0; | ||
76 | } | 85 | } |
77 | 86 | ||
78 | static struct file_system_type xenfs_type = { | 87 | static struct file_system_type xenfs_type = { |
79 | .owner = THIS_MODULE, | 88 | .owner = THIS_MODULE, |
80 | .name = "xenfs", | 89 | .name = "xenfs", |
81 | .mount = xenfs_mount, | 90 | .init_fs_context = xenfs_init_fs_context, |
82 | .kill_sb = kill_litter_super, | 91 | .kill_sb = kill_litter_super, |
83 | }; | 92 | }; |
84 | MODULE_ALIAS_FS("xenfs"); | 93 | MODULE_ALIAS_FS("xenfs"); |
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/ramfs.h> | 42 | #include <linux/ramfs.h> |
43 | #include <linux/percpu-refcount.h> | 43 | #include <linux/percpu-refcount.h> |
44 | #include <linux/mount.h> | 44 | #include <linux/mount.h> |
45 | #include <linux/pseudo_fs.h> | ||
45 | 46 | ||
46 | #include <asm/kmap_types.h> | 47 | #include <asm/kmap_types.h> |
47 | #include <linux/uaccess.h> | 48 | #include <linux/uaccess.h> |
@@ -249,15 +250,12 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages) | |||
249 | return file; | 250 | return file; |
250 | } | 251 | } |
251 | 252 | ||
252 | static struct dentry *aio_mount(struct file_system_type *fs_type, | 253 | static int aio_init_fs_context(struct fs_context *fc) |
253 | int flags, const char *dev_name, void *data) | ||
254 | { | 254 | { |
255 | struct dentry *root = mount_pseudo(fs_type, "aio:", NULL, NULL, | 255 | if (!init_pseudo(fc, AIO_RING_MAGIC)) |
256 | AIO_RING_MAGIC); | 256 | return -ENOMEM; |
257 | 257 | fc->s_iflags |= SB_I_NOEXEC; | |
258 | if (!IS_ERR(root)) | 258 | return 0; |
259 | root->d_sb->s_iflags |= SB_I_NOEXEC; | ||
260 | return root; | ||
261 | } | 259 | } |
262 | 260 | ||
263 | /* aio_setup | 261 | /* aio_setup |
@@ -268,7 +266,7 @@ static int __init aio_setup(void) | |||
268 | { | 266 | { |
269 | static struct file_system_type aio_fs = { | 267 | static struct file_system_type aio_fs = { |
270 | .name = "aio", | 268 | .name = "aio", |
271 | .mount = aio_mount, | 269 | .init_fs_context = aio_init_fs_context, |
272 | .kill_sb = kill_anon_super, | 270 | .kill_sb = kill_anon_super, |
273 | }; | 271 | }; |
274 | aio_mnt = kern_mount(&aio_fs); | 272 | aio_mnt = kern_mount(&aio_fs); |
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index c2b8663f5b00..89714308c25b 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/magic.h> | 21 | #include <linux/magic.h> |
22 | #include <linux/anon_inodes.h> | 22 | #include <linux/anon_inodes.h> |
23 | #include <linux/pseudo_fs.h> | ||
23 | 24 | ||
24 | #include <linux/uaccess.h> | 25 | #include <linux/uaccess.h> |
25 | 26 | ||
@@ -39,16 +40,18 @@ static const struct dentry_operations anon_inodefs_dentry_operations = { | |||
39 | .d_dname = anon_inodefs_dname, | 40 | .d_dname = anon_inodefs_dname, |
40 | }; | 41 | }; |
41 | 42 | ||
42 | static struct dentry *anon_inodefs_mount(struct file_system_type *fs_type, | 43 | static int anon_inodefs_init_fs_context(struct fs_context *fc) |
43 | int flags, const char *dev_name, void *data) | ||
44 | { | 44 | { |
45 | return mount_pseudo(fs_type, "anon_inode:", NULL, | 45 | struct pseudo_fs_context *ctx = init_pseudo(fc, ANON_INODE_FS_MAGIC); |
46 | &anon_inodefs_dentry_operations, ANON_INODE_FS_MAGIC); | 46 | if (!ctx) |
47 | return -ENOMEM; | ||
48 | ctx->dops = &anon_inodefs_dentry_operations; | ||
49 | return 0; | ||
47 | } | 50 | } |
48 | 51 | ||
49 | static struct file_system_type anon_inode_fs_type = { | 52 | static struct file_system_type anon_inode_fs_type = { |
50 | .name = "anon_inodefs", | 53 | .name = "anon_inodefs", |
51 | .mount = anon_inodefs_mount, | 54 | .init_fs_context = anon_inodefs_init_fs_context, |
52 | .kill_sb = kill_anon_super, | 55 | .kill_sb = kill_anon_super, |
53 | }; | 56 | }; |
54 | 57 | ||
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index b8e145552ec7..cdb45829354d 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
24 | #include <linux/namei.h> | 24 | #include <linux/namei.h> |
25 | #include <linux/mount.h> | 25 | #include <linux/mount.h> |
26 | #include <linux/fs_context.h> | ||
26 | #include <linux/syscalls.h> | 27 | #include <linux/syscalls.h> |
27 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
28 | #include <linux/uaccess.h> | 29 | #include <linux/uaccess.h> |
@@ -821,7 +822,7 @@ static const struct super_operations s_ops = { | |||
821 | .evict_inode = bm_evict_inode, | 822 | .evict_inode = bm_evict_inode, |
822 | }; | 823 | }; |
823 | 824 | ||
824 | static int bm_fill_super(struct super_block *sb, void *data, int silent) | 825 | static int bm_fill_super(struct super_block *sb, struct fs_context *fc) |
825 | { | 826 | { |
826 | int err; | 827 | int err; |
827 | static const struct tree_descr bm_files[] = { | 828 | static const struct tree_descr bm_files[] = { |
@@ -836,10 +837,19 @@ static int bm_fill_super(struct super_block *sb, void *data, int silent) | |||
836 | return err; | 837 | return err; |
837 | } | 838 | } |
838 | 839 | ||
839 | static struct dentry *bm_mount(struct file_system_type *fs_type, | 840 | static int bm_get_tree(struct fs_context *fc) |
840 | int flags, const char *dev_name, void *data) | ||
841 | { | 841 | { |
842 | return mount_single(fs_type, flags, data, bm_fill_super); | 842 | return get_tree_single(fc, bm_fill_super); |
843 | } | ||
844 | |||
845 | static const struct fs_context_operations bm_context_ops = { | ||
846 | .get_tree = bm_get_tree, | ||
847 | }; | ||
848 | |||
849 | static int bm_init_fs_context(struct fs_context *fc) | ||
850 | { | ||
851 | fc->ops = &bm_context_ops; | ||
852 | return 0; | ||
843 | } | 853 | } |
844 | 854 | ||
845 | static struct linux_binfmt misc_format = { | 855 | static struct linux_binfmt misc_format = { |
@@ -850,7 +860,7 @@ static struct linux_binfmt misc_format = { | |||
850 | static struct file_system_type bm_fs_type = { | 860 | static struct file_system_type bm_fs_type = { |
851 | .owner = THIS_MODULE, | 861 | .owner = THIS_MODULE, |
852 | .name = "binfmt_misc", | 862 | .name = "binfmt_misc", |
853 | .mount = bm_mount, | 863 | .init_fs_context = bm_init_fs_context, |
854 | .kill_sb = kill_litter_super, | 864 | .kill_sb = kill_litter_super, |
855 | }; | 865 | }; |
856 | MODULE_ALIAS_FS("binfmt_misc"); | 866 | MODULE_ALIAS_FS("binfmt_misc"); |
diff --git a/fs/block_dev.c b/fs/block_dev.c index f00b569a9f89..4707dfff991b 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/writeback.h> | 26 | #include <linux/writeback.h> |
27 | #include <linux/mpage.h> | 27 | #include <linux/mpage.h> |
28 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
29 | #include <linux/pseudo_fs.h> | ||
29 | #include <linux/uio.h> | 30 | #include <linux/uio.h> |
30 | #include <linux/namei.h> | 31 | #include <linux/namei.h> |
31 | #include <linux/log2.h> | 32 | #include <linux/log2.h> |
@@ -821,19 +822,19 @@ static const struct super_operations bdev_sops = { | |||
821 | .evict_inode = bdev_evict_inode, | 822 | .evict_inode = bdev_evict_inode, |
822 | }; | 823 | }; |
823 | 824 | ||
824 | static struct dentry *bd_mount(struct file_system_type *fs_type, | 825 | static int bd_init_fs_context(struct fs_context *fc) |
825 | int flags, const char *dev_name, void *data) | ||
826 | { | 826 | { |
827 | struct dentry *dent; | 827 | struct pseudo_fs_context *ctx = init_pseudo(fc, BDEVFS_MAGIC); |
828 | dent = mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, BDEVFS_MAGIC); | 828 | if (!ctx) |
829 | if (!IS_ERR(dent)) | 829 | return -ENOMEM; |
830 | dent->d_sb->s_iflags |= SB_I_CGROUPWB; | 830 | fc->s_iflags |= SB_I_CGROUPWB; |
831 | return dent; | 831 | ctx->ops = &bdev_sops; |
832 | return 0; | ||
832 | } | 833 | } |
833 | 834 | ||
834 | static struct file_system_type bd_type = { | 835 | static struct file_system_type bd_type = { |
835 | .name = "bdev", | 836 | .name = "bdev", |
836 | .mount = bd_mount, | 837 | .init_fs_context = bd_init_fs_context, |
837 | .kill_sb = kill_anon_super, | 838 | .kill_sb = kill_anon_super, |
838 | }; | 839 | }; |
839 | 840 | ||
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c index 9238fd4f1734..1e3ba4949399 100644 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <linux/fs.h> | 6 | #include <linux/fs.h> |
7 | #include <linux/mount.h> | 7 | #include <linux/mount.h> |
8 | #include <linux/pseudo_fs.h> | ||
8 | #include <linux/magic.h> | 9 | #include <linux/magic.h> |
9 | #include "btrfs-tests.h" | 10 | #include "btrfs-tests.h" |
10 | #include "../ctree.h" | 11 | #include "../ctree.h" |
@@ -32,17 +33,19 @@ static const struct super_operations btrfs_test_super_ops = { | |||
32 | .destroy_inode = btrfs_test_destroy_inode, | 33 | .destroy_inode = btrfs_test_destroy_inode, |
33 | }; | 34 | }; |
34 | 35 | ||
35 | static struct dentry *btrfs_test_mount(struct file_system_type *fs_type, | 36 | |
36 | int flags, const char *dev_name, | 37 | static int btrfs_test_init_fs_context(struct fs_context *fc) |
37 | void *data) | ||
38 | { | 38 | { |
39 | return mount_pseudo(fs_type, "btrfs_test:", &btrfs_test_super_ops, | 39 | struct pseudo_fs_context *ctx = init_pseudo(fc, BTRFS_TEST_MAGIC); |
40 | NULL, BTRFS_TEST_MAGIC); | 40 | if (!ctx) |
41 | return -ENOMEM; | ||
42 | ctx->ops = &btrfs_test_super_ops; | ||
43 | return 0; | ||
41 | } | 44 | } |
42 | 45 | ||
43 | static struct file_system_type test_type = { | 46 | static struct file_system_type test_type = { |
44 | .name = "btrfs_test_fs", | 47 | .name = "btrfs_test_fs", |
45 | .mount = btrfs_test_mount, | 48 | .init_fs_context = btrfs_test_init_fs_context, |
46 | .kill_sb = kill_anon_super, | 49 | .kill_sb = kill_anon_super, |
47 | }; | 50 | }; |
48 | 51 | ||
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 791304fdde9d..55438dd58189 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/mount.h> | 15 | #include <linux/mount.h> |
16 | #include <linux/fs_context.h> | ||
16 | #include <linux/pagemap.h> | 17 | #include <linux/pagemap.h> |
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -52,7 +53,7 @@ static struct configfs_dirent configfs_root = { | |||
52 | .s_iattr = NULL, | 53 | .s_iattr = NULL, |
53 | }; | 54 | }; |
54 | 55 | ||
55 | static int configfs_fill_super(struct super_block *sb, void *data, int silent) | 56 | static int configfs_fill_super(struct super_block *sb, struct fs_context *fc) |
56 | { | 57 | { |
57 | struct inode *inode; | 58 | struct inode *inode; |
58 | struct dentry *root; | 59 | struct dentry *root; |
@@ -88,16 +89,25 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent) | |||
88 | return 0; | 89 | return 0; |
89 | } | 90 | } |
90 | 91 | ||
91 | static struct dentry *configfs_do_mount(struct file_system_type *fs_type, | 92 | static int configfs_get_tree(struct fs_context *fc) |
92 | int flags, const char *dev_name, void *data) | ||
93 | { | 93 | { |
94 | return mount_single(fs_type, flags, data, configfs_fill_super); | 94 | return get_tree_single(fc, configfs_fill_super); |
95 | } | ||
96 | |||
97 | static const struct fs_context_operations configfs_context_ops = { | ||
98 | .get_tree = configfs_get_tree, | ||
99 | }; | ||
100 | |||
101 | static int configfs_init_fs_context(struct fs_context *fc) | ||
102 | { | ||
103 | fc->ops = &configfs_context_ops; | ||
104 | return 0; | ||
95 | } | 105 | } |
96 | 106 | ||
97 | static struct file_system_type configfs_fs_type = { | 107 | static struct file_system_type configfs_fs_type = { |
98 | .owner = THIS_MODULE, | 108 | .owner = THIS_MODULE, |
99 | .name = "configfs", | 109 | .name = "configfs", |
100 | .mount = configfs_do_mount, | 110 | .init_fs_context = configfs_init_fs_context, |
101 | .kill_sb = kill_litter_super, | 111 | .kill_sb = kill_litter_super, |
102 | }; | 112 | }; |
103 | MODULE_ALIAS_FS("configfs"); | 113 | MODULE_ALIAS_FS("configfs"); |
diff --git a/fs/d_path.c b/fs/d_path.c index e8fce6b1174f..a7d0a96b35ce 100644 --- a/fs/d_path.c +++ b/fs/d_path.c | |||
@@ -316,7 +316,6 @@ char *simple_dname(struct dentry *dentry, char *buffer, int buflen) | |||
316 | end = ERR_PTR(-ENAMETOOLONG); | 316 | end = ERR_PTR(-ENAMETOOLONG); |
317 | return end; | 317 | return end; |
318 | } | 318 | } |
319 | EXPORT_SYMBOL(simple_dname); | ||
320 | 319 | ||
321 | /* | 320 | /* |
322 | * Write full pathname from the root of the filesystem into the buffer. | 321 | * Write full pathname from the root of the filesystem into the buffer. |
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 5bc3c4a4c563..fa4f6447ddad 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/ctype.h> | 7 | #include <linux/ctype.h> |
8 | #include <linux/efi.h> | 8 | #include <linux/efi.h> |
9 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
10 | #include <linux/fs_context.h> | ||
10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
11 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
12 | #include <linux/ucs2_string.h> | 13 | #include <linux/ucs2_string.h> |
@@ -28,8 +29,6 @@ static const struct super_operations efivarfs_ops = { | |||
28 | .evict_inode = efivarfs_evict_inode, | 29 | .evict_inode = efivarfs_evict_inode, |
29 | }; | 30 | }; |
30 | 31 | ||
31 | static struct super_block *efivarfs_sb; | ||
32 | |||
33 | /* | 32 | /* |
34 | * Compare two efivarfs file names. | 33 | * Compare two efivarfs file names. |
35 | * | 34 | * |
@@ -188,14 +187,12 @@ static int efivarfs_destroy(struct efivar_entry *entry, void *data) | |||
188 | return 0; | 187 | return 0; |
189 | } | 188 | } |
190 | 189 | ||
191 | static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) | 190 | static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc) |
192 | { | 191 | { |
193 | struct inode *inode = NULL; | 192 | struct inode *inode = NULL; |
194 | struct dentry *root; | 193 | struct dentry *root; |
195 | int err; | 194 | int err; |
196 | 195 | ||
197 | efivarfs_sb = sb; | ||
198 | |||
199 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 196 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
200 | sb->s_blocksize = PAGE_SIZE; | 197 | sb->s_blocksize = PAGE_SIZE; |
201 | sb->s_blocksize_bits = PAGE_SHIFT; | 198 | sb->s_blocksize_bits = PAGE_SHIFT; |
@@ -223,16 +220,24 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) | |||
223 | return err; | 220 | return err; |
224 | } | 221 | } |
225 | 222 | ||
226 | static struct dentry *efivarfs_mount(struct file_system_type *fs_type, | 223 | static int efivarfs_get_tree(struct fs_context *fc) |
227 | int flags, const char *dev_name, void *data) | 224 | { |
225 | return get_tree_single(fc, efivarfs_fill_super); | ||
226 | } | ||
227 | |||
228 | static const struct fs_context_operations efivarfs_context_ops = { | ||
229 | .get_tree = efivarfs_get_tree, | ||
230 | }; | ||
231 | |||
232 | static int efivarfs_init_fs_context(struct fs_context *fc) | ||
228 | { | 233 | { |
229 | return mount_single(fs_type, flags, data, efivarfs_fill_super); | 234 | fc->ops = &efivarfs_context_ops; |
235 | return 0; | ||
230 | } | 236 | } |
231 | 237 | ||
232 | static void efivarfs_kill_sb(struct super_block *sb) | 238 | static void efivarfs_kill_sb(struct super_block *sb) |
233 | { | 239 | { |
234 | kill_litter_super(sb); | 240 | kill_litter_super(sb); |
235 | efivarfs_sb = NULL; | ||
236 | 241 | ||
237 | /* Remove all entries and destroy */ | 242 | /* Remove all entries and destroy */ |
238 | __efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL, NULL); | 243 | __efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL, NULL); |
@@ -241,7 +246,7 @@ static void efivarfs_kill_sb(struct super_block *sb) | |||
241 | static struct file_system_type efivarfs_type = { | 246 | static struct file_system_type efivarfs_type = { |
242 | .owner = THIS_MODULE, | 247 | .owner = THIS_MODULE, |
243 | .name = "efivarfs", | 248 | .name = "efivarfs", |
244 | .mount = efivarfs_mount, | 249 | .init_fs_context = efivarfs_init_fs_context, |
245 | .kill_sb = efivarfs_kill_sb, | 250 | .kill_sb = efivarfs_kill_sb, |
246 | }; | 251 | }; |
247 | 252 | ||
diff --git a/fs/fs_parser.c b/fs/fs_parser.c index 0d388faa25d1..460ea4206fa2 100644 --- a/fs/fs_parser.c +++ b/fs/fs_parser.c | |||
@@ -264,6 +264,7 @@ int fs_lookup_param(struct fs_context *fc, | |||
264 | return invalf(fc, "%s: not usable as path", param->key); | 264 | return invalf(fc, "%s: not usable as path", param->key); |
265 | } | 265 | } |
266 | 266 | ||
267 | f->refcnt++; /* filename_lookup() drops our ref. */ | ||
267 | ret = filename_lookup(param->dirfd, f, flags, _path, NULL); | 268 | ret = filename_lookup(param->dirfd, f, flags, _path, NULL); |
268 | if (ret < 0) { | 269 | if (ret < 0) { |
269 | errorf(fc, "%s: Lookup failure for '%s'", param->key, f->name); | 270 | errorf(fc, "%s: Lookup failure for '%s'", param->key, f->name); |
diff --git a/fs/fsopen.c b/fs/fsopen.c index a8bf83ce8d4e..043ffa8dc263 100644 --- a/fs/fsopen.c +++ b/fs/fsopen.c | |||
@@ -226,6 +226,8 @@ static int vfs_fsconfig_locked(struct fs_context *fc, int cmd, | |||
226 | case FSCONFIG_CMD_CREATE: | 226 | case FSCONFIG_CMD_CREATE: |
227 | if (fc->phase != FS_CONTEXT_CREATE_PARAMS) | 227 | if (fc->phase != FS_CONTEXT_CREATE_PARAMS) |
228 | return -EBUSY; | 228 | return -EBUSY; |
229 | if (!mount_capable(fc)) | ||
230 | return -EPERM; | ||
229 | fc->phase = FS_CONTEXT_CREATING; | 231 | fc->phase = FS_CONTEXT_CREATING; |
230 | ret = vfs_get_tree(fc); | 232 | ret = vfs_get_tree(fc); |
231 | if (ret) | 233 | if (ret) |
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 14ce1e47f980..c23f6f243ad4 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c | |||
@@ -346,7 +346,7 @@ static int fuse_ctl_fill_super(struct super_block *sb, struct fs_context *fctx) | |||
346 | 346 | ||
347 | static int fuse_ctl_get_tree(struct fs_context *fc) | 347 | static int fuse_ctl_get_tree(struct fs_context *fc) |
348 | { | 348 | { |
349 | return vfs_get_super(fc, vfs_get_single_super, fuse_ctl_fill_super); | 349 | return get_tree_single(fc, fuse_ctl_fill_super); |
350 | } | 350 | } |
351 | 351 | ||
352 | static const struct fs_context_operations fuse_ctl_context_ops = { | 352 | static const struct fs_context_operations fuse_ctl_context_ops = { |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 1dcc57189382..a478df035651 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -1299,7 +1299,7 @@ static int hugetlbfs_get_tree(struct fs_context *fc) | |||
1299 | int err = hugetlbfs_validate(fc); | 1299 | int err = hugetlbfs_validate(fc); |
1300 | if (err) | 1300 | if (err) |
1301 | return err; | 1301 | return err; |
1302 | return vfs_get_super(fc, vfs_get_independent_super, hugetlbfs_fill_super); | 1302 | return get_tree_nodev(fc, hugetlbfs_fill_super); |
1303 | } | 1303 | } |
1304 | 1304 | ||
1305 | static void hugetlbfs_fs_context_free(struct fs_context *fc) | 1305 | static void hugetlbfs_fs_context_free(struct fs_context *fc) |
diff --git a/fs/internal.h b/fs/internal.h index 2f3c3de51fad..b9bad2d30cef 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -14,6 +14,7 @@ struct path; | |||
14 | struct mount; | 14 | struct mount; |
15 | struct shrink_control; | 15 | struct shrink_control; |
16 | struct fs_context; | 16 | struct fs_context; |
17 | struct user_namespace; | ||
17 | 18 | ||
18 | /* | 19 | /* |
19 | * block_dev.c | 20 | * block_dev.c |
@@ -107,6 +108,7 @@ extern struct file *alloc_empty_file_noaccount(int, const struct cred *); | |||
107 | extern int reconfigure_super(struct fs_context *); | 108 | extern int reconfigure_super(struct fs_context *); |
108 | extern bool trylock_super(struct super_block *sb); | 109 | extern bool trylock_super(struct super_block *sb); |
109 | extern struct super_block *user_get_super(dev_t); | 110 | extern struct super_block *user_get_super(dev_t); |
111 | extern bool mount_capable(struct fs_context *); | ||
110 | 112 | ||
111 | /* | 113 | /* |
112 | * open.c | 114 | * open.c |
@@ -154,6 +156,7 @@ extern int d_set_mounted(struct dentry *dentry); | |||
154 | extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc); | 156 | extern long prune_dcache_sb(struct super_block *sb, struct shrink_control *sc); |
155 | extern struct dentry *d_alloc_cursor(struct dentry *); | 157 | extern struct dentry *d_alloc_cursor(struct dentry *); |
156 | extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); | 158 | extern struct dentry * d_alloc_pseudo(struct super_block *, const struct qstr *); |
159 | extern char *simple_dname(struct dentry *, char *, int); | ||
157 | 160 | ||
158 | /* | 161 | /* |
159 | * read_write.c | 162 | * read_write.c |
diff --git a/fs/libfs.c b/fs/libfs.c index 7e52e77692ec..c9b2850c0f7c 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/exportfs.h> | 17 | #include <linux/exportfs.h> |
18 | #include <linux/writeback.h> | 18 | #include <linux/writeback.h> |
19 | #include <linux/buffer_head.h> /* sync_mapping_buffers */ | 19 | #include <linux/buffer_head.h> /* sync_mapping_buffers */ |
20 | #include <linux/fs_context.h> | ||
21 | #include <linux/pseudo_fs.h> | ||
20 | 22 | ||
21 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
22 | 24 | ||
@@ -236,34 +238,22 @@ static const struct super_operations simple_super_operations = { | |||
236 | .statfs = simple_statfs, | 238 | .statfs = simple_statfs, |
237 | }; | 239 | }; |
238 | 240 | ||
239 | /* | 241 | static int pseudo_fs_fill_super(struct super_block *s, struct fs_context *fc) |
240 | * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that | ||
241 | * will never be mountable) | ||
242 | */ | ||
243 | struct dentry *mount_pseudo_xattr(struct file_system_type *fs_type, char *name, | ||
244 | const struct super_operations *ops, const struct xattr_handler **xattr, | ||
245 | const struct dentry_operations *dops, unsigned long magic) | ||
246 | { | 242 | { |
247 | struct super_block *s; | 243 | struct pseudo_fs_context *ctx = fc->fs_private; |
248 | struct dentry *dentry; | ||
249 | struct inode *root; | 244 | struct inode *root; |
250 | struct qstr d_name = QSTR_INIT(name, strlen(name)); | ||
251 | |||
252 | s = sget_userns(fs_type, NULL, set_anon_super, SB_KERNMOUNT|SB_NOUSER, | ||
253 | &init_user_ns, NULL); | ||
254 | if (IS_ERR(s)) | ||
255 | return ERR_CAST(s); | ||
256 | 245 | ||
257 | s->s_maxbytes = MAX_LFS_FILESIZE; | 246 | s->s_maxbytes = MAX_LFS_FILESIZE; |
258 | s->s_blocksize = PAGE_SIZE; | 247 | s->s_blocksize = PAGE_SIZE; |
259 | s->s_blocksize_bits = PAGE_SHIFT; | 248 | s->s_blocksize_bits = PAGE_SHIFT; |
260 | s->s_magic = magic; | 249 | s->s_magic = ctx->magic; |
261 | s->s_op = ops ? ops : &simple_super_operations; | 250 | s->s_op = ctx->ops ?: &simple_super_operations; |
262 | s->s_xattr = xattr; | 251 | s->s_xattr = ctx->xattr; |
263 | s->s_time_gran = 1; | 252 | s->s_time_gran = 1; |
264 | root = new_inode(s); | 253 | root = new_inode(s); |
265 | if (!root) | 254 | if (!root) |
266 | goto Enomem; | 255 | return -ENOMEM; |
256 | |||
267 | /* | 257 | /* |
268 | * since this is the first inode, make it number 1. New inodes created | 258 | * since this is the first inode, make it number 1. New inodes created |
269 | * after this must take care not to collide with it (by passing | 259 | * after this must take care not to collide with it (by passing |
@@ -272,22 +262,48 @@ struct dentry *mount_pseudo_xattr(struct file_system_type *fs_type, char *name, | |||
272 | root->i_ino = 1; | 262 | root->i_ino = 1; |
273 | root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; | 263 | root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR; |
274 | root->i_atime = root->i_mtime = root->i_ctime = current_time(root); | 264 | root->i_atime = root->i_mtime = root->i_ctime = current_time(root); |
275 | dentry = __d_alloc(s, &d_name); | 265 | s->s_root = d_make_root(root); |
276 | if (!dentry) { | 266 | if (!s->s_root) |
277 | iput(root); | 267 | return -ENOMEM; |
278 | goto Enomem; | 268 | s->s_d_op = ctx->dops; |
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int pseudo_fs_get_tree(struct fs_context *fc) | ||
273 | { | ||
274 | return get_tree_nodev(fc, pseudo_fs_fill_super); | ||
275 | } | ||
276 | |||
277 | static void pseudo_fs_free(struct fs_context *fc) | ||
278 | { | ||
279 | kfree(fc->fs_private); | ||
280 | } | ||
281 | |||
282 | static const struct fs_context_operations pseudo_fs_context_ops = { | ||
283 | .free = pseudo_fs_free, | ||
284 | .get_tree = pseudo_fs_get_tree, | ||
285 | }; | ||
286 | |||
287 | /* | ||
288 | * Common helper for pseudo-filesystems (sockfs, pipefs, bdev - stuff that | ||
289 | * will never be mountable) | ||
290 | */ | ||
291 | struct pseudo_fs_context *init_pseudo(struct fs_context *fc, | ||
292 | unsigned long magic) | ||
293 | { | ||
294 | struct pseudo_fs_context *ctx; | ||
295 | |||
296 | ctx = kzalloc(sizeof(struct pseudo_fs_context), GFP_KERNEL); | ||
297 | if (likely(ctx)) { | ||
298 | ctx->magic = magic; | ||
299 | fc->fs_private = ctx; | ||
300 | fc->ops = &pseudo_fs_context_ops; | ||
301 | fc->sb_flags |= SB_NOUSER; | ||
302 | fc->global = true; | ||
279 | } | 303 | } |
280 | d_instantiate(dentry, root); | 304 | return ctx; |
281 | s->s_root = dentry; | ||
282 | s->s_d_op = dops; | ||
283 | s->s_flags |= SB_ACTIVE; | ||
284 | return dget(s->s_root); | ||
285 | |||
286 | Enomem: | ||
287 | deactivate_locked_super(s); | ||
288 | return ERR_PTR(-ENOMEM); | ||
289 | } | 305 | } |
290 | EXPORT_SYMBOL(mount_pseudo_xattr); | 306 | EXPORT_SYMBOL(init_pseudo); |
291 | 307 | ||
292 | int simple_open(struct inode *inode, struct file *file) | 308 | int simple_open(struct inode *inode, struct file *file) |
293 | { | 309 | { |
diff --git a/fs/namespace.c b/fs/namespace.c index 6fbc9126367a..f0d664adb9ba 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/sched/task.h> | 29 | #include <linux/sched/task.h> |
30 | #include <uapi/linux/mount.h> | 30 | #include <uapi/linux/mount.h> |
31 | #include <linux/fs_context.h> | 31 | #include <linux/fs_context.h> |
32 | #include <linux/shmem_fs.h> | ||
32 | 33 | ||
33 | #include "pnode.h" | 34 | #include "pnode.h" |
34 | #include "internal.h" | 35 | #include "internal.h" |
@@ -2788,6 +2789,8 @@ static int do_new_mount(struct path *path, const char *fstype, int sb_flags, | |||
2788 | err = vfs_parse_fs_string(fc, "source", name, strlen(name)); | 2789 | err = vfs_parse_fs_string(fc, "source", name, strlen(name)); |
2789 | if (!err) | 2790 | if (!err) |
2790 | err = parse_monolithic_mount_data(fc, data); | 2791 | err = parse_monolithic_mount_data(fc, data); |
2792 | if (!err && !mount_capable(fc)) | ||
2793 | err = -EPERM; | ||
2791 | if (!err) | 2794 | if (!err) |
2792 | err = vfs_get_tree(fc); | 2795 | err = vfs_get_tree(fc); |
2793 | if (!err) | 2796 | if (!err) |
@@ -3295,8 +3298,8 @@ struct dentry *mount_subtree(struct vfsmount *m, const char *name) | |||
3295 | } | 3298 | } |
3296 | EXPORT_SYMBOL(mount_subtree); | 3299 | EXPORT_SYMBOL(mount_subtree); |
3297 | 3300 | ||
3298 | int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, | 3301 | int ksys_mount(const char __user *dev_name, const char __user *dir_name, |
3299 | unsigned long flags, void __user *data) | 3302 | const char __user *type, unsigned long flags, void __user *data) |
3300 | { | 3303 | { |
3301 | int ret; | 3304 | int ret; |
3302 | char *kernel_type; | 3305 | char *kernel_type; |
@@ -3687,13 +3690,8 @@ static void __init init_mount_tree(void) | |||
3687 | struct mount *m; | 3690 | struct mount *m; |
3688 | struct mnt_namespace *ns; | 3691 | struct mnt_namespace *ns; |
3689 | struct path root; | 3692 | struct path root; |
3690 | struct file_system_type *type; | ||
3691 | 3693 | ||
3692 | type = get_fs_type("rootfs"); | 3694 | mnt = vfs_kern_mount(&rootfs_fs_type, 0, "rootfs", NULL); |
3693 | if (!type) | ||
3694 | panic("Can't find rootfs type"); | ||
3695 | mnt = vfs_kern_mount(type, 0, "rootfs", NULL); | ||
3696 | put_filesystem(type); | ||
3697 | if (IS_ERR(mnt)) | 3695 | if (IS_ERR(mnt)) |
3698 | panic("Can't create rootfs"); | 3696 | panic("Can't create rootfs"); |
3699 | 3697 | ||
@@ -3746,6 +3744,7 @@ void __init mnt_init(void) | |||
3746 | fs_kobj = kobject_create_and_add("fs", NULL); | 3744 | fs_kobj = kobject_create_and_add("fs", NULL); |
3747 | if (!fs_kobj) | 3745 | if (!fs_kobj) |
3748 | printk(KERN_WARNING "%s: kobj create error\n", __func__); | 3746 | printk(KERN_WARNING "%s: kobj create error\n", __func__); |
3747 | shmem_init(); | ||
3749 | init_rootfs(); | 3748 | init_rootfs(); |
3750 | init_mount_tree(); | 3749 | init_mount_tree(); |
3751 | } | 3750 | } |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 0a9a49ded546..13c548733860 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/namei.h> | 9 | #include <linux/namei.h> |
10 | #include <linux/ctype.h> | 10 | #include <linux/ctype.h> |
11 | #include <linux/fs_context.h> | ||
11 | 12 | ||
12 | #include <linux/sunrpc/svcsock.h> | 13 | #include <linux/sunrpc/svcsock.h> |
13 | #include <linux/lockd/lockd.h> | 14 | #include <linux/lockd/lockd.h> |
@@ -1337,7 +1338,7 @@ void nfsd_client_rmdir(struct dentry *dentry) | |||
1337 | inode_unlock(dir); | 1338 | inode_unlock(dir); |
1338 | } | 1339 | } |
1339 | 1340 | ||
1340 | static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | 1341 | static int nfsd_fill_super(struct super_block *sb, struct fs_context *fc) |
1341 | { | 1342 | { |
1342 | struct nfsd_net *nn = net_generic(current->nsproxy->net_ns, | 1343 | struct nfsd_net *nn = net_generic(current->nsproxy->net_ns, |
1343 | nfsd_net_id); | 1344 | nfsd_net_id); |
@@ -1372,7 +1373,7 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | |||
1372 | #endif | 1373 | #endif |
1373 | /* last one */ {""} | 1374 | /* last one */ {""} |
1374 | }; | 1375 | }; |
1375 | get_net(sb->s_fs_info); | 1376 | |
1376 | ret = simple_fill_super(sb, 0x6e667364, nfsd_files); | 1377 | ret = simple_fill_super(sb, 0x6e667364, nfsd_files); |
1377 | if (ret) | 1378 | if (ret) |
1378 | return ret; | 1379 | return ret; |
@@ -1381,14 +1382,31 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | |||
1381 | return PTR_ERR(dentry); | 1382 | return PTR_ERR(dentry); |
1382 | nn->nfsd_client_dir = dentry; | 1383 | nn->nfsd_client_dir = dentry; |
1383 | return 0; | 1384 | return 0; |
1385 | } | ||
1384 | 1386 | ||
1387 | static int nfsd_fs_get_tree(struct fs_context *fc) | ||
1388 | { | ||
1389 | fc->s_fs_info = get_net(fc->net_ns); | ||
1390 | return vfs_get_super(fc, vfs_get_keyed_super, nfsd_fill_super); | ||
1385 | } | 1391 | } |
1386 | 1392 | ||
1387 | static struct dentry *nfsd_mount(struct file_system_type *fs_type, | 1393 | static void nfsd_fs_free_fc(struct fs_context *fc) |
1388 | int flags, const char *dev_name, void *data) | ||
1389 | { | 1394 | { |
1390 | struct net *net = current->nsproxy->net_ns; | 1395 | if (fc->s_fs_info) |
1391 | return mount_ns(fs_type, flags, data, net, net->user_ns, nfsd_fill_super); | 1396 | put_net(fc->s_fs_info); |
1397 | } | ||
1398 | |||
1399 | static const struct fs_context_operations nfsd_fs_context_ops = { | ||
1400 | .free = nfsd_fs_free_fc, | ||
1401 | .get_tree = nfsd_fs_get_tree, | ||
1402 | }; | ||
1403 | |||
1404 | static int nfsd_init_fs_context(struct fs_context *fc) | ||
1405 | { | ||
1406 | put_user_ns(fc->user_ns); | ||
1407 | fc->user_ns = get_user_ns(fc->net_ns->user_ns); | ||
1408 | fc->ops = &nfsd_fs_context_ops; | ||
1409 | return 0; | ||
1392 | } | 1410 | } |
1393 | 1411 | ||
1394 | static void nfsd_umount(struct super_block *sb) | 1412 | static void nfsd_umount(struct super_block *sb) |
@@ -1402,7 +1420,7 @@ static void nfsd_umount(struct super_block *sb) | |||
1402 | static struct file_system_type nfsd_fs_type = { | 1420 | static struct file_system_type nfsd_fs_type = { |
1403 | .owner = THIS_MODULE, | 1421 | .owner = THIS_MODULE, |
1404 | .name = "nfsd", | 1422 | .name = "nfsd", |
1405 | .mount = nfsd_mount, | 1423 | .init_fs_context = nfsd_init_fs_context, |
1406 | .kill_sb = nfsd_umount, | 1424 | .kill_sb = nfsd_umount, |
1407 | }; | 1425 | }; |
1408 | MODULE_ALIAS_FS("nfsd"); | 1426 | MODULE_ALIAS_FS("nfsd"); |
@@ -1,5 +1,6 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
2 | #include <linux/mount.h> | 2 | #include <linux/mount.h> |
3 | #include <linux/pseudo_fs.h> | ||
3 | #include <linux/file.h> | 4 | #include <linux/file.h> |
4 | #include <linux/fs.h> | 5 | #include <linux/fs.h> |
5 | #include <linux/proc_ns.h> | 6 | #include <linux/proc_ns.h> |
@@ -258,15 +259,20 @@ static const struct super_operations nsfs_ops = { | |||
258 | .evict_inode = nsfs_evict, | 259 | .evict_inode = nsfs_evict, |
259 | .show_path = nsfs_show_path, | 260 | .show_path = nsfs_show_path, |
260 | }; | 261 | }; |
261 | static struct dentry *nsfs_mount(struct file_system_type *fs_type, | 262 | |
262 | int flags, const char *dev_name, void *data) | 263 | static int nsfs_init_fs_context(struct fs_context *fc) |
263 | { | 264 | { |
264 | return mount_pseudo(fs_type, "nsfs:", &nsfs_ops, | 265 | struct pseudo_fs_context *ctx = init_pseudo(fc, NSFS_MAGIC); |
265 | &ns_dentry_operations, NSFS_MAGIC); | 266 | if (!ctx) |
267 | return -ENOMEM; | ||
268 | ctx->ops = &nsfs_ops; | ||
269 | ctx->dops = &ns_dentry_operations; | ||
270 | return 0; | ||
266 | } | 271 | } |
272 | |||
267 | static struct file_system_type nsfs = { | 273 | static struct file_system_type nsfs = { |
268 | .name = "nsfs", | 274 | .name = "nsfs", |
269 | .mount = nsfs_mount, | 275 | .init_fs_context = nsfs_init_fs_context, |
270 | .kill_sb = kill_anon_super, | 276 | .kill_sb = kill_anon_super, |
271 | }; | 277 | }; |
272 | 278 | ||
diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index e6cb7689fec4..40c8c2e32fa3 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/string.h> | 10 | #include <linux/string.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/fs_context.h> | ||
12 | #include <linux/init.h> | 13 | #include <linux/init.h> |
13 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
14 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
@@ -375,7 +376,7 @@ static const struct super_operations openprom_sops = { | |||
375 | .remount_fs = openprom_remount, | 376 | .remount_fs = openprom_remount, |
376 | }; | 377 | }; |
377 | 378 | ||
378 | static int openprom_fill_super(struct super_block *s, void *data, int silent) | 379 | static int openprom_fill_super(struct super_block *s, struct fs_context *fc) |
379 | { | 380 | { |
380 | struct inode *root_inode; | 381 | struct inode *root_inode; |
381 | struct op_inode_info *oi; | 382 | struct op_inode_info *oi; |
@@ -409,16 +410,25 @@ out_no_root: | |||
409 | return ret; | 410 | return ret; |
410 | } | 411 | } |
411 | 412 | ||
412 | static struct dentry *openprom_mount(struct file_system_type *fs_type, | 413 | static int openpromfs_get_tree(struct fs_context *fc) |
413 | int flags, const char *dev_name, void *data) | ||
414 | { | 414 | { |
415 | return mount_single(fs_type, flags, data, openprom_fill_super); | 415 | return get_tree_single(fc, openprom_fill_super); |
416 | } | ||
417 | |||
418 | static const struct fs_context_operations openpromfs_context_ops = { | ||
419 | .get_tree = openpromfs_get_tree, | ||
420 | }; | ||
421 | |||
422 | static int openpromfs_init_fs_context(struct fs_context *fc) | ||
423 | { | ||
424 | fc->ops = &openpromfs_context_ops; | ||
425 | return 0; | ||
416 | } | 426 | } |
417 | 427 | ||
418 | static struct file_system_type openprom_fs_type = { | 428 | static struct file_system_type openprom_fs_type = { |
419 | .owner = THIS_MODULE, | 429 | .owner = THIS_MODULE, |
420 | .name = "openpromfs", | 430 | .name = "openpromfs", |
421 | .mount = openprom_mount, | 431 | .init_fs_context = openpromfs_init_fs_context, |
422 | .kill_sb = kill_anon_super, | 432 | .kill_sb = kill_anon_super, |
423 | }; | 433 | }; |
424 | MODULE_ALIAS_FS("openpromfs"); | 434 | MODULE_ALIAS_FS("openpromfs"); |
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/log2.h> | 15 | #include <linux/log2.h> |
16 | #include <linux/mount.h> | 16 | #include <linux/mount.h> |
17 | #include <linux/pseudo_fs.h> | ||
17 | #include <linux/magic.h> | 18 | #include <linux/magic.h> |
18 | #include <linux/pipe_fs_i.h> | 19 | #include <linux/pipe_fs_i.h> |
19 | #include <linux/uio.h> | 20 | #include <linux/uio.h> |
@@ -1182,16 +1183,20 @@ static const struct super_operations pipefs_ops = { | |||
1182 | * any operations on the root directory. However, we need a non-trivial | 1183 | * any operations on the root directory. However, we need a non-trivial |
1183 | * d_name - pipe: will go nicely and kill the special-casing in procfs. | 1184 | * d_name - pipe: will go nicely and kill the special-casing in procfs. |
1184 | */ | 1185 | */ |
1185 | static struct dentry *pipefs_mount(struct file_system_type *fs_type, | 1186 | |
1186 | int flags, const char *dev_name, void *data) | 1187 | static int pipefs_init_fs_context(struct fs_context *fc) |
1187 | { | 1188 | { |
1188 | return mount_pseudo(fs_type, "pipe:", &pipefs_ops, | 1189 | struct pseudo_fs_context *ctx = init_pseudo(fc, PIPEFS_MAGIC); |
1189 | &pipefs_dentry_operations, PIPEFS_MAGIC); | 1190 | if (!ctx) |
1191 | return -ENOMEM; | ||
1192 | ctx->ops = &pipefs_ops; | ||
1193 | ctx->dops = &pipefs_dentry_operations; | ||
1194 | return 0; | ||
1190 | } | 1195 | } |
1191 | 1196 | ||
1192 | static struct file_system_type pipe_fs_type = { | 1197 | static struct file_system_type pipe_fs_type = { |
1193 | .name = "pipefs", | 1198 | .name = "pipefs", |
1194 | .mount = pipefs_mount, | 1199 | .init_fs_context = pipefs_init_fs_context, |
1195 | .kill_sb = kill_anon_super, | 1200 | .kill_sb = kill_anon_super, |
1196 | }; | 1201 | }; |
1197 | 1202 | ||
diff --git a/fs/proc/root.c b/fs/proc/root.c index 522199e9525e..33f72d1b92cc 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -157,8 +157,6 @@ static int proc_get_tree(struct fs_context *fc) | |||
157 | { | 157 | { |
158 | struct proc_fs_context *ctx = fc->fs_private; | 158 | struct proc_fs_context *ctx = fc->fs_private; |
159 | 159 | ||
160 | put_user_ns(fc->user_ns); | ||
161 | fc->user_ns = get_user_ns(ctx->pid_ns->user_ns); | ||
162 | fc->s_fs_info = ctx->pid_ns; | 160 | fc->s_fs_info = ctx->pid_ns; |
163 | return vfs_get_super(fc, vfs_get_keyed_super, proc_fill_super); | 161 | return vfs_get_super(fc, vfs_get_keyed_super, proc_fill_super); |
164 | } | 162 | } |
@@ -167,8 +165,7 @@ static void proc_fs_context_free(struct fs_context *fc) | |||
167 | { | 165 | { |
168 | struct proc_fs_context *ctx = fc->fs_private; | 166 | struct proc_fs_context *ctx = fc->fs_private; |
169 | 167 | ||
170 | if (ctx->pid_ns) | 168 | put_pid_ns(ctx->pid_ns); |
171 | put_pid_ns(ctx->pid_ns); | ||
172 | kfree(ctx); | 169 | kfree(ctx); |
173 | } | 170 | } |
174 | 171 | ||
@@ -188,6 +185,8 @@ static int proc_init_fs_context(struct fs_context *fc) | |||
188 | return -ENOMEM; | 185 | return -ENOMEM; |
189 | 186 | ||
190 | ctx->pid_ns = get_pid_ns(task_active_pid_ns(current)); | 187 | ctx->pid_ns = get_pid_ns(task_active_pid_ns(current)); |
188 | put_user_ns(fc->user_ns); | ||
189 | fc->user_ns = get_user_ns(ctx->pid_ns->user_ns); | ||
191 | fc->fs_private = ctx; | 190 | fc->fs_private = ctx; |
192 | fc->ops = &proc_fs_context_ops; | 191 | fc->ops = &proc_fs_context_ops; |
193 | return 0; | 192 | return 0; |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 11201b2d06b9..733c6b4193dc 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -266,12 +266,8 @@ static struct file_system_type ramfs_fs_type = { | |||
266 | .fs_flags = FS_USERNS_MOUNT, | 266 | .fs_flags = FS_USERNS_MOUNT, |
267 | }; | 267 | }; |
268 | 268 | ||
269 | int __init init_ramfs_fs(void) | 269 | static int __init init_ramfs_fs(void) |
270 | { | 270 | { |
271 | static unsigned long once; | ||
272 | |||
273 | if (test_and_set_bit(0, &once)) | ||
274 | return 0; | ||
275 | return register_filesystem(&ramfs_fs_type); | 271 | return register_filesystem(&ramfs_fs_type); |
276 | } | 272 | } |
277 | fs_initcall(init_ramfs_fs); | 273 | fs_initcall(init_ramfs_fs); |
diff --git a/fs/super.c b/fs/super.c index 2739f57515f8..113c58f19425 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -476,6 +476,17 @@ void generic_shutdown_super(struct super_block *sb) | |||
476 | 476 | ||
477 | EXPORT_SYMBOL(generic_shutdown_super); | 477 | EXPORT_SYMBOL(generic_shutdown_super); |
478 | 478 | ||
479 | bool mount_capable(struct fs_context *fc) | ||
480 | { | ||
481 | struct user_namespace *user_ns = fc->global ? &init_user_ns | ||
482 | : fc->user_ns; | ||
483 | |||
484 | if (!(fc->fs_type->fs_flags & FS_USERNS_MOUNT)) | ||
485 | return capable(CAP_SYS_ADMIN); | ||
486 | else | ||
487 | return ns_capable(user_ns, CAP_SYS_ADMIN); | ||
488 | } | ||
489 | |||
479 | /** | 490 | /** |
480 | * sget_fc - Find or create a superblock | 491 | * sget_fc - Find or create a superblock |
481 | * @fc: Filesystem context. | 492 | * @fc: Filesystem context. |
@@ -503,20 +514,6 @@ struct super_block *sget_fc(struct fs_context *fc, | |||
503 | struct user_namespace *user_ns = fc->global ? &init_user_ns : fc->user_ns; | 514 | struct user_namespace *user_ns = fc->global ? &init_user_ns : fc->user_ns; |
504 | int err; | 515 | int err; |
505 | 516 | ||
506 | if (!(fc->sb_flags & SB_KERNMOUNT) && | ||
507 | fc->purpose != FS_CONTEXT_FOR_SUBMOUNT) { | ||
508 | /* Don't allow mounting unless the caller has CAP_SYS_ADMIN | ||
509 | * over the namespace. | ||
510 | */ | ||
511 | if (!(fc->fs_type->fs_flags & FS_USERNS_MOUNT)) { | ||
512 | if (!capable(CAP_SYS_ADMIN)) | ||
513 | return ERR_PTR(-EPERM); | ||
514 | } else { | ||
515 | if (!ns_capable(fc->user_ns, CAP_SYS_ADMIN)) | ||
516 | return ERR_PTR(-EPERM); | ||
517 | } | ||
518 | } | ||
519 | |||
520 | retry: | 517 | retry: |
521 | spin_lock(&sb_lock); | 518 | spin_lock(&sb_lock); |
522 | if (test) { | 519 | if (test) { |
@@ -543,6 +540,7 @@ retry: | |||
543 | } | 540 | } |
544 | fc->s_fs_info = NULL; | 541 | fc->s_fs_info = NULL; |
545 | s->s_type = fc->fs_type; | 542 | s->s_type = fc->fs_type; |
543 | s->s_iflags |= fc->s_iflags; | ||
546 | strlcpy(s->s_id, s->s_type->name, sizeof(s->s_id)); | 544 | strlcpy(s->s_id, s->s_type->name, sizeof(s->s_id)); |
547 | list_add_tail(&s->s_list, &super_blocks); | 545 | list_add_tail(&s->s_list, &super_blocks); |
548 | hlist_add_head(&s->s_instances, &s->s_type->fs_supers); | 546 | hlist_add_head(&s->s_instances, &s->s_type->fs_supers); |
@@ -565,28 +563,31 @@ share_extant_sb: | |||
565 | EXPORT_SYMBOL(sget_fc); | 563 | EXPORT_SYMBOL(sget_fc); |
566 | 564 | ||
567 | /** | 565 | /** |
568 | * sget_userns - find or create a superblock | 566 | * sget - find or create a superblock |
569 | * @type: filesystem type superblock should belong to | 567 | * @type: filesystem type superblock should belong to |
570 | * @test: comparison callback | 568 | * @test: comparison callback |
571 | * @set: setup callback | 569 | * @set: setup callback |
572 | * @flags: mount flags | 570 | * @flags: mount flags |
573 | * @user_ns: User namespace for the super_block | 571 | * @data: argument to each of them |
574 | * @data: argument to each of them | ||
575 | */ | 572 | */ |
576 | struct super_block *sget_userns(struct file_system_type *type, | 573 | struct super_block *sget(struct file_system_type *type, |
577 | int (*test)(struct super_block *,void *), | 574 | int (*test)(struct super_block *,void *), |
578 | int (*set)(struct super_block *,void *), | 575 | int (*set)(struct super_block *,void *), |
579 | int flags, struct user_namespace *user_ns, | 576 | int flags, |
580 | void *data) | 577 | void *data) |
581 | { | 578 | { |
579 | struct user_namespace *user_ns = current_user_ns(); | ||
582 | struct super_block *s = NULL; | 580 | struct super_block *s = NULL; |
583 | struct super_block *old; | 581 | struct super_block *old; |
584 | int err; | 582 | int err; |
585 | 583 | ||
586 | if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT)) && | 584 | /* We don't yet pass the user namespace of the parent |
587 | !(type->fs_flags & FS_USERNS_MOUNT) && | 585 | * mount through to here so always use &init_user_ns |
588 | !capable(CAP_SYS_ADMIN)) | 586 | * until that changes. |
589 | return ERR_PTR(-EPERM); | 587 | */ |
588 | if (flags & SB_SUBMOUNT) | ||
589 | user_ns = &init_user_ns; | ||
590 | |||
590 | retry: | 591 | retry: |
591 | spin_lock(&sb_lock); | 592 | spin_lock(&sb_lock); |
592 | if (test) { | 593 | if (test) { |
@@ -627,39 +628,6 @@ retry: | |||
627 | register_shrinker_prepared(&s->s_shrink); | 628 | register_shrinker_prepared(&s->s_shrink); |
628 | return s; | 629 | return s; |
629 | } | 630 | } |
630 | |||
631 | EXPORT_SYMBOL(sget_userns); | ||
632 | |||
633 | /** | ||
634 | * sget - find or create a superblock | ||
635 | * @type: filesystem type superblock should belong to | ||
636 | * @test: comparison callback | ||
637 | * @set: setup callback | ||
638 | * @flags: mount flags | ||
639 | * @data: argument to each of them | ||
640 | */ | ||
641 | struct super_block *sget(struct file_system_type *type, | ||
642 | int (*test)(struct super_block *,void *), | ||
643 | int (*set)(struct super_block *,void *), | ||
644 | int flags, | ||
645 | void *data) | ||
646 | { | ||
647 | struct user_namespace *user_ns = current_user_ns(); | ||
648 | |||
649 | /* We don't yet pass the user namespace of the parent | ||
650 | * mount through to here so always use &init_user_ns | ||
651 | * until that changes. | ||
652 | */ | ||
653 | if (flags & SB_SUBMOUNT) | ||
654 | user_ns = &init_user_ns; | ||
655 | |||
656 | /* Ensure the requestor has permissions over the target filesystem */ | ||
657 | if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT)) && !ns_capable(user_ns, CAP_SYS_ADMIN)) | ||
658 | return ERR_PTR(-EPERM); | ||
659 | |||
660 | return sget_userns(type, test, set, flags, user_ns, data); | ||
661 | } | ||
662 | |||
663 | EXPORT_SYMBOL(sget); | 631 | EXPORT_SYMBOL(sget); |
664 | 632 | ||
665 | void drop_super(struct super_block *sb) | 633 | void drop_super(struct super_block *sb) |
@@ -1147,50 +1115,6 @@ void kill_litter_super(struct super_block *sb) | |||
1147 | } | 1115 | } |
1148 | EXPORT_SYMBOL(kill_litter_super); | 1116 | EXPORT_SYMBOL(kill_litter_super); |
1149 | 1117 | ||
1150 | static int ns_test_super(struct super_block *sb, void *data) | ||
1151 | { | ||
1152 | return sb->s_fs_info == data; | ||
1153 | } | ||
1154 | |||
1155 | static int ns_set_super(struct super_block *sb, void *data) | ||
1156 | { | ||
1157 | sb->s_fs_info = data; | ||
1158 | return set_anon_super(sb, NULL); | ||
1159 | } | ||
1160 | |||
1161 | struct dentry *mount_ns(struct file_system_type *fs_type, | ||
1162 | int flags, void *data, void *ns, struct user_namespace *user_ns, | ||
1163 | int (*fill_super)(struct super_block *, void *, int)) | ||
1164 | { | ||
1165 | struct super_block *sb; | ||
1166 | |||
1167 | /* Don't allow mounting unless the caller has CAP_SYS_ADMIN | ||
1168 | * over the namespace. | ||
1169 | */ | ||
1170 | if (!(flags & SB_KERNMOUNT) && !ns_capable(user_ns, CAP_SYS_ADMIN)) | ||
1171 | return ERR_PTR(-EPERM); | ||
1172 | |||
1173 | sb = sget_userns(fs_type, ns_test_super, ns_set_super, flags, | ||
1174 | user_ns, ns); | ||
1175 | if (IS_ERR(sb)) | ||
1176 | return ERR_CAST(sb); | ||
1177 | |||
1178 | if (!sb->s_root) { | ||
1179 | int err; | ||
1180 | err = fill_super(sb, data, flags & SB_SILENT ? 1 : 0); | ||
1181 | if (err) { | ||
1182 | deactivate_locked_super(sb); | ||
1183 | return ERR_PTR(err); | ||
1184 | } | ||
1185 | |||
1186 | sb->s_flags |= SB_ACTIVE; | ||
1187 | } | ||
1188 | |||
1189 | return dget(sb->s_root); | ||
1190 | } | ||
1191 | |||
1192 | EXPORT_SYMBOL(mount_ns); | ||
1193 | |||
1194 | int set_anon_super_fc(struct super_block *sb, struct fs_context *fc) | 1118 | int set_anon_super_fc(struct super_block *sb, struct fs_context *fc) |
1195 | { | 1119 | { |
1196 | return set_anon_super(sb, NULL); | 1120 | return set_anon_super(sb, NULL); |
@@ -1274,6 +1198,22 @@ int vfs_get_super(struct fs_context *fc, | |||
1274 | } | 1198 | } |
1275 | EXPORT_SYMBOL(vfs_get_super); | 1199 | EXPORT_SYMBOL(vfs_get_super); |
1276 | 1200 | ||
1201 | int get_tree_nodev(struct fs_context *fc, | ||
1202 | int (*fill_super)(struct super_block *sb, | ||
1203 | struct fs_context *fc)) | ||
1204 | { | ||
1205 | return vfs_get_super(fc, vfs_get_independent_super, fill_super); | ||
1206 | } | ||
1207 | EXPORT_SYMBOL(get_tree_nodev); | ||
1208 | |||
1209 | int get_tree_single(struct fs_context *fc, | ||
1210 | int (*fill_super)(struct super_block *sb, | ||
1211 | struct fs_context *fc)) | ||
1212 | { | ||
1213 | return vfs_get_super(fc, vfs_get_single_super, fill_super); | ||
1214 | } | ||
1215 | EXPORT_SYMBOL(get_tree_single); | ||
1216 | |||
1277 | #ifdef CONFIG_BLOCK | 1217 | #ifdef CONFIG_BLOCK |
1278 | static int set_bdev_super(struct super_block *s, void *data) | 1218 | static int set_bdev_super(struct super_block *s, void *data) |
1279 | { | 1219 | { |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 1b56686ab178..db81cfbab9d6 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -72,8 +72,7 @@ static int sysfs_init_fs_context(struct fs_context *fc) | |||
72 | fc->fs_private = kfc; | 72 | fc->fs_private = kfc; |
73 | fc->ops = &sysfs_fs_context_ops; | 73 | fc->ops = &sysfs_fs_context_ops; |
74 | if (netns) { | 74 | if (netns) { |
75 | if (fc->user_ns) | 75 | put_user_ns(fc->user_ns); |
76 | put_user_ns(fc->user_ns); | ||
77 | fc->user_ns = get_user_ns(netns->user_ns); | 76 | fc->user_ns = get_user_ns(netns->user_ns); |
78 | } | 77 | } |
79 | fc->global = true; | 78 | fc->global = true; |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 5e0eadf7de55..9451011ac014 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -291,7 +291,6 @@ static inline unsigned d_count(const struct dentry *dentry) | |||
291 | */ | 291 | */ |
292 | extern __printf(4, 5) | 292 | extern __printf(4, 5) |
293 | char *dynamic_dname(struct dentry *, char *, int, const char *, ...); | 293 | char *dynamic_dname(struct dentry *, char *, int, const char *, ...); |
294 | extern char *simple_dname(struct dentry *, char *, int); | ||
295 | 294 | ||
296 | extern char *__d_path(const struct path *, const struct path *, char *, int); | 295 | extern char *__d_path(const struct path *, const struct path *, char *, int); |
297 | extern char *d_absolute_path(const struct path *, char *, int); | 296 | extern char *d_absolute_path(const struct path *, char *, int); |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 75f2ed289a3f..56b8e358af5c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2210,9 +2210,6 @@ struct file_system_type { | |||
2210 | 2210 | ||
2211 | #define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME) | 2211 | #define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME) |
2212 | 2212 | ||
2213 | extern struct dentry *mount_ns(struct file_system_type *fs_type, | ||
2214 | int flags, void *data, void *ns, struct user_namespace *user_ns, | ||
2215 | int (*fill_super)(struct super_block *, void *, int)); | ||
2216 | #ifdef CONFIG_BLOCK | 2213 | #ifdef CONFIG_BLOCK |
2217 | extern struct dentry *mount_bdev(struct file_system_type *fs_type, | 2214 | extern struct dentry *mount_bdev(struct file_system_type *fs_type, |
2218 | int flags, const char *dev_name, void *data, | 2215 | int flags, const char *dev_name, void *data, |
@@ -2252,28 +2249,10 @@ void free_anon_bdev(dev_t); | |||
2252 | struct super_block *sget_fc(struct fs_context *fc, | 2249 | struct super_block *sget_fc(struct fs_context *fc, |
2253 | int (*test)(struct super_block *, struct fs_context *), | 2250 | int (*test)(struct super_block *, struct fs_context *), |
2254 | int (*set)(struct super_block *, struct fs_context *)); | 2251 | int (*set)(struct super_block *, struct fs_context *)); |
2255 | struct super_block *sget_userns(struct file_system_type *type, | ||
2256 | int (*test)(struct super_block *,void *), | ||
2257 | int (*set)(struct super_block *,void *), | ||
2258 | int flags, struct user_namespace *user_ns, | ||
2259 | void *data); | ||
2260 | struct super_block *sget(struct file_system_type *type, | 2252 | struct super_block *sget(struct file_system_type *type, |
2261 | int (*test)(struct super_block *,void *), | 2253 | int (*test)(struct super_block *,void *), |
2262 | int (*set)(struct super_block *,void *), | 2254 | int (*set)(struct super_block *,void *), |
2263 | int flags, void *data); | 2255 | int flags, void *data); |
2264 | extern struct dentry *mount_pseudo_xattr(struct file_system_type *, char *, | ||
2265 | const struct super_operations *ops, | ||
2266 | const struct xattr_handler **xattr, | ||
2267 | const struct dentry_operations *dops, | ||
2268 | unsigned long); | ||
2269 | |||
2270 | static inline struct dentry * | ||
2271 | mount_pseudo(struct file_system_type *fs_type, char *name, | ||
2272 | const struct super_operations *ops, | ||
2273 | const struct dentry_operations *dops, unsigned long magic) | ||
2274 | { | ||
2275 | return mount_pseudo_xattr(fs_type, name, ops, NULL, dops, magic); | ||
2276 | } | ||
2277 | 2256 | ||
2278 | /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ | 2257 | /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ |
2279 | #define fops_get(fops) \ | 2258 | #define fops_get(fops) \ |
diff --git a/include/linux/fs_context.h b/include/linux/fs_context.h index 4933187d5b9a..7c6fe3d47fa6 100644 --- a/include/linux/fs_context.h +++ b/include/linux/fs_context.h | |||
@@ -99,6 +99,7 @@ struct fs_context { | |||
99 | void *s_fs_info; /* Proposed s_fs_info */ | 99 | void *s_fs_info; /* Proposed s_fs_info */ |
100 | unsigned int sb_flags; /* Proposed superblock flags (SB_*) */ | 100 | unsigned int sb_flags; /* Proposed superblock flags (SB_*) */ |
101 | unsigned int sb_flags_mask; /* Superblock flags that were changed */ | 101 | unsigned int sb_flags_mask; /* Superblock flags that were changed */ |
102 | unsigned int s_iflags; /* OR'd with sb->s_iflags */ | ||
102 | unsigned int lsm_flags; /* Information flags from the fs to the LSM */ | 103 | unsigned int lsm_flags; /* Information flags from the fs to the LSM */ |
103 | enum fs_context_purpose purpose:8; | 104 | enum fs_context_purpose purpose:8; |
104 | enum fs_context_phase phase:8; /* The phase the context is in */ | 105 | enum fs_context_phase phase:8; /* The phase the context is in */ |
@@ -146,6 +147,12 @@ extern int vfs_get_super(struct fs_context *fc, | |||
146 | enum vfs_get_super_keying keying, | 147 | enum vfs_get_super_keying keying, |
147 | int (*fill_super)(struct super_block *sb, | 148 | int (*fill_super)(struct super_block *sb, |
148 | struct fs_context *fc)); | 149 | struct fs_context *fc)); |
150 | extern int get_tree_nodev(struct fs_context *fc, | ||
151 | int (*fill_super)(struct super_block *sb, | ||
152 | struct fs_context *fc)); | ||
153 | extern int get_tree_single(struct fs_context *fc, | ||
154 | int (*fill_super)(struct super_block *sb, | ||
155 | struct fs_context *fc)); | ||
149 | 156 | ||
150 | extern const struct file_operations fscontext_fops; | 157 | extern const struct file_operations fscontext_fops; |
151 | 158 | ||
diff --git a/include/linux/init.h b/include/linux/init.h index 5255069f5a9f..212fc9e2f691 100644 --- a/include/linux/init.h +++ b/include/linux/init.h | |||
@@ -137,6 +137,8 @@ extern initcall_entry_t __con_initcall_start[], __con_initcall_end[]; | |||
137 | /* Used for contructor calls. */ | 137 | /* Used for contructor calls. */ |
138 | typedef void (*ctor_fn_t)(void); | 138 | typedef void (*ctor_fn_t)(void); |
139 | 139 | ||
140 | struct file_system_type; | ||
141 | |||
140 | /* Defined in init/main.c */ | 142 | /* Defined in init/main.c */ |
141 | extern int do_one_initcall(initcall_t fn); | 143 | extern int do_one_initcall(initcall_t fn); |
142 | extern char __initdata boot_command_line[]; | 144 | extern char __initdata boot_command_line[]; |
@@ -146,7 +148,8 @@ extern unsigned int reset_devices; | |||
146 | /* used by init/main.c */ | 148 | /* used by init/main.c */ |
147 | void setup_arch(char **); | 149 | void setup_arch(char **); |
148 | void prepare_namespace(void); | 150 | void prepare_namespace(void); |
149 | int __init init_rootfs(void); | 151 | void __init init_rootfs(void); |
152 | extern struct file_system_type rootfs_fs_type; | ||
150 | 153 | ||
151 | #if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX) | 154 | #if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX) |
152 | extern bool rodata_enabled; | 155 | extern bool rodata_enabled; |
diff --git a/include/linux/pseudo_fs.h b/include/linux/pseudo_fs.h new file mode 100644 index 000000000000..eceda1d1407a --- /dev/null +++ b/include/linux/pseudo_fs.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef __LINUX_PSEUDO_FS__ | ||
2 | #define __LINUX_PSEUDO_FS__ | ||
3 | |||
4 | #include <linux/fs_context.h> | ||
5 | |||
6 | struct pseudo_fs_context { | ||
7 | const struct super_operations *ops; | ||
8 | const struct xattr_handler **xattr; | ||
9 | const struct dentry_operations *dops; | ||
10 | unsigned long magic; | ||
11 | }; | ||
12 | |||
13 | struct pseudo_fs_context *init_pseudo(struct fs_context *fc, | ||
14 | unsigned long magic); | ||
15 | |||
16 | #endif | ||
diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h index 5ef7d54caac2..ee582bdb7fda 100644 --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h | |||
@@ -19,7 +19,6 @@ extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); | |||
19 | 19 | ||
20 | extern const struct file_operations ramfs_file_operations; | 20 | extern const struct file_operations ramfs_file_operations; |
21 | extern const struct vm_operations_struct generic_file_vm_ops; | 21 | extern const struct vm_operations_struct generic_file_vm_ops; |
22 | extern int __init init_ramfs_fs(void); | ||
23 | 22 | ||
24 | int ramfs_fill_super(struct super_block *sb, void *data, int silent); | 23 | int ramfs_fill_super(struct super_block *sb, void *data, int silent); |
25 | 24 | ||
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index b01d54a5732e..88145da7d140 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -1231,8 +1231,8 @@ asmlinkage long sys_ni_syscall(void); | |||
1231 | * the ksys_xyzyyz() functions prototyped below. | 1231 | * the ksys_xyzyyz() functions prototyped below. |
1232 | */ | 1232 | */ |
1233 | 1233 | ||
1234 | int ksys_mount(char __user *dev_name, char __user *dir_name, char __user *type, | 1234 | int ksys_mount(const char __user *dev_name, const char __user *dir_name, |
1235 | unsigned long flags, void __user *data); | 1235 | const char __user *type, unsigned long flags, void __user *data); |
1236 | int ksys_umount(char __user *name, int flags); | 1236 | int ksys_umount(char __user *name, int flags); |
1237 | int ksys_dup(unsigned int fildes); | 1237 | int ksys_dup(unsigned int fildes); |
1238 | int ksys_chroot(const char __user *filename); | 1238 | int ksys_chroot(const char __user *filename); |
diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h index 665e18627f78..1274c692e59c 100644 --- a/include/uapi/linux/magic.h +++ b/include/uapi/linux/magic.h | |||
@@ -92,5 +92,6 @@ | |||
92 | #define BALLOON_KVM_MAGIC 0x13661366 | 92 | #define BALLOON_KVM_MAGIC 0x13661366 |
93 | #define ZSMALLOC_MAGIC 0x58295829 | 93 | #define ZSMALLOC_MAGIC 0x58295829 |
94 | #define DMA_BUF_MAGIC 0x444d4142 /* "DMAB" */ | 94 | #define DMA_BUF_MAGIC 0x444d4142 /* "DMAB" */ |
95 | #define Z3FOLD_MAGIC 0x33 | ||
95 | 96 | ||
96 | #endif /* __LINUX_MAGIC_H__ */ | 97 | #endif /* __LINUX_MAGIC_H__ */ |
diff --git a/init/do_mounts.c b/init/do_mounts.c index 2d1ea3028454..53cb37b66227 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -630,41 +630,23 @@ static bool is_tmpfs; | |||
630 | static struct dentry *rootfs_mount(struct file_system_type *fs_type, | 630 | static struct dentry *rootfs_mount(struct file_system_type *fs_type, |
631 | int flags, const char *dev_name, void *data) | 631 | int flags, const char *dev_name, void *data) |
632 | { | 632 | { |
633 | static unsigned long once; | ||
634 | void *fill = ramfs_fill_super; | 633 | void *fill = ramfs_fill_super; |
635 | 634 | ||
636 | if (test_and_set_bit(0, &once)) | ||
637 | return ERR_PTR(-ENODEV); | ||
638 | |||
639 | if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) | 635 | if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) |
640 | fill = shmem_fill_super; | 636 | fill = shmem_fill_super; |
641 | 637 | ||
642 | return mount_nodev(fs_type, flags, data, fill); | 638 | return mount_nodev(fs_type, flags, data, fill); |
643 | } | 639 | } |
644 | 640 | ||
645 | static struct file_system_type rootfs_fs_type = { | 641 | struct file_system_type rootfs_fs_type = { |
646 | .name = "rootfs", | 642 | .name = "rootfs", |
647 | .mount = rootfs_mount, | 643 | .mount = rootfs_mount, |
648 | .kill_sb = kill_litter_super, | 644 | .kill_sb = kill_litter_super, |
649 | }; | 645 | }; |
650 | 646 | ||
651 | int __init init_rootfs(void) | 647 | void __init init_rootfs(void) |
652 | { | 648 | { |
653 | int err = register_filesystem(&rootfs_fs_type); | ||
654 | |||
655 | if (err) | ||
656 | return err; | ||
657 | |||
658 | if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && | 649 | if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && |
659 | (!root_fs_names || strstr(root_fs_names, "tmpfs"))) { | 650 | (!root_fs_names || strstr(root_fs_names, "tmpfs"))) |
660 | err = shmem_init(); | ||
661 | is_tmpfs = true; | 651 | is_tmpfs = true; |
662 | } else { | ||
663 | err = init_ramfs_fs(); | ||
664 | } | ||
665 | |||
666 | if (err) | ||
667 | unregister_filesystem(&rootfs_fs_type); | ||
668 | |||
669 | return err; | ||
670 | } | 652 | } |
diff --git a/init/main.c b/init/main.c index ff5803b0841c..96f8d5af52d6 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -1025,7 +1025,6 @@ static void __init do_initcalls(void) | |||
1025 | static void __init do_basic_setup(void) | 1025 | static void __init do_basic_setup(void) |
1026 | { | 1026 | { |
1027 | cpuset_init_smp(); | 1027 | cpuset_init_smp(); |
1028 | shmem_init(); | ||
1029 | driver_init(); | 1028 | driver_init(); |
1030 | init_irq_proc(); | 1029 | init_irq_proc(); |
1031 | do_ctors(); | 1030 | do_ctors(); |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 65c351564ad0..7a5a8edc3de3 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -364,8 +364,6 @@ static int mqueue_get_tree(struct fs_context *fc) | |||
364 | { | 364 | { |
365 | struct mqueue_fs_context *ctx = fc->fs_private; | 365 | struct mqueue_fs_context *ctx = fc->fs_private; |
366 | 366 | ||
367 | put_user_ns(fc->user_ns); | ||
368 | fc->user_ns = get_user_ns(ctx->ipc_ns->user_ns); | ||
369 | fc->s_fs_info = ctx->ipc_ns; | 367 | fc->s_fs_info = ctx->ipc_ns; |
370 | return vfs_get_super(fc, vfs_get_keyed_super, mqueue_fill_super); | 368 | return vfs_get_super(fc, vfs_get_keyed_super, mqueue_fill_super); |
371 | } | 369 | } |
@@ -374,8 +372,7 @@ static void mqueue_fs_context_free(struct fs_context *fc) | |||
374 | { | 372 | { |
375 | struct mqueue_fs_context *ctx = fc->fs_private; | 373 | struct mqueue_fs_context *ctx = fc->fs_private; |
376 | 374 | ||
377 | if (ctx->ipc_ns) | 375 | put_ipc_ns(ctx->ipc_ns); |
378 | put_ipc_ns(ctx->ipc_ns); | ||
379 | kfree(ctx); | 376 | kfree(ctx); |
380 | } | 377 | } |
381 | 378 | ||
@@ -388,6 +385,8 @@ static int mqueue_init_fs_context(struct fs_context *fc) | |||
388 | return -ENOMEM; | 385 | return -ENOMEM; |
389 | 386 | ||
390 | ctx->ipc_ns = get_ipc_ns(current->nsproxy->ipc_ns); | 387 | ctx->ipc_ns = get_ipc_ns(current->nsproxy->ipc_ns); |
388 | put_user_ns(fc->user_ns); | ||
389 | fc->user_ns = get_user_ns(ctx->ipc_ns->user_ns); | ||
391 | fc->fs_private = ctx; | 390 | fc->fs_private = ctx; |
392 | fc->ops = &mqueue_fs_context_ops; | 391 | fc->ops = &mqueue_fs_context_ops; |
393 | return 0; | 392 | return 0; |
@@ -406,6 +405,8 @@ static struct vfsmount *mq_create_mount(struct ipc_namespace *ns) | |||
406 | ctx = fc->fs_private; | 405 | ctx = fc->fs_private; |
407 | put_ipc_ns(ctx->ipc_ns); | 406 | put_ipc_ns(ctx->ipc_ns); |
408 | ctx->ipc_ns = get_ipc_ns(ns); | 407 | ctx->ipc_ns = get_ipc_ns(ns); |
408 | put_user_ns(fc->user_ns); | ||
409 | fc->user_ns = get_user_ns(ctx->ipc_ns->user_ns); | ||
409 | 410 | ||
410 | mnt = fc_mount(fc); | 411 | mnt = fc_mount(fc); |
411 | put_fs_context(fc); | 412 | put_fs_context(fc); |
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 300b0c416341..753afbca549f 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c | |||
@@ -2201,8 +2201,7 @@ static int cgroup_init_fs_context(struct fs_context *fc) | |||
2201 | fc->ops = &cgroup_fs_context_ops; | 2201 | fc->ops = &cgroup_fs_context_ops; |
2202 | else | 2202 | else |
2203 | fc->ops = &cgroup1_fs_context_ops; | 2203 | fc->ops = &cgroup1_fs_context_ops; |
2204 | if (fc->user_ns) | 2204 | put_user_ns(fc->user_ns); |
2205 | put_user_ns(fc->user_ns); | ||
2206 | fc->user_ns = get_user_ns(ctx->ns->user_ns); | 2205 | fc->user_ns = get_user_ns(ctx->ns->user_ns); |
2207 | fc->global = true; | 2206 | fc->global = true; |
2208 | return 0; | 2207 | return 0; |
@@ -2243,6 +2242,50 @@ static struct file_system_type cgroup2_fs_type = { | |||
2243 | .fs_flags = FS_USERNS_MOUNT, | 2242 | .fs_flags = FS_USERNS_MOUNT, |
2244 | }; | 2243 | }; |
2245 | 2244 | ||
2245 | #ifdef CONFIG_CPUSETS | ||
2246 | static const struct fs_context_operations cpuset_fs_context_ops = { | ||
2247 | .get_tree = cgroup1_get_tree, | ||
2248 | .free = cgroup_fs_context_free, | ||
2249 | }; | ||
2250 | |||
2251 | /* | ||
2252 | * This is ugly, but preserves the userspace API for existing cpuset | ||
2253 | * users. If someone tries to mount the "cpuset" filesystem, we | ||
2254 | * silently switch it to mount "cgroup" instead | ||
2255 | */ | ||
2256 | static int cpuset_init_fs_context(struct fs_context *fc) | ||
2257 | { | ||
2258 | char *agent = kstrdup("/sbin/cpuset_release_agent", GFP_USER); | ||
2259 | struct cgroup_fs_context *ctx; | ||
2260 | int err; | ||
2261 | |||
2262 | err = cgroup_init_fs_context(fc); | ||
2263 | if (err) { | ||
2264 | kfree(agent); | ||
2265 | return err; | ||
2266 | } | ||
2267 | |||
2268 | fc->ops = &cpuset_fs_context_ops; | ||
2269 | |||
2270 | ctx = cgroup_fc2context(fc); | ||
2271 | ctx->subsys_mask = 1 << cpuset_cgrp_id; | ||
2272 | ctx->flags |= CGRP_ROOT_NOPREFIX; | ||
2273 | ctx->release_agent = agent; | ||
2274 | |||
2275 | get_filesystem(&cgroup_fs_type); | ||
2276 | put_filesystem(fc->fs_type); | ||
2277 | fc->fs_type = &cgroup_fs_type; | ||
2278 | |||
2279 | return 0; | ||
2280 | } | ||
2281 | |||
2282 | static struct file_system_type cpuset_fs_type = { | ||
2283 | .name = "cpuset", | ||
2284 | .init_fs_context = cpuset_init_fs_context, | ||
2285 | .fs_flags = FS_USERNS_MOUNT, | ||
2286 | }; | ||
2287 | #endif | ||
2288 | |||
2246 | int cgroup_path_ns_locked(struct cgroup *cgrp, char *buf, size_t buflen, | 2289 | int cgroup_path_ns_locked(struct cgroup *cgrp, char *buf, size_t buflen, |
2247 | struct cgroup_namespace *ns) | 2290 | struct cgroup_namespace *ns) |
2248 | { | 2291 | { |
@@ -5761,6 +5804,9 @@ int __init cgroup_init(void) | |||
5761 | WARN_ON(register_filesystem(&cgroup_fs_type)); | 5804 | WARN_ON(register_filesystem(&cgroup_fs_type)); |
5762 | WARN_ON(register_filesystem(&cgroup2_fs_type)); | 5805 | WARN_ON(register_filesystem(&cgroup2_fs_type)); |
5763 | WARN_ON(!proc_create_single("cgroups", 0, NULL, proc_cgroupstats_show)); | 5806 | WARN_ON(!proc_create_single("cgroups", 0, NULL, proc_cgroupstats_show)); |
5807 | #ifdef CONFIG_CPUSETS | ||
5808 | WARN_ON(register_filesystem(&cpuset_fs_type)); | ||
5809 | #endif | ||
5764 | 5810 | ||
5765 | return 0; | 5811 | return 0; |
5766 | } | 5812 | } |
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 863e434a6020..5aa37531ce76 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c | |||
@@ -356,59 +356,6 @@ static inline bool is_in_v2_mode(void) | |||
356 | } | 356 | } |
357 | 357 | ||
358 | /* | 358 | /* |
359 | * This is ugly, but preserves the userspace API for existing cpuset | ||
360 | * users. If someone tries to mount the "cpuset" filesystem, we | ||
361 | * silently switch it to mount "cgroup" instead | ||
362 | */ | ||
363 | static int cpuset_get_tree(struct fs_context *fc) | ||
364 | { | ||
365 | struct file_system_type *cgroup_fs; | ||
366 | struct fs_context *new_fc; | ||
367 | int ret; | ||
368 | |||
369 | cgroup_fs = get_fs_type("cgroup"); | ||
370 | if (!cgroup_fs) | ||
371 | return -ENODEV; | ||
372 | |||
373 | new_fc = fs_context_for_mount(cgroup_fs, fc->sb_flags); | ||
374 | if (IS_ERR(new_fc)) { | ||
375 | ret = PTR_ERR(new_fc); | ||
376 | } else { | ||
377 | static const char agent_path[] = "/sbin/cpuset_release_agent"; | ||
378 | ret = vfs_parse_fs_string(new_fc, "cpuset", NULL, 0); | ||
379 | if (!ret) | ||
380 | ret = vfs_parse_fs_string(new_fc, "noprefix", NULL, 0); | ||
381 | if (!ret) | ||
382 | ret = vfs_parse_fs_string(new_fc, "release_agent", | ||
383 | agent_path, sizeof(agent_path) - 1); | ||
384 | if (!ret) | ||
385 | ret = vfs_get_tree(new_fc); | ||
386 | if (!ret) { /* steal the result */ | ||
387 | fc->root = new_fc->root; | ||
388 | new_fc->root = NULL; | ||
389 | } | ||
390 | put_fs_context(new_fc); | ||
391 | } | ||
392 | put_filesystem(cgroup_fs); | ||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | static const struct fs_context_operations cpuset_fs_context_ops = { | ||
397 | .get_tree = cpuset_get_tree, | ||
398 | }; | ||
399 | |||
400 | static int cpuset_init_fs_context(struct fs_context *fc) | ||
401 | { | ||
402 | fc->ops = &cpuset_fs_context_ops; | ||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static struct file_system_type cpuset_fs_type = { | ||
407 | .name = "cpuset", | ||
408 | .init_fs_context = cpuset_init_fs_context, | ||
409 | }; | ||
410 | |||
411 | /* | ||
412 | * Return in pmask the portion of a cpusets's cpus_allowed that | 359 | * Return in pmask the portion of a cpusets's cpus_allowed that |
413 | * are online. If none are online, walk up the cpuset hierarchy | 360 | * are online. If none are online, walk up the cpuset hierarchy |
414 | * until we find one that does have some online cpus. | 361 | * until we find one that does have some online cpus. |
@@ -2853,13 +2800,11 @@ struct cgroup_subsys cpuset_cgrp_subsys = { | |||
2853 | /** | 2800 | /** |
2854 | * cpuset_init - initialize cpusets at system boot | 2801 | * cpuset_init - initialize cpusets at system boot |
2855 | * | 2802 | * |
2856 | * Description: Initialize top_cpuset and the cpuset internal file system, | 2803 | * Description: Initialize top_cpuset |
2857 | **/ | 2804 | **/ |
2858 | 2805 | ||
2859 | int __init cpuset_init(void) | 2806 | int __init cpuset_init(void) |
2860 | { | 2807 | { |
2861 | int err = 0; | ||
2862 | |||
2863 | BUG_ON(!alloc_cpumask_var(&top_cpuset.cpus_allowed, GFP_KERNEL)); | 2808 | BUG_ON(!alloc_cpumask_var(&top_cpuset.cpus_allowed, GFP_KERNEL)); |
2864 | BUG_ON(!alloc_cpumask_var(&top_cpuset.effective_cpus, GFP_KERNEL)); | 2809 | BUG_ON(!alloc_cpumask_var(&top_cpuset.effective_cpus, GFP_KERNEL)); |
2865 | BUG_ON(!zalloc_cpumask_var(&top_cpuset.subparts_cpus, GFP_KERNEL)); | 2810 | BUG_ON(!zalloc_cpumask_var(&top_cpuset.subparts_cpus, GFP_KERNEL)); |
@@ -2873,10 +2818,6 @@ int __init cpuset_init(void) | |||
2873 | set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags); | 2818 | set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags); |
2874 | top_cpuset.relax_domain_level = -1; | 2819 | top_cpuset.relax_domain_level = -1; |
2875 | 2820 | ||
2876 | err = register_filesystem(&cpuset_fs_type); | ||
2877 | if (err < 0) | ||
2878 | return err; | ||
2879 | |||
2880 | BUG_ON(!alloc_cpumask_var(&cpus_attach, GFP_KERNEL)); | 2821 | BUG_ON(!alloc_cpumask_var(&cpus_attach, GFP_KERNEL)); |
2881 | 2822 | ||
2882 | return 0; | 2823 | return 0; |
diff --git a/mm/shmem.c b/mm/shmem.c index c88a30919ae5..626d8c74b973 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -3777,10 +3777,6 @@ int __init shmem_init(void) | |||
3777 | { | 3777 | { |
3778 | int error; | 3778 | int error; |
3779 | 3779 | ||
3780 | /* If rootfs called this, don't re-init */ | ||
3781 | if (shmem_inode_cachep) | ||
3782 | return 0; | ||
3783 | |||
3784 | shmem_init_inodecache(); | 3780 | shmem_init_inodecache(); |
3785 | 3781 | ||
3786 | error = register_filesystem(&shmem_fs_type); | 3782 | error = register_filesystem(&shmem_fs_type); |
diff --git a/mm/z3fold.c b/mm/z3fold.c index 6c72b18d8b9c..1a029a7432ee 100644 --- a/mm/z3fold.c +++ b/mm/z3fold.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/atomic.h> | 26 | #include <linux/atomic.h> |
27 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
28 | #include <linux/cpumask.h> | 28 | #include <linux/cpumask.h> |
29 | #include <linux/dcache.h> | ||
30 | #include <linux/list.h> | 29 | #include <linux/list.h> |
31 | #include <linux/mm.h> | 30 | #include <linux/mm.h> |
32 | #include <linux/module.h> | 31 | #include <linux/module.h> |
@@ -36,12 +35,14 @@ | |||
36 | #include <linux/compaction.h> | 35 | #include <linux/compaction.h> |
37 | #include <linux/percpu.h> | 36 | #include <linux/percpu.h> |
38 | #include <linux/mount.h> | 37 | #include <linux/mount.h> |
38 | #include <linux/pseudo_fs.h> | ||
39 | #include <linux/fs.h> | 39 | #include <linux/fs.h> |
40 | #include <linux/preempt.h> | 40 | #include <linux/preempt.h> |
41 | #include <linux/workqueue.h> | 41 | #include <linux/workqueue.h> |
42 | #include <linux/slab.h> | 42 | #include <linux/slab.h> |
43 | #include <linux/spinlock.h> | 43 | #include <linux/spinlock.h> |
44 | #include <linux/zpool.h> | 44 | #include <linux/zpool.h> |
45 | #include <linux/magic.h> | ||
45 | 46 | ||
46 | /* | 47 | /* |
47 | * NCHUNKS_ORDER determines the internal allocation granularity, effectively | 48 | * NCHUNKS_ORDER determines the internal allocation granularity, effectively |
@@ -245,19 +246,14 @@ static inline void free_handle(unsigned long handle) | |||
245 | } | 246 | } |
246 | } | 247 | } |
247 | 248 | ||
248 | static struct dentry *z3fold_do_mount(struct file_system_type *fs_type, | 249 | static int z3fold_init_fs_context(struct fs_context *fc) |
249 | int flags, const char *dev_name, void *data) | ||
250 | { | 250 | { |
251 | static const struct dentry_operations ops = { | 251 | return init_pseudo(fc, Z3FOLD_MAGIC) ? 0 : -ENOMEM; |
252 | .d_dname = simple_dname, | ||
253 | }; | ||
254 | |||
255 | return mount_pseudo(fs_type, "z3fold:", NULL, &ops, 0x33); | ||
256 | } | 252 | } |
257 | 253 | ||
258 | static struct file_system_type z3fold_fs = { | 254 | static struct file_system_type z3fold_fs = { |
259 | .name = "z3fold", | 255 | .name = "z3fold", |
260 | .mount = z3fold_do_mount, | 256 | .init_fs_context = z3fold_init_fs_context, |
261 | .kill_sb = kill_anon_super, | 257 | .kill_sb = kill_anon_super, |
262 | }; | 258 | }; |
263 | 259 | ||
diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index db09eb3669c5..57fbb7ced69f 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/zsmalloc.h> | 52 | #include <linux/zsmalloc.h> |
53 | #include <linux/zpool.h> | 53 | #include <linux/zpool.h> |
54 | #include <linux/mount.h> | 54 | #include <linux/mount.h> |
55 | #include <linux/pseudo_fs.h> | ||
55 | #include <linux/migrate.h> | 56 | #include <linux/migrate.h> |
56 | #include <linux/pagemap.h> | 57 | #include <linux/pagemap.h> |
57 | #include <linux/fs.h> | 58 | #include <linux/fs.h> |
@@ -1798,19 +1799,14 @@ static void lock_zspage(struct zspage *zspage) | |||
1798 | } while ((page = get_next_page(page)) != NULL); | 1799 | } while ((page = get_next_page(page)) != NULL); |
1799 | } | 1800 | } |
1800 | 1801 | ||
1801 | static struct dentry *zs_mount(struct file_system_type *fs_type, | 1802 | static int zs_init_fs_context(struct fs_context *fc) |
1802 | int flags, const char *dev_name, void *data) | ||
1803 | { | 1803 | { |
1804 | static const struct dentry_operations ops = { | 1804 | return init_pseudo(fc, ZSMALLOC_MAGIC) ? 0 : -ENOMEM; |
1805 | .d_dname = simple_dname, | ||
1806 | }; | ||
1807 | |||
1808 | return mount_pseudo(fs_type, "zsmalloc:", NULL, &ops, ZSMALLOC_MAGIC); | ||
1809 | } | 1805 | } |
1810 | 1806 | ||
1811 | static struct file_system_type zsmalloc_fs = { | 1807 | static struct file_system_type zsmalloc_fs = { |
1812 | .name = "zsmalloc", | 1808 | .name = "zsmalloc", |
1813 | .mount = zs_mount, | 1809 | .init_fs_context = zs_init_fs_context, |
1814 | .kill_sb = kill_anon_super, | 1810 | .kill_sb = kill_anon_super, |
1815 | }; | 1811 | }; |
1816 | 1812 | ||
diff --git a/net/socket.c b/net/socket.c index 293d56836f01..6a9ab7a8b1d2 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #include <linux/module.h> | 73 | #include <linux/module.h> |
74 | #include <linux/highmem.h> | 74 | #include <linux/highmem.h> |
75 | #include <linux/mount.h> | 75 | #include <linux/mount.h> |
76 | #include <linux/pseudo_fs.h> | ||
76 | #include <linux/security.h> | 77 | #include <linux/security.h> |
77 | #include <linux/syscalls.h> | 78 | #include <linux/syscalls.h> |
78 | #include <linux/compat.h> | 79 | #include <linux/compat.h> |
@@ -338,19 +339,22 @@ static const struct xattr_handler *sockfs_xattr_handlers[] = { | |||
338 | NULL | 339 | NULL |
339 | }; | 340 | }; |
340 | 341 | ||
341 | static struct dentry *sockfs_mount(struct file_system_type *fs_type, | 342 | static int sockfs_init_fs_context(struct fs_context *fc) |
342 | int flags, const char *dev_name, void *data) | ||
343 | { | 343 | { |
344 | return mount_pseudo_xattr(fs_type, "socket:", &sockfs_ops, | 344 | struct pseudo_fs_context *ctx = init_pseudo(fc, SOCKFS_MAGIC); |
345 | sockfs_xattr_handlers, | 345 | if (!ctx) |
346 | &sockfs_dentry_operations, SOCKFS_MAGIC); | 346 | return -ENOMEM; |
347 | ctx->ops = &sockfs_ops; | ||
348 | ctx->dops = &sockfs_dentry_operations; | ||
349 | ctx->xattr = sockfs_xattr_handlers; | ||
350 | return 0; | ||
347 | } | 351 | } |
348 | 352 | ||
349 | static struct vfsmount *sock_mnt __read_mostly; | 353 | static struct vfsmount *sock_mnt __read_mostly; |
350 | 354 | ||
351 | static struct file_system_type sock_fs_type = { | 355 | static struct file_system_type sock_fs_type = { |
352 | .name = "sockfs", | 356 | .name = "sockfs", |
353 | .mount = sockfs_mount, | 357 | .init_fs_context = sockfs_init_fs_context, |
354 | .kill_sb = kill_anon_super, | 358 | .kill_sb = kill_anon_super, |
355 | }; | 359 | }; |
356 | 360 | ||
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 73bd62979fe7..748bac601e47 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <linux/pagemap.h> | 15 | #include <linux/pagemap.h> |
16 | #include <linux/mount.h> | 16 | #include <linux/mount.h> |
17 | #include <linux/fs_context.h> | ||
17 | #include <linux/namei.h> | 18 | #include <linux/namei.h> |
18 | #include <linux/fsnotify.h> | 19 | #include <linux/fsnotify.h> |
19 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
@@ -1352,11 +1353,11 @@ rpc_gssd_dummy_depopulate(struct dentry *pipe_dentry) | |||
1352 | } | 1353 | } |
1353 | 1354 | ||
1354 | static int | 1355 | static int |
1355 | rpc_fill_super(struct super_block *sb, void *data, int silent) | 1356 | rpc_fill_super(struct super_block *sb, struct fs_context *fc) |
1356 | { | 1357 | { |
1357 | struct inode *inode; | 1358 | struct inode *inode; |
1358 | struct dentry *root, *gssd_dentry; | 1359 | struct dentry *root, *gssd_dentry; |
1359 | struct net *net = get_net(sb->s_fs_info); | 1360 | struct net *net = sb->s_fs_info; |
1360 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | 1361 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); |
1361 | int err; | 1362 | int err; |
1362 | 1363 | ||
@@ -1413,12 +1414,29 @@ gssd_running(struct net *net) | |||
1413 | } | 1414 | } |
1414 | EXPORT_SYMBOL_GPL(gssd_running); | 1415 | EXPORT_SYMBOL_GPL(gssd_running); |
1415 | 1416 | ||
1416 | static struct dentry * | 1417 | static int rpc_fs_get_tree(struct fs_context *fc) |
1417 | rpc_mount(struct file_system_type *fs_type, | 1418 | { |
1418 | int flags, const char *dev_name, void *data) | 1419 | fc->s_fs_info = get_net(fc->net_ns); |
1420 | return vfs_get_super(fc, vfs_get_keyed_super, rpc_fill_super); | ||
1421 | } | ||
1422 | |||
1423 | static void rpc_fs_free_fc(struct fs_context *fc) | ||
1419 | { | 1424 | { |
1420 | struct net *net = current->nsproxy->net_ns; | 1425 | if (fc->s_fs_info) |
1421 | return mount_ns(fs_type, flags, data, net, net->user_ns, rpc_fill_super); | 1426 | put_net(fc->s_fs_info); |
1427 | } | ||
1428 | |||
1429 | static const struct fs_context_operations rpc_fs_context_ops = { | ||
1430 | .free = rpc_fs_free_fc, | ||
1431 | .get_tree = rpc_fs_get_tree, | ||
1432 | }; | ||
1433 | |||
1434 | static int rpc_init_fs_context(struct fs_context *fc) | ||
1435 | { | ||
1436 | put_user_ns(fc->user_ns); | ||
1437 | fc->user_ns = get_user_ns(fc->net_ns->user_ns); | ||
1438 | fc->ops = &rpc_fs_context_ops; | ||
1439 | return 0; | ||
1422 | } | 1440 | } |
1423 | 1441 | ||
1424 | static void rpc_kill_sb(struct super_block *sb) | 1442 | static void rpc_kill_sb(struct super_block *sb) |
@@ -1446,7 +1464,7 @@ out: | |||
1446 | static struct file_system_type rpc_pipe_fs_type = { | 1464 | static struct file_system_type rpc_pipe_fs_type = { |
1447 | .owner = THIS_MODULE, | 1465 | .owner = THIS_MODULE, |
1448 | .name = "rpc_pipefs", | 1466 | .name = "rpc_pipefs", |
1449 | .mount = rpc_mount, | 1467 | .init_fs_context = rpc_init_fs_context, |
1450 | .kill_sb = rpc_kill_sb, | 1468 | .kill_sb = rpc_kill_sb, |
1451 | }; | 1469 | }; |
1452 | MODULE_ALIAS_FS("rpc_pipefs"); | 1470 | MODULE_ALIAS_FS("rpc_pipefs"); |
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index 66d0b4245ef6..45d13b6462aa 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/capability.h> | 19 | #include <linux/capability.h> |
20 | #include <linux/rcupdate.h> | 20 | #include <linux/rcupdate.h> |
21 | #include <linux/fs.h> | 21 | #include <linux/fs.h> |
22 | #include <linux/fs_context.h> | ||
22 | #include <linux/poll.h> | 23 | #include <linux/poll.h> |
23 | #include <uapi/linux/major.h> | 24 | #include <uapi/linux/major.h> |
24 | #include <uapi/linux/magic.h> | 25 | #include <uapi/linux/magic.h> |
@@ -132,7 +133,7 @@ static const struct super_operations aafs_super_ops = { | |||
132 | .show_path = aafs_show_path, | 133 | .show_path = aafs_show_path, |
133 | }; | 134 | }; |
134 | 135 | ||
135 | static int fill_super(struct super_block *sb, void *data, int silent) | 136 | static int apparmorfs_fill_super(struct super_block *sb, struct fs_context *fc) |
136 | { | 137 | { |
137 | static struct tree_descr files[] = { {""} }; | 138 | static struct tree_descr files[] = { {""} }; |
138 | int error; | 139 | int error; |
@@ -145,16 +146,25 @@ static int fill_super(struct super_block *sb, void *data, int silent) | |||
145 | return 0; | 146 | return 0; |
146 | } | 147 | } |
147 | 148 | ||
148 | static struct dentry *aafs_mount(struct file_system_type *fs_type, | 149 | static int apparmorfs_get_tree(struct fs_context *fc) |
149 | int flags, const char *dev_name, void *data) | ||
150 | { | 150 | { |
151 | return mount_single(fs_type, flags, data, fill_super); | 151 | return get_tree_single(fc, apparmorfs_fill_super); |
152 | } | ||
153 | |||
154 | static const struct fs_context_operations apparmorfs_context_ops = { | ||
155 | .get_tree = apparmorfs_get_tree, | ||
156 | }; | ||
157 | |||
158 | static int apparmorfs_init_fs_context(struct fs_context *fc) | ||
159 | { | ||
160 | fc->ops = &apparmorfs_context_ops; | ||
161 | return 0; | ||
152 | } | 162 | } |
153 | 163 | ||
154 | static struct file_system_type aafs_ops = { | 164 | static struct file_system_type aafs_ops = { |
155 | .owner = THIS_MODULE, | 165 | .owner = THIS_MODULE, |
156 | .name = AAFS_NAME, | 166 | .name = AAFS_NAME, |
157 | .mount = aafs_mount, | 167 | .init_fs_context = apparmorfs_init_fs_context, |
158 | .kill_sb = kill_anon_super, | 168 | .kill_sb = kill_anon_super, |
159 | }; | 169 | }; |
160 | 170 | ||
diff --git a/security/inode.c b/security/inode.c index fcff7f08bb1c..6c326939750d 100644 --- a/security/inode.c +++ b/security/inode.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/sysfs.h> | 13 | #include <linux/sysfs.h> |
14 | #include <linux/kobject.h> | 14 | #include <linux/kobject.h> |
15 | #include <linux/fs.h> | 15 | #include <linux/fs.h> |
16 | #include <linux/fs_context.h> | ||
16 | #include <linux/mount.h> | 17 | #include <linux/mount.h> |
17 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
@@ -36,7 +37,7 @@ static const struct super_operations securityfs_super_operations = { | |||
36 | .free_inode = securityfs_free_inode, | 37 | .free_inode = securityfs_free_inode, |
37 | }; | 38 | }; |
38 | 39 | ||
39 | static int fill_super(struct super_block *sb, void *data, int silent) | 40 | static int securityfs_fill_super(struct super_block *sb, struct fs_context *fc) |
40 | { | 41 | { |
41 | static const struct tree_descr files[] = {{""}}; | 42 | static const struct tree_descr files[] = {{""}}; |
42 | int error; | 43 | int error; |
@@ -50,17 +51,25 @@ static int fill_super(struct super_block *sb, void *data, int silent) | |||
50 | return 0; | 51 | return 0; |
51 | } | 52 | } |
52 | 53 | ||
53 | static struct dentry *get_sb(struct file_system_type *fs_type, | 54 | static int securityfs_get_tree(struct fs_context *fc) |
54 | int flags, const char *dev_name, | ||
55 | void *data) | ||
56 | { | 55 | { |
57 | return mount_single(fs_type, flags, data, fill_super); | 56 | return get_tree_single(fc, securityfs_fill_super); |
57 | } | ||
58 | |||
59 | static const struct fs_context_operations securityfs_context_ops = { | ||
60 | .get_tree = securityfs_get_tree, | ||
61 | }; | ||
62 | |||
63 | static int securityfs_init_fs_context(struct fs_context *fc) | ||
64 | { | ||
65 | fc->ops = &securityfs_context_ops; | ||
66 | return 0; | ||
58 | } | 67 | } |
59 | 68 | ||
60 | static struct file_system_type fs_type = { | 69 | static struct file_system_type fs_type = { |
61 | .owner = THIS_MODULE, | 70 | .owner = THIS_MODULE, |
62 | .name = "securityfs", | 71 | .name = "securityfs", |
63 | .mount = get_sb, | 72 | .init_fs_context = securityfs_init_fs_context, |
64 | .kill_sb = kill_litter_super, | 73 | .kill_sb = kill_litter_super, |
65 | }; | 74 | }; |
66 | 75 | ||
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 6f195c7915de..e6c7643c3fc0 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/fs.h> | 19 | #include <linux/fs.h> |
20 | #include <linux/fs_context.h> | ||
20 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
21 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
@@ -1891,7 +1892,7 @@ static struct dentry *sel_make_dir(struct dentry *dir, const char *name, | |||
1891 | 1892 | ||
1892 | #define NULL_FILE_NAME "null" | 1893 | #define NULL_FILE_NAME "null" |
1893 | 1894 | ||
1894 | static int sel_fill_super(struct super_block *sb, void *data, int silent) | 1895 | static int sel_fill_super(struct super_block *sb, struct fs_context *fc) |
1895 | { | 1896 | { |
1896 | struct selinux_fs_info *fsi; | 1897 | struct selinux_fs_info *fsi; |
1897 | int ret; | 1898 | int ret; |
@@ -2007,10 +2008,19 @@ err: | |||
2007 | return ret; | 2008 | return ret; |
2008 | } | 2009 | } |
2009 | 2010 | ||
2010 | static struct dentry *sel_mount(struct file_system_type *fs_type, | 2011 | static int sel_get_tree(struct fs_context *fc) |
2011 | int flags, const char *dev_name, void *data) | ||
2012 | { | 2012 | { |
2013 | return mount_single(fs_type, flags, data, sel_fill_super); | 2013 | return get_tree_single(fc, sel_fill_super); |
2014 | } | ||
2015 | |||
2016 | static const struct fs_context_operations sel_context_ops = { | ||
2017 | .get_tree = sel_get_tree, | ||
2018 | }; | ||
2019 | |||
2020 | static int sel_init_fs_context(struct fs_context *fc) | ||
2021 | { | ||
2022 | fc->ops = &sel_context_ops; | ||
2023 | return 0; | ||
2014 | } | 2024 | } |
2015 | 2025 | ||
2016 | static void sel_kill_sb(struct super_block *sb) | 2026 | static void sel_kill_sb(struct super_block *sb) |
@@ -2021,7 +2031,7 @@ static void sel_kill_sb(struct super_block *sb) | |||
2021 | 2031 | ||
2022 | static struct file_system_type sel_fs_type = { | 2032 | static struct file_system_type sel_fs_type = { |
2023 | .name = "selinuxfs", | 2033 | .name = "selinuxfs", |
2024 | .mount = sel_mount, | 2034 | .init_fs_context = sel_init_fs_context, |
2025 | .kill_sb = sel_kill_sb, | 2035 | .kill_sb = sel_kill_sb, |
2026 | }; | 2036 | }; |
2027 | 2037 | ||
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index ef0d8712d318..e3e05c04dbd1 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/ctype.h> | 23 | #include <linux/ctype.h> |
24 | #include <linux/audit.h> | 24 | #include <linux/audit.h> |
25 | #include <linux/magic.h> | 25 | #include <linux/magic.h> |
26 | #include <linux/fs_context.h> | ||
26 | #include "smack.h" | 27 | #include "smack.h" |
27 | 28 | ||
28 | #define BEBITS (sizeof(__be32) * 8) | 29 | #define BEBITS (sizeof(__be32) * 8) |
@@ -2816,14 +2817,13 @@ static const struct file_operations smk_ptrace_ops = { | |||
2816 | /** | 2817 | /** |
2817 | * smk_fill_super - fill the smackfs superblock | 2818 | * smk_fill_super - fill the smackfs superblock |
2818 | * @sb: the empty superblock | 2819 | * @sb: the empty superblock |
2819 | * @data: unused | 2820 | * @fc: unused |
2820 | * @silent: unused | ||
2821 | * | 2821 | * |
2822 | * Fill in the well known entries for the smack filesystem | 2822 | * Fill in the well known entries for the smack filesystem |
2823 | * | 2823 | * |
2824 | * Returns 0 on success, an error code on failure | 2824 | * Returns 0 on success, an error code on failure |
2825 | */ | 2825 | */ |
2826 | static int smk_fill_super(struct super_block *sb, void *data, int silent) | 2826 | static int smk_fill_super(struct super_block *sb, struct fs_context *fc) |
2827 | { | 2827 | { |
2828 | int rc; | 2828 | int rc; |
2829 | 2829 | ||
@@ -2893,25 +2893,35 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent) | |||
2893 | } | 2893 | } |
2894 | 2894 | ||
2895 | /** | 2895 | /** |
2896 | * smk_mount - get the smackfs superblock | 2896 | * smk_get_tree - get the smackfs superblock |
2897 | * @fs_type: passed along without comment | 2897 | * @fc: The mount context, including any options |
2898 | * @flags: passed along without comment | ||
2899 | * @dev_name: passed along without comment | ||
2900 | * @data: passed along without comment | ||
2901 | * | 2898 | * |
2902 | * Just passes everything along. | 2899 | * Just passes everything along. |
2903 | * | 2900 | * |
2904 | * Returns what the lower level code does. | 2901 | * Returns what the lower level code does. |
2905 | */ | 2902 | */ |
2906 | static struct dentry *smk_mount(struct file_system_type *fs_type, | 2903 | static int smk_get_tree(struct fs_context *fc) |
2907 | int flags, const char *dev_name, void *data) | ||
2908 | { | 2904 | { |
2909 | return mount_single(fs_type, flags, data, smk_fill_super); | 2905 | return get_tree_single(fc, smk_fill_super); |
2906 | } | ||
2907 | |||
2908 | static const struct fs_context_operations smk_context_ops = { | ||
2909 | .get_tree = smk_get_tree, | ||
2910 | }; | ||
2911 | |||
2912 | /** | ||
2913 | * smk_init_fs_context - Initialise a filesystem context for smackfs | ||
2914 | * @fc: The blank mount context | ||
2915 | */ | ||
2916 | static int smk_init_fs_context(struct fs_context *fc) | ||
2917 | { | ||
2918 | fc->ops = &smk_context_ops; | ||
2919 | return 0; | ||
2910 | } | 2920 | } |
2911 | 2921 | ||
2912 | static struct file_system_type smk_fs_type = { | 2922 | static struct file_system_type smk_fs_type = { |
2913 | .name = "smackfs", | 2923 | .name = "smackfs", |
2914 | .mount = smk_mount, | 2924 | .init_fs_context = smk_init_fs_context, |
2915 | .kill_sb = kill_litter_super, | 2925 | .kill_sb = kill_litter_super, |
2916 | }; | 2926 | }; |
2917 | 2927 | ||