diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-24 15:33:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-24 15:33:34 -0400 |
commit | 0b36c9eed232760fbf51921818f48b3699f1f1ca (patch) | |
tree | 1392ebcd076e87f7c80cd93e29db7acbee542071 | |
parent | 722e6f500ac72d0d43955710738a24fd957607a4 (diff) | |
parent | 1f52aa08d12f8d359e71b4bfd73ca9d5d668e4da (diff) |
Merge branch 'work.mount3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull more mount API conversions from Al Viro:
"Assorted conversions of options parsing to new API.
gfs2 is probably the most serious one here; the rest is trivial stuff.
Other things in what used to be #work.mount are going to wait for the
next cycle (and preferably go via git trees of the filesystems
involved)"
* 'work.mount3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
gfs2: Convert gfs2 to fs_context
vfs: Convert spufs to use the new mount API
vfs: Convert hypfs to use the new mount API
hypfs: Fix error number left in struct pointer member
vfs: Convert functionfs to use the new mount API
vfs: Convert bpf to use the new mount API
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/inode.c | 207 | ||||
-rw-r--r-- | arch/s390/hypfs/inode.c | 137 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 233 | ||||
-rw-r--r-- | fs/gfs2/incore.h | 8 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 495 | ||||
-rw-r--r-- | fs/gfs2/super.c | 333 | ||||
-rw-r--r-- | fs/gfs2/super.h | 3 | ||||
-rw-r--r-- | kernel/bpf/inode.c | 92 |
8 files changed, 749 insertions, 759 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 065ff14b76e1..1d93e55a2de1 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -10,6 +10,8 @@ | |||
10 | 10 | ||
11 | #include <linux/file.h> | 11 | #include <linux/file.h> |
12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
13 | #include <linux/fs_context.h> | ||
14 | #include <linux/fs_parser.h> | ||
13 | #include <linux/fsnotify.h> | 15 | #include <linux/fsnotify.h> |
14 | #include <linux/backing-dev.h> | 16 | #include <linux/backing-dev.h> |
15 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -20,7 +22,6 @@ | |||
20 | #include <linux/pagemap.h> | 22 | #include <linux/pagemap.h> |
21 | #include <linux/poll.h> | 23 | #include <linux/poll.h> |
22 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
23 | #include <linux/parser.h> | ||
24 | 25 | ||
25 | #include <asm/prom.h> | 26 | #include <asm/prom.h> |
26 | #include <asm/spu.h> | 27 | #include <asm/spu.h> |
@@ -30,7 +31,7 @@ | |||
30 | #include "spufs.h" | 31 | #include "spufs.h" |
31 | 32 | ||
32 | struct spufs_sb_info { | 33 | struct spufs_sb_info { |
33 | int debug; | 34 | bool debug; |
34 | }; | 35 | }; |
35 | 36 | ||
36 | static struct kmem_cache *spufs_inode_cache; | 37 | static struct kmem_cache *spufs_inode_cache; |
@@ -574,16 +575,27 @@ long spufs_create(struct path *path, struct dentry *dentry, | |||
574 | } | 575 | } |
575 | 576 | ||
576 | /* File system initialization */ | 577 | /* File system initialization */ |
578 | struct spufs_fs_context { | ||
579 | kuid_t uid; | ||
580 | kgid_t gid; | ||
581 | umode_t mode; | ||
582 | }; | ||
583 | |||
577 | enum { | 584 | enum { |
578 | Opt_uid, Opt_gid, Opt_mode, Opt_debug, Opt_err, | 585 | Opt_uid, Opt_gid, Opt_mode, Opt_debug, |
586 | }; | ||
587 | |||
588 | static const struct fs_parameter_spec spufs_param_specs[] = { | ||
589 | fsparam_u32 ("gid", Opt_gid), | ||
590 | fsparam_u32oct ("mode", Opt_mode), | ||
591 | fsparam_u32 ("uid", Opt_uid), | ||
592 | fsparam_flag ("debug", Opt_debug), | ||
593 | {} | ||
579 | }; | 594 | }; |
580 | 595 | ||
581 | static const match_table_t spufs_tokens = { | 596 | static const struct fs_parameter_description spufs_fs_parameters = { |
582 | { Opt_uid, "uid=%d" }, | 597 | .name = "spufs", |
583 | { Opt_gid, "gid=%d" }, | 598 | .specs = spufs_param_specs, |
584 | { Opt_mode, "mode=%o" }, | ||
585 | { Opt_debug, "debug" }, | ||
586 | { Opt_err, NULL }, | ||
587 | }; | 599 | }; |
588 | 600 | ||
589 | static int spufs_show_options(struct seq_file *m, struct dentry *root) | 601 | static int spufs_show_options(struct seq_file *m, struct dentry *root) |
@@ -604,47 +616,41 @@ static int spufs_show_options(struct seq_file *m, struct dentry *root) | |||
604 | return 0; | 616 | return 0; |
605 | } | 617 | } |
606 | 618 | ||
607 | static int | 619 | static int spufs_parse_param(struct fs_context *fc, struct fs_parameter *param) |
608 | spufs_parse_options(struct super_block *sb, char *options, struct inode *root) | 620 | { |
609 | { | 621 | struct spufs_fs_context *ctx = fc->fs_private; |
610 | char *p; | 622 | struct spufs_sb_info *sbi = fc->s_fs_info; |
611 | substring_t args[MAX_OPT_ARGS]; | 623 | struct fs_parse_result result; |
612 | 624 | kuid_t uid; | |
613 | while ((p = strsep(&options, ",")) != NULL) { | 625 | kgid_t gid; |
614 | int token, option; | 626 | int opt; |
615 | 627 | ||
616 | if (!*p) | 628 | opt = fs_parse(fc, &spufs_fs_parameters, param, &result); |
617 | continue; | 629 | if (opt < 0) |
618 | 630 | return opt; | |
619 | token = match_token(p, spufs_tokens, args); | 631 | |
620 | switch (token) { | 632 | switch (opt) { |
621 | case Opt_uid: | 633 | case Opt_uid: |
622 | if (match_int(&args[0], &option)) | 634 | uid = make_kuid(current_user_ns(), result.uint_32); |
623 | return 0; | 635 | if (!uid_valid(uid)) |
624 | root->i_uid = make_kuid(current_user_ns(), option); | 636 | return invalf(fc, "Unknown uid"); |
625 | if (!uid_valid(root->i_uid)) | 637 | ctx->uid = uid; |
626 | return 0; | 638 | break; |
627 | break; | 639 | case Opt_gid: |
628 | case Opt_gid: | 640 | gid = make_kgid(current_user_ns(), result.uint_32); |
629 | if (match_int(&args[0], &option)) | 641 | if (!gid_valid(gid)) |
630 | return 0; | 642 | return invalf(fc, "Unknown gid"); |
631 | root->i_gid = make_kgid(current_user_ns(), option); | 643 | ctx->gid = gid; |
632 | if (!gid_valid(root->i_gid)) | 644 | break; |
633 | return 0; | 645 | case Opt_mode: |
634 | break; | 646 | ctx->mode = result.uint_32 & S_IALLUGO; |
635 | case Opt_mode: | 647 | break; |
636 | if (match_octal(&args[0], &option)) | 648 | case Opt_debug: |
637 | return 0; | 649 | sbi->debug = true; |
638 | root->i_mode = option | S_IFDIR; | 650 | break; |
639 | break; | ||
640 | case Opt_debug: | ||
641 | spufs_get_sb_info(sb)->debug = 1; | ||
642 | break; | ||
643 | default: | ||
644 | return 0; | ||
645 | } | ||
646 | } | 651 | } |
647 | return 1; | 652 | |
653 | return 0; | ||
648 | } | 654 | } |
649 | 655 | ||
650 | static void spufs_exit_isolated_loader(void) | 656 | static void spufs_exit_isolated_loader(void) |
@@ -678,79 +684,98 @@ spufs_init_isolated_loader(void) | |||
678 | printk(KERN_INFO "spufs: SPU isolation mode enabled\n"); | 684 | printk(KERN_INFO "spufs: SPU isolation mode enabled\n"); |
679 | } | 685 | } |
680 | 686 | ||
681 | static int | 687 | static int spufs_create_root(struct super_block *sb, struct fs_context *fc) |
682 | spufs_create_root(struct super_block *sb, void *data) | ||
683 | { | 688 | { |
689 | struct spufs_fs_context *ctx = fc->fs_private; | ||
684 | struct inode *inode; | 690 | struct inode *inode; |
685 | int ret; | ||
686 | 691 | ||
687 | ret = -ENODEV; | ||
688 | if (!spu_management_ops) | 692 | if (!spu_management_ops) |
689 | goto out; | 693 | return -ENODEV; |
690 | 694 | ||
691 | ret = -ENOMEM; | 695 | inode = spufs_new_inode(sb, S_IFDIR | ctx->mode); |
692 | inode = spufs_new_inode(sb, S_IFDIR | 0775); | ||
693 | if (!inode) | 696 | if (!inode) |
694 | goto out; | 697 | return -ENOMEM; |
695 | 698 | ||
699 | inode->i_uid = ctx->uid; | ||
700 | inode->i_gid = ctx->gid; | ||
696 | inode->i_op = &simple_dir_inode_operations; | 701 | inode->i_op = &simple_dir_inode_operations; |
697 | inode->i_fop = &simple_dir_operations; | 702 | inode->i_fop = &simple_dir_operations; |
698 | SPUFS_I(inode)->i_ctx = NULL; | 703 | SPUFS_I(inode)->i_ctx = NULL; |
699 | inc_nlink(inode); | 704 | inc_nlink(inode); |
700 | 705 | ||
701 | ret = -EINVAL; | ||
702 | if (!spufs_parse_options(sb, data, inode)) | ||
703 | goto out_iput; | ||
704 | |||
705 | ret = -ENOMEM; | ||
706 | sb->s_root = d_make_root(inode); | 706 | sb->s_root = d_make_root(inode); |
707 | if (!sb->s_root) | 707 | if (!sb->s_root) |
708 | goto out; | 708 | return -ENOMEM; |
709 | |||
710 | return 0; | 709 | return 0; |
711 | out_iput: | ||
712 | iput(inode); | ||
713 | out: | ||
714 | return ret; | ||
715 | } | 710 | } |
716 | 711 | ||
717 | static int | 712 | static const struct super_operations spufs_ops = { |
718 | spufs_fill_super(struct super_block *sb, void *data, int silent) | 713 | .alloc_inode = spufs_alloc_inode, |
719 | { | 714 | .free_inode = spufs_free_inode, |
720 | struct spufs_sb_info *info; | 715 | .statfs = simple_statfs, |
721 | static const struct super_operations s_ops = { | 716 | .evict_inode = spufs_evict_inode, |
722 | .alloc_inode = spufs_alloc_inode, | 717 | .show_options = spufs_show_options, |
723 | .free_inode = spufs_free_inode, | 718 | }; |
724 | .statfs = simple_statfs, | ||
725 | .evict_inode = spufs_evict_inode, | ||
726 | .show_options = spufs_show_options, | ||
727 | }; | ||
728 | |||
729 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
730 | if (!info) | ||
731 | return -ENOMEM; | ||
732 | 719 | ||
720 | static int spufs_fill_super(struct super_block *sb, struct fs_context *fc) | ||
721 | { | ||
733 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 722 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
734 | sb->s_blocksize = PAGE_SIZE; | 723 | sb->s_blocksize = PAGE_SIZE; |
735 | sb->s_blocksize_bits = PAGE_SHIFT; | 724 | sb->s_blocksize_bits = PAGE_SHIFT; |
736 | sb->s_magic = SPUFS_MAGIC; | 725 | sb->s_magic = SPUFS_MAGIC; |
737 | sb->s_op = &s_ops; | 726 | sb->s_op = &spufs_ops; |
738 | sb->s_fs_info = info; | ||
739 | 727 | ||
740 | return spufs_create_root(sb, data); | 728 | return spufs_create_root(sb, fc); |
729 | } | ||
730 | |||
731 | static int spufs_get_tree(struct fs_context *fc) | ||
732 | { | ||
733 | return get_tree_single(fc, spufs_fill_super); | ||
741 | } | 734 | } |
742 | 735 | ||
743 | static struct dentry * | 736 | static void spufs_free_fc(struct fs_context *fc) |
744 | spufs_mount(struct file_system_type *fstype, int flags, | ||
745 | const char *name, void *data) | ||
746 | { | 737 | { |
747 | return mount_single(fstype, flags, data, spufs_fill_super); | 738 | kfree(fc->s_fs_info); |
739 | } | ||
740 | |||
741 | static const struct fs_context_operations spufs_context_ops = { | ||
742 | .free = spufs_free_fc, | ||
743 | .parse_param = spufs_parse_param, | ||
744 | .get_tree = spufs_get_tree, | ||
745 | }; | ||
746 | |||
747 | static int spufs_init_fs_context(struct fs_context *fc) | ||
748 | { | ||
749 | struct spufs_fs_context *ctx; | ||
750 | struct spufs_sb_info *sbi; | ||
751 | |||
752 | ctx = kzalloc(sizeof(struct spufs_fs_context), GFP_KERNEL); | ||
753 | if (!ctx) | ||
754 | goto nomem; | ||
755 | |||
756 | sbi = kzalloc(sizeof(struct spufs_sb_info), GFP_KERNEL); | ||
757 | if (!sbi) | ||
758 | goto nomem_ctx; | ||
759 | |||
760 | ctx->uid = current_uid(); | ||
761 | ctx->gid = current_gid(); | ||
762 | ctx->mode = 0755; | ||
763 | |||
764 | fc->s_fs_info = sbi; | ||
765 | fc->ops = &spufs_context_ops; | ||
766 | return 0; | ||
767 | |||
768 | nomem_ctx: | ||
769 | kfree(ctx); | ||
770 | nomem: | ||
771 | return -ENOMEM; | ||
748 | } | 772 | } |
749 | 773 | ||
750 | static struct file_system_type spufs_type = { | 774 | static struct file_system_type spufs_type = { |
751 | .owner = THIS_MODULE, | 775 | .owner = THIS_MODULE, |
752 | .name = "spufs", | 776 | .name = "spufs", |
753 | .mount = spufs_mount, | 777 | .init_fs_context = spufs_init_fs_context, |
778 | .parameters = &spufs_fs_parameters, | ||
754 | .kill_sb = kill_litter_super, | 779 | .kill_sb = kill_litter_super, |
755 | }; | 780 | }; |
756 | MODULE_ALIAS_FS("spufs"); | 781 | MODULE_ALIAS_FS("spufs"); |
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index a4418fc425b8..70139d0791b6 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
@@ -12,17 +12,17 @@ | |||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/fs_context.h> | ||
16 | #include <linux/fs_parser.h> | ||
15 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
16 | #include <linux/vfs.h> | 18 | #include <linux/vfs.h> |
17 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
18 | #include <linux/pagemap.h> | 20 | #include <linux/pagemap.h> |
19 | #include <linux/time.h> | 21 | #include <linux/time.h> |
20 | #include <linux/parser.h> | ||
21 | #include <linux/sysfs.h> | 22 | #include <linux/sysfs.h> |
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
23 | #include <linux/kobject.h> | 24 | #include <linux/kobject.h> |
24 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
25 | #include <linux/mount.h> | ||
26 | #include <linux/uio.h> | 26 | #include <linux/uio.h> |
27 | #include <asm/ebcdic.h> | 27 | #include <asm/ebcdic.h> |
28 | #include "hypfs.h" | 28 | #include "hypfs.h" |
@@ -207,52 +207,44 @@ static int hypfs_release(struct inode *inode, struct file *filp) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | enum { opt_uid, opt_gid, opt_err }; | 210 | enum { Opt_uid, Opt_gid, }; |
211 | 211 | ||
212 | static const match_table_t hypfs_tokens = { | 212 | static const struct fs_parameter_spec hypfs_param_specs[] = { |
213 | {opt_uid, "uid=%u"}, | 213 | fsparam_u32("gid", Opt_gid), |
214 | {opt_gid, "gid=%u"}, | 214 | fsparam_u32("uid", Opt_uid), |
215 | {opt_err, NULL} | 215 | {} |
216 | }; | 216 | }; |
217 | 217 | ||
218 | static int hypfs_parse_options(char *options, struct super_block *sb) | 218 | static const struct fs_parameter_description hypfs_fs_parameters = { |
219 | .name = "hypfs", | ||
220 | .specs = hypfs_param_specs, | ||
221 | }; | ||
222 | |||
223 | static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param) | ||
219 | { | 224 | { |
220 | char *str; | 225 | struct hypfs_sb_info *hypfs_info = fc->s_fs_info; |
221 | substring_t args[MAX_OPT_ARGS]; | 226 | struct fs_parse_result result; |
222 | kuid_t uid; | 227 | kuid_t uid; |
223 | kgid_t gid; | 228 | kgid_t gid; |
224 | 229 | int opt; | |
225 | if (!options) | 230 | |
226 | return 0; | 231 | opt = fs_parse(fc, &hypfs_fs_parameters, param, &result); |
227 | while ((str = strsep(&options, ",")) != NULL) { | 232 | if (opt < 0) |
228 | int token, option; | 233 | return opt; |
229 | struct hypfs_sb_info *hypfs_info = sb->s_fs_info; | 234 | |
230 | 235 | switch (opt) { | |
231 | if (!*str) | 236 | case Opt_uid: |
232 | continue; | 237 | uid = make_kuid(current_user_ns(), result.uint_32); |
233 | token = match_token(str, hypfs_tokens, args); | 238 | if (!uid_valid(uid)) |
234 | switch (token) { | 239 | return invalf(fc, "Unknown uid"); |
235 | case opt_uid: | 240 | hypfs_info->uid = uid; |
236 | if (match_int(&args[0], &option)) | 241 | break; |
237 | return -EINVAL; | 242 | case Opt_gid: |
238 | uid = make_kuid(current_user_ns(), option); | 243 | gid = make_kgid(current_user_ns(), result.uint_32); |
239 | if (!uid_valid(uid)) | 244 | if (!gid_valid(gid)) |
240 | return -EINVAL; | 245 | return invalf(fc, "Unknown gid"); |
241 | hypfs_info->uid = uid; | 246 | hypfs_info->gid = gid; |
242 | break; | 247 | break; |
243 | case opt_gid: | ||
244 | if (match_int(&args[0], &option)) | ||
245 | return -EINVAL; | ||
246 | gid = make_kgid(current_user_ns(), option); | ||
247 | if (!gid_valid(gid)) | ||
248 | return -EINVAL; | ||
249 | hypfs_info->gid = gid; | ||
250 | break; | ||
251 | case opt_err: | ||
252 | default: | ||
253 | pr_err("%s is not a valid mount option\n", str); | ||
254 | return -EINVAL; | ||
255 | } | ||
256 | } | 248 | } |
257 | return 0; | 249 | return 0; |
258 | } | 250 | } |
@@ -266,26 +258,18 @@ static int hypfs_show_options(struct seq_file *s, struct dentry *root) | |||
266 | return 0; | 258 | return 0; |
267 | } | 259 | } |
268 | 260 | ||
269 | static int hypfs_fill_super(struct super_block *sb, void *data, int silent) | 261 | static int hypfs_fill_super(struct super_block *sb, struct fs_context *fc) |
270 | { | 262 | { |
263 | struct hypfs_sb_info *sbi = sb->s_fs_info; | ||
271 | struct inode *root_inode; | 264 | struct inode *root_inode; |
272 | struct dentry *root_dentry; | 265 | struct dentry *root_dentry, *update_file; |
273 | int rc = 0; | 266 | int rc; |
274 | struct hypfs_sb_info *sbi; | ||
275 | 267 | ||
276 | sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL); | ||
277 | if (!sbi) | ||
278 | return -ENOMEM; | ||
279 | mutex_init(&sbi->lock); | ||
280 | sbi->uid = current_uid(); | ||
281 | sbi->gid = current_gid(); | ||
282 | sb->s_fs_info = sbi; | ||
283 | sb->s_blocksize = PAGE_SIZE; | 268 | sb->s_blocksize = PAGE_SIZE; |
284 | sb->s_blocksize_bits = PAGE_SHIFT; | 269 | sb->s_blocksize_bits = PAGE_SHIFT; |
285 | sb->s_magic = HYPFS_MAGIC; | 270 | sb->s_magic = HYPFS_MAGIC; |
286 | sb->s_op = &hypfs_s_ops; | 271 | sb->s_op = &hypfs_s_ops; |
287 | if (hypfs_parse_options(data, sb)) | 272 | |
288 | return -EINVAL; | ||
289 | root_inode = hypfs_make_inode(sb, S_IFDIR | 0755); | 273 | root_inode = hypfs_make_inode(sb, S_IFDIR | 0755); |
290 | if (!root_inode) | 274 | if (!root_inode) |
291 | return -ENOMEM; | 275 | return -ENOMEM; |
@@ -300,18 +284,46 @@ static int hypfs_fill_super(struct super_block *sb, void *data, int silent) | |||
300 | rc = hypfs_diag_create_files(root_dentry); | 284 | rc = hypfs_diag_create_files(root_dentry); |
301 | if (rc) | 285 | if (rc) |
302 | return rc; | 286 | return rc; |
303 | sbi->update_file = hypfs_create_update_file(root_dentry); | 287 | update_file = hypfs_create_update_file(root_dentry); |
304 | if (IS_ERR(sbi->update_file)) | 288 | if (IS_ERR(update_file)) |
305 | return PTR_ERR(sbi->update_file); | 289 | return PTR_ERR(update_file); |
290 | sbi->update_file = update_file; | ||
306 | hypfs_update_update(sb); | 291 | hypfs_update_update(sb); |
307 | pr_info("Hypervisor filesystem mounted\n"); | 292 | pr_info("Hypervisor filesystem mounted\n"); |
308 | return 0; | 293 | return 0; |
309 | } | 294 | } |
310 | 295 | ||
311 | static struct dentry *hypfs_mount(struct file_system_type *fst, int flags, | 296 | static int hypfs_get_tree(struct fs_context *fc) |
312 | const char *devname, void *data) | 297 | { |
298 | return get_tree_single(fc, hypfs_fill_super); | ||
299 | } | ||
300 | |||
301 | static void hypfs_free_fc(struct fs_context *fc) | ||
313 | { | 302 | { |
314 | return mount_single(fst, flags, data, hypfs_fill_super); | 303 | kfree(fc->s_fs_info); |
304 | } | ||
305 | |||
306 | static const struct fs_context_operations hypfs_context_ops = { | ||
307 | .free = hypfs_free_fc, | ||
308 | .parse_param = hypfs_parse_param, | ||
309 | .get_tree = hypfs_get_tree, | ||
310 | }; | ||
311 | |||
312 | static int hypfs_init_fs_context(struct fs_context *fc) | ||
313 | { | ||
314 | struct hypfs_sb_info *sbi; | ||
315 | |||
316 | sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL); | ||
317 | if (!sbi) | ||
318 | return -ENOMEM; | ||
319 | |||
320 | mutex_init(&sbi->lock); | ||
321 | sbi->uid = current_uid(); | ||
322 | sbi->gid = current_gid(); | ||
323 | |||
324 | fc->s_fs_info = sbi; | ||
325 | fc->ops = &hypfs_context_ops; | ||
326 | return 0; | ||
315 | } | 327 | } |
316 | 328 | ||
317 | static void hypfs_kill_super(struct super_block *sb) | 329 | static void hypfs_kill_super(struct super_block *sb) |
@@ -442,7 +454,8 @@ static const struct file_operations hypfs_file_ops = { | |||
442 | static struct file_system_type hypfs_type = { | 454 | static struct file_system_type hypfs_type = { |
443 | .owner = THIS_MODULE, | 455 | .owner = THIS_MODULE, |
444 | .name = "s390_hypfs", | 456 | .name = "s390_hypfs", |
445 | .mount = hypfs_mount, | 457 | .init_fs_context = hypfs_init_fs_context, |
458 | .parameters = &hypfs_fs_parameters, | ||
446 | .kill_sb = hypfs_kill_super | 459 | .kill_sb = hypfs_kill_super |
447 | }; | 460 | }; |
448 | 461 | ||
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 213ff03c8a9f..59d9d512dcda 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/blkdev.h> | 17 | #include <linux/blkdev.h> |
18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
19 | #include <linux/export.h> | 19 | #include <linux/export.h> |
20 | #include <linux/fs_parser.h> | ||
20 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
21 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
@@ -1451,9 +1452,9 @@ struct ffs_sb_fill_data { | |||
1451 | struct ffs_data *ffs_data; | 1452 | struct ffs_data *ffs_data; |
1452 | }; | 1453 | }; |
1453 | 1454 | ||
1454 | static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) | 1455 | static int ffs_sb_fill(struct super_block *sb, struct fs_context *fc) |
1455 | { | 1456 | { |
1456 | struct ffs_sb_fill_data *data = _data; | 1457 | struct ffs_sb_fill_data *data = fc->fs_private; |
1457 | struct inode *inode; | 1458 | struct inode *inode; |
1458 | struct ffs_data *ffs = data->ffs_data; | 1459 | struct ffs_data *ffs = data->ffs_data; |
1459 | 1460 | ||
@@ -1486,147 +1487,152 @@ static int ffs_sb_fill(struct super_block *sb, void *_data, int silent) | |||
1486 | return 0; | 1487 | return 0; |
1487 | } | 1488 | } |
1488 | 1489 | ||
1489 | static int ffs_fs_parse_opts(struct ffs_sb_fill_data *data, char *opts) | 1490 | enum { |
1490 | { | 1491 | Opt_no_disconnect, |
1491 | ENTER(); | 1492 | Opt_rmode, |
1493 | Opt_fmode, | ||
1494 | Opt_mode, | ||
1495 | Opt_uid, | ||
1496 | Opt_gid, | ||
1497 | }; | ||
1492 | 1498 | ||
1493 | if (!opts || !*opts) | 1499 | static const struct fs_parameter_spec ffs_fs_param_specs[] = { |
1494 | return 0; | 1500 | fsparam_bool ("no_disconnect", Opt_no_disconnect), |
1501 | fsparam_u32 ("rmode", Opt_rmode), | ||
1502 | fsparam_u32 ("fmode", Opt_fmode), | ||
1503 | fsparam_u32 ("mode", Opt_mode), | ||
1504 | fsparam_u32 ("uid", Opt_uid), | ||
1505 | fsparam_u32 ("gid", Opt_gid), | ||
1506 | {} | ||
1507 | }; | ||
1495 | 1508 | ||
1496 | for (;;) { | 1509 | static const struct fs_parameter_description ffs_fs_fs_parameters = { |
1497 | unsigned long value; | 1510 | .name = "kAFS", |
1498 | char *eq, *comma; | 1511 | .specs = ffs_fs_param_specs, |
1499 | 1512 | }; | |
1500 | /* Option limit */ | ||
1501 | comma = strchr(opts, ','); | ||
1502 | if (comma) | ||
1503 | *comma = 0; | ||
1504 | |||
1505 | /* Value limit */ | ||
1506 | eq = strchr(opts, '='); | ||
1507 | if (unlikely(!eq)) { | ||
1508 | pr_err("'=' missing in %s\n", opts); | ||
1509 | return -EINVAL; | ||
1510 | } | ||
1511 | *eq = 0; | ||
1512 | 1513 | ||
1513 | /* Parse value */ | 1514 | static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param) |
1514 | if (kstrtoul(eq + 1, 0, &value)) { | 1515 | { |
1515 | pr_err("%s: invalid value: %s\n", opts, eq + 1); | 1516 | struct ffs_sb_fill_data *data = fc->fs_private; |
1516 | return -EINVAL; | 1517 | struct fs_parse_result result; |
1517 | } | 1518 | int opt; |
1518 | 1519 | ||
1519 | /* Interpret option */ | 1520 | ENTER(); |
1520 | switch (eq - opts) { | ||
1521 | case 13: | ||
1522 | if (!memcmp(opts, "no_disconnect", 13)) | ||
1523 | data->no_disconnect = !!value; | ||
1524 | else | ||
1525 | goto invalid; | ||
1526 | break; | ||
1527 | case 5: | ||
1528 | if (!memcmp(opts, "rmode", 5)) | ||
1529 | data->root_mode = (value & 0555) | S_IFDIR; | ||
1530 | else if (!memcmp(opts, "fmode", 5)) | ||
1531 | data->perms.mode = (value & 0666) | S_IFREG; | ||
1532 | else | ||
1533 | goto invalid; | ||
1534 | break; | ||
1535 | 1521 | ||
1536 | case 4: | 1522 | opt = fs_parse(fc, &ffs_fs_fs_parameters, param, &result); |
1537 | if (!memcmp(opts, "mode", 4)) { | 1523 | if (opt < 0) |
1538 | data->root_mode = (value & 0555) | S_IFDIR; | 1524 | return opt; |
1539 | data->perms.mode = (value & 0666) | S_IFREG; | ||
1540 | } else { | ||
1541 | goto invalid; | ||
1542 | } | ||
1543 | break; | ||
1544 | 1525 | ||
1545 | case 3: | 1526 | switch (opt) { |
1546 | if (!memcmp(opts, "uid", 3)) { | 1527 | case Opt_no_disconnect: |
1547 | data->perms.uid = make_kuid(current_user_ns(), value); | 1528 | data->no_disconnect = result.boolean; |
1548 | if (!uid_valid(data->perms.uid)) { | 1529 | break; |
1549 | pr_err("%s: unmapped value: %lu\n", opts, value); | 1530 | case Opt_rmode: |
1550 | return -EINVAL; | 1531 | data->root_mode = (result.uint_32 & 0555) | S_IFDIR; |
1551 | } | 1532 | break; |
1552 | } else if (!memcmp(opts, "gid", 3)) { | 1533 | case Opt_fmode: |
1553 | data->perms.gid = make_kgid(current_user_ns(), value); | 1534 | data->perms.mode = (result.uint_32 & 0666) | S_IFREG; |
1554 | if (!gid_valid(data->perms.gid)) { | 1535 | break; |
1555 | pr_err("%s: unmapped value: %lu\n", opts, value); | 1536 | case Opt_mode: |
1556 | return -EINVAL; | 1537 | data->root_mode = (result.uint_32 & 0555) | S_IFDIR; |
1557 | } | 1538 | data->perms.mode = (result.uint_32 & 0666) | S_IFREG; |
1558 | } else { | 1539 | break; |
1559 | goto invalid; | ||
1560 | } | ||
1561 | break; | ||
1562 | 1540 | ||
1563 | default: | 1541 | case Opt_uid: |
1564 | invalid: | 1542 | data->perms.uid = make_kuid(current_user_ns(), result.uint_32); |
1565 | pr_err("%s: invalid option\n", opts); | 1543 | if (!uid_valid(data->perms.uid)) |
1566 | return -EINVAL; | 1544 | goto unmapped_value; |
1567 | } | 1545 | break; |
1546 | case Opt_gid: | ||
1547 | data->perms.gid = make_kgid(current_user_ns(), result.uint_32); | ||
1548 | if (!gid_valid(data->perms.gid)) | ||
1549 | goto unmapped_value; | ||
1550 | break; | ||
1568 | 1551 | ||
1569 | /* Next iteration */ | 1552 | default: |
1570 | if (!comma) | 1553 | return -ENOPARAM; |
1571 | break; | ||
1572 | opts = comma + 1; | ||
1573 | } | 1554 | } |
1574 | 1555 | ||
1575 | return 0; | 1556 | return 0; |
1576 | } | ||
1577 | 1557 | ||
1578 | /* "mount -t functionfs dev_name /dev/function" ends up here */ | 1558 | unmapped_value: |
1559 | return invalf(fc, "%s: unmapped value: %u", param->key, result.uint_32); | ||
1560 | } | ||
1579 | 1561 | ||
1580 | static struct dentry * | 1562 | /* |
1581 | ffs_fs_mount(struct file_system_type *t, int flags, | 1563 | * Set up the superblock for a mount. |
1582 | const char *dev_name, void *opts) | 1564 | */ |
1583 | { | 1565 | static int ffs_fs_get_tree(struct fs_context *fc) |
1584 | struct ffs_sb_fill_data data = { | 1566 | { |
1585 | .perms = { | 1567 | struct ffs_sb_fill_data *ctx = fc->fs_private; |
1586 | .mode = S_IFREG | 0600, | ||
1587 | .uid = GLOBAL_ROOT_UID, | ||
1588 | .gid = GLOBAL_ROOT_GID, | ||
1589 | }, | ||
1590 | .root_mode = S_IFDIR | 0500, | ||
1591 | .no_disconnect = false, | ||
1592 | }; | ||
1593 | struct dentry *rv; | ||
1594 | int ret; | ||
1595 | void *ffs_dev; | 1568 | void *ffs_dev; |
1596 | struct ffs_data *ffs; | 1569 | struct ffs_data *ffs; |
1597 | 1570 | ||
1598 | ENTER(); | 1571 | ENTER(); |
1599 | 1572 | ||
1600 | ret = ffs_fs_parse_opts(&data, opts); | 1573 | if (!fc->source) |
1601 | if (unlikely(ret < 0)) | 1574 | return invalf(fc, "No source specified"); |
1602 | return ERR_PTR(ret); | ||
1603 | 1575 | ||
1604 | ffs = ffs_data_new(dev_name); | 1576 | ffs = ffs_data_new(fc->source); |
1605 | if (unlikely(!ffs)) | 1577 | if (unlikely(!ffs)) |
1606 | return ERR_PTR(-ENOMEM); | 1578 | return -ENOMEM; |
1607 | ffs->file_perms = data.perms; | 1579 | ffs->file_perms = ctx->perms; |
1608 | ffs->no_disconnect = data.no_disconnect; | 1580 | ffs->no_disconnect = ctx->no_disconnect; |
1609 | 1581 | ||
1610 | ffs->dev_name = kstrdup(dev_name, GFP_KERNEL); | 1582 | ffs->dev_name = kstrdup(fc->source, GFP_KERNEL); |
1611 | if (unlikely(!ffs->dev_name)) { | 1583 | if (unlikely(!ffs->dev_name)) { |
1612 | ffs_data_put(ffs); | 1584 | ffs_data_put(ffs); |
1613 | return ERR_PTR(-ENOMEM); | 1585 | return -ENOMEM; |
1614 | } | 1586 | } |
1615 | 1587 | ||
1616 | ffs_dev = ffs_acquire_dev(dev_name); | 1588 | ffs_dev = ffs_acquire_dev(ffs->dev_name); |
1617 | if (IS_ERR(ffs_dev)) { | 1589 | if (IS_ERR(ffs_dev)) { |
1618 | ffs_data_put(ffs); | 1590 | ffs_data_put(ffs); |
1619 | return ERR_CAST(ffs_dev); | 1591 | return PTR_ERR(ffs_dev); |
1620 | } | 1592 | } |
1593 | |||
1621 | ffs->private_data = ffs_dev; | 1594 | ffs->private_data = ffs_dev; |
1622 | data.ffs_data = ffs; | 1595 | ctx->ffs_data = ffs; |
1596 | return get_tree_nodev(fc, ffs_sb_fill); | ||
1597 | } | ||
1598 | |||
1599 | static void ffs_fs_free_fc(struct fs_context *fc) | ||
1600 | { | ||
1601 | struct ffs_sb_fill_data *ctx = fc->fs_private; | ||
1602 | |||
1603 | if (ctx) { | ||
1604 | if (ctx->ffs_data) { | ||
1605 | ffs_release_dev(ctx->ffs_data); | ||
1606 | ffs_data_put(ctx->ffs_data); | ||
1607 | } | ||
1623 | 1608 | ||
1624 | rv = mount_nodev(t, flags, &data, ffs_sb_fill); | 1609 | kfree(ctx); |
1625 | if (IS_ERR(rv) && data.ffs_data) { | ||
1626 | ffs_release_dev(data.ffs_data); | ||
1627 | ffs_data_put(data.ffs_data); | ||
1628 | } | 1610 | } |
1629 | return rv; | 1611 | } |
1612 | |||
1613 | static const struct fs_context_operations ffs_fs_context_ops = { | ||
1614 | .free = ffs_fs_free_fc, | ||
1615 | .parse_param = ffs_fs_parse_param, | ||
1616 | .get_tree = ffs_fs_get_tree, | ||
1617 | }; | ||
1618 | |||
1619 | static int ffs_fs_init_fs_context(struct fs_context *fc) | ||
1620 | { | ||
1621 | struct ffs_sb_fill_data *ctx; | ||
1622 | |||
1623 | ctx = kzalloc(sizeof(struct ffs_sb_fill_data), GFP_KERNEL); | ||
1624 | if (!ctx) | ||
1625 | return -ENOMEM; | ||
1626 | |||
1627 | ctx->perms.mode = S_IFREG | 0600; | ||
1628 | ctx->perms.uid = GLOBAL_ROOT_UID; | ||
1629 | ctx->perms.gid = GLOBAL_ROOT_GID; | ||
1630 | ctx->root_mode = S_IFDIR | 0500; | ||
1631 | ctx->no_disconnect = false; | ||
1632 | |||
1633 | fc->fs_private = ctx; | ||
1634 | fc->ops = &ffs_fs_context_ops; | ||
1635 | return 0; | ||
1630 | } | 1636 | } |
1631 | 1637 | ||
1632 | static void | 1638 | static void |
@@ -1644,7 +1650,8 @@ ffs_fs_kill_sb(struct super_block *sb) | |||
1644 | static struct file_system_type ffs_fs_type = { | 1650 | static struct file_system_type ffs_fs_type = { |
1645 | .owner = THIS_MODULE, | 1651 | .owner = THIS_MODULE, |
1646 | .name = "functionfs", | 1652 | .name = "functionfs", |
1647 | .mount = ffs_fs_mount, | 1653 | .init_fs_context = ffs_fs_init_fs_context, |
1654 | .parameters = &ffs_fs_fs_parameters, | ||
1648 | .kill_sb = ffs_fs_kill_sb, | 1655 | .kill_sb = ffs_fs_kill_sb, |
1649 | }; | 1656 | }; |
1650 | MODULE_ALIAS_FS("functionfs"); | 1657 | MODULE_ALIAS_FS("functionfs"); |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 6b450065b9d5..5f89c515f5bb 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -584,10 +584,10 @@ struct gfs2_args { | |||
584 | unsigned int ar_rgrplvb:1; /* use lvbs for rgrp info */ | 584 | unsigned int ar_rgrplvb:1; /* use lvbs for rgrp info */ |
585 | unsigned int ar_loccookie:1; /* use location based readdir | 585 | unsigned int ar_loccookie:1; /* use location based readdir |
586 | cookies */ | 586 | cookies */ |
587 | int ar_commit; /* Commit interval */ | 587 | s32 ar_commit; /* Commit interval */ |
588 | int ar_statfs_quantum; /* The fast statfs interval */ | 588 | s32 ar_statfs_quantum; /* The fast statfs interval */ |
589 | int ar_quota_quantum; /* The quota interval */ | 589 | s32 ar_quota_quantum; /* The quota interval */ |
590 | int ar_statfs_percent; /* The % change to force sync */ | 590 | s32 ar_statfs_percent; /* The % change to force sync */ |
591 | }; | 591 | }; |
592 | 592 | ||
593 | struct gfs2_tune { | 593 | struct gfs2_tune { |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index f3fd5cd9d43f..681b44682b0d 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/lockdep.h> | 21 | #include <linux/lockdep.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/backing-dev.h> | 23 | #include <linux/backing-dev.h> |
24 | #include <linux/fs_parser.h> | ||
24 | 25 | ||
25 | #include "gfs2.h" | 26 | #include "gfs2.h" |
26 | #include "incore.h" | 27 | #include "incore.h" |
@@ -1031,16 +1032,17 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp) | |||
1031 | } | 1032 | } |
1032 | 1033 | ||
1033 | /** | 1034 | /** |
1034 | * fill_super - Read in superblock | 1035 | * gfs2_fill_super - Read in superblock |
1035 | * @sb: The VFS superblock | 1036 | * @sb: The VFS superblock |
1036 | * @data: Mount options | 1037 | * @args: Mount options |
1037 | * @silent: Don't complain if it's not a GFS2 filesystem | 1038 | * @silent: Don't complain if it's not a GFS2 filesystem |
1038 | * | 1039 | * |
1039 | * Returns: errno | 1040 | * Returns: -errno |
1040 | */ | 1041 | */ |
1041 | 1042 | static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) | |
1042 | static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent) | ||
1043 | { | 1043 | { |
1044 | struct gfs2_args *args = fc->fs_private; | ||
1045 | int silent = fc->sb_flags & SB_SILENT; | ||
1044 | struct gfs2_sbd *sdp; | 1046 | struct gfs2_sbd *sdp; |
1045 | struct gfs2_holder mount_gh; | 1047 | struct gfs2_holder mount_gh; |
1046 | int error; | 1048 | int error; |
@@ -1205,161 +1207,411 @@ fail_debug: | |||
1205 | return error; | 1207 | return error; |
1206 | } | 1208 | } |
1207 | 1209 | ||
1208 | static int set_gfs2_super(struct super_block *s, void *data) | 1210 | /** |
1211 | * gfs2_get_tree - Get the GFS2 superblock and root directory | ||
1212 | * @fc: The filesystem context | ||
1213 | * | ||
1214 | * Returns: 0 or -errno on error | ||
1215 | */ | ||
1216 | static int gfs2_get_tree(struct fs_context *fc) | ||
1209 | { | 1217 | { |
1210 | s->s_bdev = data; | 1218 | struct gfs2_args *args = fc->fs_private; |
1211 | s->s_dev = s->s_bdev->bd_dev; | 1219 | struct gfs2_sbd *sdp; |
1212 | s->s_bdi = bdi_get(s->s_bdev->bd_bdi); | 1220 | int error; |
1221 | |||
1222 | error = get_tree_bdev(fc, gfs2_fill_super); | ||
1223 | if (error) | ||
1224 | return error; | ||
1225 | |||
1226 | sdp = fc->root->d_sb->s_fs_info; | ||
1227 | dput(fc->root); | ||
1228 | if (args->ar_meta) | ||
1229 | fc->root = dget(sdp->sd_master_dir); | ||
1230 | else | ||
1231 | fc->root = dget(sdp->sd_root_dir); | ||
1213 | return 0; | 1232 | return 0; |
1214 | } | 1233 | } |
1215 | 1234 | ||
1216 | static int test_gfs2_super(struct super_block *s, void *ptr) | 1235 | static void gfs2_fc_free(struct fs_context *fc) |
1217 | { | 1236 | { |
1218 | struct block_device *bdev = ptr; | 1237 | struct gfs2_args *args = fc->fs_private; |
1219 | return (bdev == s->s_bdev); | 1238 | |
1239 | kfree(args); | ||
1220 | } | 1240 | } |
1221 | 1241 | ||
1222 | /** | 1242 | enum gfs2_param { |
1223 | * gfs2_mount - Get the GFS2 superblock | 1243 | Opt_lockproto, |
1224 | * @fs_type: The GFS2 filesystem type | 1244 | Opt_locktable, |
1225 | * @flags: Mount flags | 1245 | Opt_hostdata, |
1226 | * @dev_name: The name of the device | 1246 | Opt_spectator, |
1227 | * @data: The mount arguments | 1247 | Opt_ignore_local_fs, |
1228 | * | 1248 | Opt_localflocks, |
1229 | * Q. Why not use get_sb_bdev() ? | 1249 | Opt_localcaching, |
1230 | * A. We need to select one of two root directories to mount, independent | 1250 | Opt_debug, |
1231 | * of whether this is the initial, or subsequent, mount of this sb | 1251 | Opt_upgrade, |
1232 | * | 1252 | Opt_acl, |
1233 | * Returns: 0 or -ve on error | 1253 | Opt_quota, |
1234 | */ | 1254 | Opt_suiddir, |
1255 | Opt_data, | ||
1256 | Opt_meta, | ||
1257 | Opt_discard, | ||
1258 | Opt_commit, | ||
1259 | Opt_errors, | ||
1260 | Opt_statfs_quantum, | ||
1261 | Opt_statfs_percent, | ||
1262 | Opt_quota_quantum, | ||
1263 | Opt_barrier, | ||
1264 | Opt_rgrplvb, | ||
1265 | Opt_loccookie, | ||
1266 | }; | ||
1235 | 1267 | ||
1236 | static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, | 1268 | enum opt_quota { |
1237 | const char *dev_name, void *data) | 1269 | Opt_quota_unset = 0, |
1238 | { | 1270 | Opt_quota_off, |
1239 | struct block_device *bdev; | 1271 | Opt_quota_account, |
1240 | struct super_block *s; | 1272 | Opt_quota_on, |
1241 | fmode_t mode = FMODE_READ | FMODE_EXCL; | 1273 | }; |
1242 | int error; | 1274 | |
1243 | struct gfs2_args args; | 1275 | static const unsigned int opt_quota_values[] = { |
1244 | struct gfs2_sbd *sdp; | 1276 | [Opt_quota_off] = GFS2_QUOTA_OFF, |
1277 | [Opt_quota_account] = GFS2_QUOTA_ACCOUNT, | ||
1278 | [Opt_quota_on] = GFS2_QUOTA_ON, | ||
1279 | }; | ||
1245 | 1280 | ||
1246 | if (!(flags & SB_RDONLY)) | 1281 | enum opt_data { |
1247 | mode |= FMODE_WRITE; | 1282 | Opt_data_writeback = GFS2_DATA_WRITEBACK, |
1283 | Opt_data_ordered = GFS2_DATA_ORDERED, | ||
1284 | }; | ||
1248 | 1285 | ||
1249 | bdev = blkdev_get_by_path(dev_name, mode, fs_type); | 1286 | enum opt_errors { |
1250 | if (IS_ERR(bdev)) | 1287 | Opt_errors_withdraw = GFS2_ERRORS_WITHDRAW, |
1251 | return ERR_CAST(bdev); | 1288 | Opt_errors_panic = GFS2_ERRORS_PANIC, |
1289 | }; | ||
1252 | 1290 | ||
1253 | /* | 1291 | static const struct fs_parameter_spec gfs2_param_specs[] = { |
1254 | * once the super is inserted into the list by sget, s_umount | 1292 | fsparam_string ("lockproto", Opt_lockproto), |
1255 | * will protect the lockfs code from trying to start a snapshot | 1293 | fsparam_string ("locktable", Opt_locktable), |
1256 | * while we are mounting | 1294 | fsparam_string ("hostdata", Opt_hostdata), |
1257 | */ | 1295 | fsparam_flag ("spectator", Opt_spectator), |
1258 | mutex_lock(&bdev->bd_fsfreeze_mutex); | 1296 | fsparam_flag ("norecovery", Opt_spectator), |
1259 | if (bdev->bd_fsfreeze_count > 0) { | 1297 | fsparam_flag ("ignore_local_fs", Opt_ignore_local_fs), |
1260 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 1298 | fsparam_flag ("localflocks", Opt_localflocks), |
1261 | error = -EBUSY; | 1299 | fsparam_flag ("localcaching", Opt_localcaching), |
1262 | goto error_bdev; | 1300 | fsparam_flag_no("debug", Opt_debug), |
1263 | } | 1301 | fsparam_flag ("upgrade", Opt_upgrade), |
1264 | s = sget(fs_type, test_gfs2_super, set_gfs2_super, flags, bdev); | 1302 | fsparam_flag_no("acl", Opt_acl), |
1265 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 1303 | fsparam_flag_no("suiddir", Opt_suiddir), |
1266 | error = PTR_ERR(s); | 1304 | fsparam_enum ("data", Opt_data), |
1267 | if (IS_ERR(s)) | 1305 | fsparam_flag ("meta", Opt_meta), |
1268 | goto error_bdev; | 1306 | fsparam_flag_no("discard", Opt_discard), |
1269 | 1307 | fsparam_s32 ("commit", Opt_commit), | |
1270 | if (s->s_root) { | 1308 | fsparam_enum ("errors", Opt_errors), |
1271 | /* | 1309 | fsparam_s32 ("statfs_quantum", Opt_statfs_quantum), |
1272 | * s_umount nests inside bd_mutex during | 1310 | fsparam_s32 ("statfs_percent", Opt_statfs_percent), |
1273 | * __invalidate_device(). blkdev_put() acquires | 1311 | fsparam_s32 ("quota_quantum", Opt_quota_quantum), |
1274 | * bd_mutex and can't be called under s_umount. Drop | 1312 | fsparam_flag_no("barrier", Opt_barrier), |
1275 | * s_umount temporarily. This is safe as we're | 1313 | fsparam_flag_no("rgrplvb", Opt_rgrplvb), |
1276 | * holding an active reference. | 1314 | fsparam_flag_no("loccookie", Opt_loccookie), |
1277 | */ | 1315 | /* quota can be a flag or an enum so it gets special treatment */ |
1278 | up_write(&s->s_umount); | 1316 | __fsparam(fs_param_is_enum, "quota", Opt_quota, fs_param_neg_with_no|fs_param_v_optional), |
1279 | blkdev_put(bdev, mode); | 1317 | {} |
1280 | down_write(&s->s_umount); | 1318 | }; |
1281 | } else { | ||
1282 | /* s_mode must be set before deactivate_locked_super calls */ | ||
1283 | s->s_mode = mode; | ||
1284 | } | ||
1285 | 1319 | ||
1286 | memset(&args, 0, sizeof(args)); | 1320 | static const struct fs_parameter_enum gfs2_param_enums[] = { |
1287 | args.ar_quota = GFS2_QUOTA_DEFAULT; | 1321 | { Opt_quota, "off", Opt_quota_off }, |
1288 | args.ar_data = GFS2_DATA_DEFAULT; | 1322 | { Opt_quota, "account", Opt_quota_account }, |
1289 | args.ar_commit = 30; | 1323 | { Opt_quota, "on", Opt_quota_on }, |
1290 | args.ar_statfs_quantum = 30; | 1324 | { Opt_data, "writeback", Opt_data_writeback }, |
1291 | args.ar_quota_quantum = 60; | 1325 | { Opt_data, "ordered", Opt_data_ordered }, |
1292 | args.ar_errors = GFS2_ERRORS_DEFAULT; | 1326 | { Opt_errors, "withdraw", Opt_errors_withdraw }, |
1327 | { Opt_errors, "panic", Opt_errors_panic }, | ||
1328 | {} | ||
1329 | }; | ||
1293 | 1330 | ||
1294 | error = gfs2_mount_args(&args, data); | 1331 | const struct fs_parameter_description gfs2_fs_parameters = { |
1295 | if (error) { | 1332 | .name = "gfs2", |
1296 | pr_warn("can't parse mount arguments\n"); | 1333 | .specs = gfs2_param_specs, |
1297 | goto error_super; | 1334 | .enums = gfs2_param_enums, |
1335 | }; | ||
1336 | |||
1337 | /* Parse a single mount parameter */ | ||
1338 | static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param) | ||
1339 | { | ||
1340 | struct gfs2_args *args = fc->fs_private; | ||
1341 | struct fs_parse_result result; | ||
1342 | int o; | ||
1343 | |||
1344 | o = fs_parse(fc, &gfs2_fs_parameters, param, &result); | ||
1345 | if (o < 0) | ||
1346 | return o; | ||
1347 | |||
1348 | switch (o) { | ||
1349 | case Opt_lockproto: | ||
1350 | strlcpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN); | ||
1351 | break; | ||
1352 | case Opt_locktable: | ||
1353 | strlcpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN); | ||
1354 | break; | ||
1355 | case Opt_hostdata: | ||
1356 | strlcpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN); | ||
1357 | break; | ||
1358 | case Opt_spectator: | ||
1359 | args->ar_spectator = 1; | ||
1360 | break; | ||
1361 | case Opt_ignore_local_fs: | ||
1362 | /* Retained for backwards compat only */ | ||
1363 | break; | ||
1364 | case Opt_localflocks: | ||
1365 | args->ar_localflocks = 1; | ||
1366 | break; | ||
1367 | case Opt_localcaching: | ||
1368 | /* Retained for backwards compat only */ | ||
1369 | break; | ||
1370 | case Opt_debug: | ||
1371 | if (result.boolean && args->ar_errors == GFS2_ERRORS_PANIC) | ||
1372 | return invalf(fc, "gfs2: -o debug and -o errors=panic are mutually exclusive"); | ||
1373 | args->ar_debug = result.boolean; | ||
1374 | break; | ||
1375 | case Opt_upgrade: | ||
1376 | /* Retained for backwards compat only */ | ||
1377 | break; | ||
1378 | case Opt_acl: | ||
1379 | args->ar_posix_acl = result.boolean; | ||
1380 | break; | ||
1381 | case Opt_quota: | ||
1382 | /* The quota option can be a flag or an enum. A non-zero int_32 | ||
1383 | result means that we have an enum index. Otherwise we have | ||
1384 | to rely on the 'negated' flag to tell us whether 'quota' or | ||
1385 | 'noquota' was specified. */ | ||
1386 | if (result.negated) | ||
1387 | args->ar_quota = GFS2_QUOTA_OFF; | ||
1388 | else if (result.int_32 > 0) | ||
1389 | args->ar_quota = opt_quota_values[result.int_32]; | ||
1390 | else | ||
1391 | args->ar_quota = GFS2_QUOTA_ON; | ||
1392 | break; | ||
1393 | case Opt_suiddir: | ||
1394 | args->ar_suiddir = result.boolean; | ||
1395 | break; | ||
1396 | case Opt_data: | ||
1397 | /* The uint_32 result maps directly to GFS2_DATA_* */ | ||
1398 | args->ar_data = result.uint_32; | ||
1399 | break; | ||
1400 | case Opt_meta: | ||
1401 | args->ar_meta = 1; | ||
1402 | break; | ||
1403 | case Opt_discard: | ||
1404 | args->ar_discard = result.boolean; | ||
1405 | break; | ||
1406 | case Opt_commit: | ||
1407 | if (result.int_32 <= 0) | ||
1408 | return invalf(fc, "gfs2: commit mount option requires a positive numeric argument"); | ||
1409 | args->ar_commit = result.int_32; | ||
1410 | break; | ||
1411 | case Opt_statfs_quantum: | ||
1412 | if (result.int_32 < 0) | ||
1413 | return invalf(fc, "gfs2: statfs_quantum mount option requires a non-negative numeric argument"); | ||
1414 | args->ar_statfs_quantum = result.int_32; | ||
1415 | break; | ||
1416 | case Opt_quota_quantum: | ||
1417 | if (result.int_32 <= 0) | ||
1418 | return invalf(fc, "gfs2: quota_quantum mount option requires a positive numeric argument"); | ||
1419 | args->ar_quota_quantum = result.int_32; | ||
1420 | break; | ||
1421 | case Opt_statfs_percent: | ||
1422 | if (result.int_32 < 0 || result.int_32 > 100) | ||
1423 | return invalf(fc, "gfs2: statfs_percent mount option requires a numeric argument between 0 and 100"); | ||
1424 | args->ar_statfs_percent = result.int_32; | ||
1425 | break; | ||
1426 | case Opt_errors: | ||
1427 | if (args->ar_debug && result.uint_32 == GFS2_ERRORS_PANIC) | ||
1428 | return invalf(fc, "gfs2: -o debug and -o errors=panic are mutually exclusive"); | ||
1429 | args->ar_errors = result.uint_32; | ||
1430 | break; | ||
1431 | case Opt_barrier: | ||
1432 | args->ar_nobarrier = result.boolean; | ||
1433 | break; | ||
1434 | case Opt_rgrplvb: | ||
1435 | args->ar_rgrplvb = result.boolean; | ||
1436 | break; | ||
1437 | case Opt_loccookie: | ||
1438 | args->ar_loccookie = result.boolean; | ||
1439 | break; | ||
1440 | default: | ||
1441 | return invalf(fc, "gfs2: invalid mount option: %s", param->key); | ||
1298 | } | 1442 | } |
1443 | return 0; | ||
1444 | } | ||
1299 | 1445 | ||
1300 | if (s->s_root) { | 1446 | static int gfs2_reconfigure(struct fs_context *fc) |
1301 | error = -EBUSY; | 1447 | { |
1302 | if ((flags ^ s->s_flags) & SB_RDONLY) | 1448 | struct super_block *sb = fc->root->d_sb; |
1303 | goto error_super; | 1449 | struct gfs2_sbd *sdp = sb->s_fs_info; |
1304 | } else { | 1450 | struct gfs2_args *oldargs = &sdp->sd_args; |
1305 | snprintf(s->s_id, sizeof(s->s_id), "%pg", bdev); | 1451 | struct gfs2_args *newargs = fc->fs_private; |
1306 | sb_set_blocksize(s, block_size(bdev)); | 1452 | struct gfs2_tune *gt = &sdp->sd_tune; |
1307 | error = fill_super(s, &args, flags & SB_SILENT ? 1 : 0); | 1453 | int error = 0; |
1308 | if (error) | 1454 | |
1309 | goto error_super; | 1455 | sync_filesystem(sb); |
1310 | s->s_flags |= SB_ACTIVE; | 1456 | |
1311 | bdev->bd_super = s; | 1457 | spin_lock(>->gt_spin); |
1458 | oldargs->ar_commit = gt->gt_logd_secs; | ||
1459 | oldargs->ar_quota_quantum = gt->gt_quota_quantum; | ||
1460 | if (gt->gt_statfs_slow) | ||
1461 | oldargs->ar_statfs_quantum = 0; | ||
1462 | else | ||
1463 | oldargs->ar_statfs_quantum = gt->gt_statfs_quantum; | ||
1464 | spin_unlock(>->gt_spin); | ||
1465 | |||
1466 | if (strcmp(newargs->ar_lockproto, oldargs->ar_lockproto)) { | ||
1467 | errorf(fc, "gfs2: reconfiguration of locking protocol not allowed"); | ||
1468 | return -EINVAL; | ||
1469 | } | ||
1470 | if (strcmp(newargs->ar_locktable, oldargs->ar_locktable)) { | ||
1471 | errorf(fc, "gfs2: reconfiguration of lock table not allowed"); | ||
1472 | return -EINVAL; | ||
1473 | } | ||
1474 | if (strcmp(newargs->ar_hostdata, oldargs->ar_hostdata)) { | ||
1475 | errorf(fc, "gfs2: reconfiguration of host data not allowed"); | ||
1476 | return -EINVAL; | ||
1477 | } | ||
1478 | if (newargs->ar_spectator != oldargs->ar_spectator) { | ||
1479 | errorf(fc, "gfs2: reconfiguration of spectator mode not allowed"); | ||
1480 | return -EINVAL; | ||
1481 | } | ||
1482 | if (newargs->ar_localflocks != oldargs->ar_localflocks) { | ||
1483 | errorf(fc, "gfs2: reconfiguration of localflocks not allowed"); | ||
1484 | return -EINVAL; | ||
1485 | } | ||
1486 | if (newargs->ar_meta != oldargs->ar_meta) { | ||
1487 | errorf(fc, "gfs2: switching between gfs2 and gfs2meta not allowed"); | ||
1488 | return -EINVAL; | ||
1489 | } | ||
1490 | if (oldargs->ar_spectator) | ||
1491 | fc->sb_flags |= SB_RDONLY; | ||
1492 | |||
1493 | if ((sb->s_flags ^ fc->sb_flags) & SB_RDONLY) { | ||
1494 | if (fc->sb_flags & SB_RDONLY) { | ||
1495 | error = gfs2_make_fs_ro(sdp); | ||
1496 | if (error) | ||
1497 | errorf(fc, "gfs2: unable to remount read-only"); | ||
1498 | } else { | ||
1499 | error = gfs2_make_fs_rw(sdp); | ||
1500 | if (error) | ||
1501 | errorf(fc, "gfs2: unable to remount read-write"); | ||
1502 | } | ||
1312 | } | 1503 | } |
1504 | sdp->sd_args = *newargs; | ||
1313 | 1505 | ||
1314 | sdp = s->s_fs_info; | 1506 | if (sdp->sd_args.ar_posix_acl) |
1315 | if (args.ar_meta) | 1507 | sb->s_flags |= SB_POSIXACL; |
1316 | return dget(sdp->sd_master_dir); | 1508 | else |
1509 | sb->s_flags &= ~SB_POSIXACL; | ||
1510 | if (sdp->sd_args.ar_nobarrier) | ||
1511 | set_bit(SDF_NOBARRIERS, &sdp->sd_flags); | ||
1317 | else | 1512 | else |
1318 | return dget(sdp->sd_root_dir); | 1513 | clear_bit(SDF_NOBARRIERS, &sdp->sd_flags); |
1319 | 1514 | spin_lock(>->gt_spin); | |
1320 | error_super: | 1515 | gt->gt_logd_secs = newargs->ar_commit; |
1321 | deactivate_locked_super(s); | 1516 | gt->gt_quota_quantum = newargs->ar_quota_quantum; |
1322 | return ERR_PTR(error); | 1517 | if (newargs->ar_statfs_quantum) { |
1323 | error_bdev: | 1518 | gt->gt_statfs_slow = 0; |
1324 | blkdev_put(bdev, mode); | 1519 | gt->gt_statfs_quantum = newargs->ar_statfs_quantum; |
1325 | return ERR_PTR(error); | 1520 | } |
1521 | else { | ||
1522 | gt->gt_statfs_slow = 1; | ||
1523 | gt->gt_statfs_quantum = 30; | ||
1524 | } | ||
1525 | spin_unlock(>->gt_spin); | ||
1526 | |||
1527 | gfs2_online_uevent(sdp); | ||
1528 | return error; | ||
1529 | } | ||
1530 | |||
1531 | static const struct fs_context_operations gfs2_context_ops = { | ||
1532 | .free = gfs2_fc_free, | ||
1533 | .parse_param = gfs2_parse_param, | ||
1534 | .get_tree = gfs2_get_tree, | ||
1535 | .reconfigure = gfs2_reconfigure, | ||
1536 | }; | ||
1537 | |||
1538 | /* Set up the filesystem mount context */ | ||
1539 | static int gfs2_init_fs_context(struct fs_context *fc) | ||
1540 | { | ||
1541 | struct gfs2_args *args; | ||
1542 | |||
1543 | args = kzalloc(sizeof(*args), GFP_KERNEL); | ||
1544 | if (args == NULL) | ||
1545 | return -ENOMEM; | ||
1546 | |||
1547 | args->ar_quota = GFS2_QUOTA_DEFAULT; | ||
1548 | args->ar_data = GFS2_DATA_DEFAULT; | ||
1549 | args->ar_commit = 30; | ||
1550 | args->ar_statfs_quantum = 30; | ||
1551 | args->ar_quota_quantum = 60; | ||
1552 | args->ar_errors = GFS2_ERRORS_DEFAULT; | ||
1553 | |||
1554 | fc->fs_private = args; | ||
1555 | fc->ops = &gfs2_context_ops; | ||
1556 | return 0; | ||
1326 | } | 1557 | } |
1327 | 1558 | ||
1328 | static int set_meta_super(struct super_block *s, void *ptr) | 1559 | static int set_meta_super(struct super_block *s, struct fs_context *fc) |
1329 | { | 1560 | { |
1330 | return -EINVAL; | 1561 | return -EINVAL; |
1331 | } | 1562 | } |
1332 | 1563 | ||
1333 | static struct dentry *gfs2_mount_meta(struct file_system_type *fs_type, | 1564 | static int test_meta_super(struct super_block *s, struct fs_context *fc) |
1334 | int flags, const char *dev_name, void *data) | 1565 | { |
1566 | return (fc->sget_key == s->s_bdev); | ||
1567 | } | ||
1568 | |||
1569 | static int gfs2_meta_get_tree(struct fs_context *fc) | ||
1335 | { | 1570 | { |
1336 | struct super_block *s; | 1571 | struct super_block *s; |
1337 | struct gfs2_sbd *sdp; | 1572 | struct gfs2_sbd *sdp; |
1338 | struct path path; | 1573 | struct path path; |
1339 | int error; | 1574 | int error; |
1340 | 1575 | ||
1341 | if (!dev_name || !*dev_name) | 1576 | if (!fc->source || !*fc->source) |
1342 | return ERR_PTR(-EINVAL); | 1577 | return -EINVAL; |
1343 | 1578 | ||
1344 | error = kern_path(dev_name, LOOKUP_FOLLOW, &path); | 1579 | error = kern_path(fc->source, LOOKUP_FOLLOW, &path); |
1345 | if (error) { | 1580 | if (error) { |
1346 | pr_warn("path_lookup on %s returned error %d\n", | 1581 | pr_warn("path_lookup on %s returned error %d\n", |
1347 | dev_name, error); | 1582 | fc->source, error); |
1348 | return ERR_PTR(error); | 1583 | return error; |
1349 | } | 1584 | } |
1350 | s = sget(&gfs2_fs_type, test_gfs2_super, set_meta_super, flags, | 1585 | fc->fs_type = &gfs2_fs_type; |
1351 | path.dentry->d_sb->s_bdev); | 1586 | fc->sget_key = path.dentry->d_sb->s_bdev; |
1587 | s = sget_fc(fc, test_meta_super, set_meta_super); | ||
1352 | path_put(&path); | 1588 | path_put(&path); |
1353 | if (IS_ERR(s)) { | 1589 | if (IS_ERR(s)) { |
1354 | pr_warn("gfs2 mount does not exist\n"); | 1590 | pr_warn("gfs2 mount does not exist\n"); |
1355 | return ERR_CAST(s); | 1591 | return PTR_ERR(s); |
1356 | } | 1592 | } |
1357 | if ((flags ^ s->s_flags) & SB_RDONLY) { | 1593 | if ((fc->sb_flags ^ s->s_flags) & SB_RDONLY) { |
1358 | deactivate_locked_super(s); | 1594 | deactivate_locked_super(s); |
1359 | return ERR_PTR(-EBUSY); | 1595 | return -EBUSY; |
1360 | } | 1596 | } |
1361 | sdp = s->s_fs_info; | 1597 | sdp = s->s_fs_info; |
1362 | return dget(sdp->sd_master_dir); | 1598 | fc->root = dget(sdp->sd_master_dir); |
1599 | return 0; | ||
1600 | } | ||
1601 | |||
1602 | static const struct fs_context_operations gfs2_meta_context_ops = { | ||
1603 | .get_tree = gfs2_meta_get_tree, | ||
1604 | }; | ||
1605 | |||
1606 | static int gfs2_meta_init_fs_context(struct fs_context *fc) | ||
1607 | { | ||
1608 | int ret = gfs2_init_fs_context(fc); | ||
1609 | |||
1610 | if (ret) | ||
1611 | return ret; | ||
1612 | |||
1613 | fc->ops = &gfs2_meta_context_ops; | ||
1614 | return 0; | ||
1363 | } | 1615 | } |
1364 | 1616 | ||
1365 | static void gfs2_kill_sb(struct super_block *sb) | 1617 | static void gfs2_kill_sb(struct super_block *sb) |
@@ -1383,7 +1635,8 @@ static void gfs2_kill_sb(struct super_block *sb) | |||
1383 | struct file_system_type gfs2_fs_type = { | 1635 | struct file_system_type gfs2_fs_type = { |
1384 | .name = "gfs2", | 1636 | .name = "gfs2", |
1385 | .fs_flags = FS_REQUIRES_DEV, | 1637 | .fs_flags = FS_REQUIRES_DEV, |
1386 | .mount = gfs2_mount, | 1638 | .init_fs_context = gfs2_init_fs_context, |
1639 | .parameters = &gfs2_fs_parameters, | ||
1387 | .kill_sb = gfs2_kill_sb, | 1640 | .kill_sb = gfs2_kill_sb, |
1388 | .owner = THIS_MODULE, | 1641 | .owner = THIS_MODULE, |
1389 | }; | 1642 | }; |
@@ -1392,7 +1645,7 @@ MODULE_ALIAS_FS("gfs2"); | |||
1392 | struct file_system_type gfs2meta_fs_type = { | 1645 | struct file_system_type gfs2meta_fs_type = { |
1393 | .name = "gfs2meta", | 1646 | .name = "gfs2meta", |
1394 | .fs_flags = FS_REQUIRES_DEV, | 1647 | .fs_flags = FS_REQUIRES_DEV, |
1395 | .mount = gfs2_mount_meta, | 1648 | .init_fs_context = gfs2_meta_init_fs_context, |
1396 | .owner = THIS_MODULE, | 1649 | .owner = THIS_MODULE, |
1397 | }; | 1650 | }; |
1398 | MODULE_ALIAS_FS("gfs2meta"); | 1651 | MODULE_ALIAS_FS("gfs2meta"); |
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 644c70ae09f7..5fa1eec4fb4f 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -44,258 +44,6 @@ | |||
44 | #include "xattr.h" | 44 | #include "xattr.h" |
45 | #include "lops.h" | 45 | #include "lops.h" |
46 | 46 | ||
47 | #define args_neq(a1, a2, x) ((a1)->ar_##x != (a2)->ar_##x) | ||
48 | |||
49 | enum { | ||
50 | Opt_lockproto, | ||
51 | Opt_locktable, | ||
52 | Opt_hostdata, | ||
53 | Opt_spectator, | ||
54 | Opt_ignore_local_fs, | ||
55 | Opt_localflocks, | ||
56 | Opt_localcaching, | ||
57 | Opt_debug, | ||
58 | Opt_nodebug, | ||
59 | Opt_upgrade, | ||
60 | Opt_acl, | ||
61 | Opt_noacl, | ||
62 | Opt_quota_off, | ||
63 | Opt_quota_account, | ||
64 | Opt_quota_on, | ||
65 | Opt_quota, | ||
66 | Opt_noquota, | ||
67 | Opt_suiddir, | ||
68 | Opt_nosuiddir, | ||
69 | Opt_data_writeback, | ||
70 | Opt_data_ordered, | ||
71 | Opt_meta, | ||
72 | Opt_discard, | ||
73 | Opt_nodiscard, | ||
74 | Opt_commit, | ||
75 | Opt_err_withdraw, | ||
76 | Opt_err_panic, | ||
77 | Opt_statfs_quantum, | ||
78 | Opt_statfs_percent, | ||
79 | Opt_quota_quantum, | ||
80 | Opt_barrier, | ||
81 | Opt_nobarrier, | ||
82 | Opt_rgrplvb, | ||
83 | Opt_norgrplvb, | ||
84 | Opt_loccookie, | ||
85 | Opt_noloccookie, | ||
86 | Opt_error, | ||
87 | }; | ||
88 | |||
89 | static const match_table_t tokens = { | ||
90 | {Opt_lockproto, "lockproto=%s"}, | ||
91 | {Opt_locktable, "locktable=%s"}, | ||
92 | {Opt_hostdata, "hostdata=%s"}, | ||
93 | {Opt_spectator, "spectator"}, | ||
94 | {Opt_spectator, "norecovery"}, | ||
95 | {Opt_ignore_local_fs, "ignore_local_fs"}, | ||
96 | {Opt_localflocks, "localflocks"}, | ||
97 | {Opt_localcaching, "localcaching"}, | ||
98 | {Opt_debug, "debug"}, | ||
99 | {Opt_nodebug, "nodebug"}, | ||
100 | {Opt_upgrade, "upgrade"}, | ||
101 | {Opt_acl, "acl"}, | ||
102 | {Opt_noacl, "noacl"}, | ||
103 | {Opt_quota_off, "quota=off"}, | ||
104 | {Opt_quota_account, "quota=account"}, | ||
105 | {Opt_quota_on, "quota=on"}, | ||
106 | {Opt_quota, "quota"}, | ||
107 | {Opt_noquota, "noquota"}, | ||
108 | {Opt_suiddir, "suiddir"}, | ||
109 | {Opt_nosuiddir, "nosuiddir"}, | ||
110 | {Opt_data_writeback, "data=writeback"}, | ||
111 | {Opt_data_ordered, "data=ordered"}, | ||
112 | {Opt_meta, "meta"}, | ||
113 | {Opt_discard, "discard"}, | ||
114 | {Opt_nodiscard, "nodiscard"}, | ||
115 | {Opt_commit, "commit=%d"}, | ||
116 | {Opt_err_withdraw, "errors=withdraw"}, | ||
117 | {Opt_err_panic, "errors=panic"}, | ||
118 | {Opt_statfs_quantum, "statfs_quantum=%d"}, | ||
119 | {Opt_statfs_percent, "statfs_percent=%d"}, | ||
120 | {Opt_quota_quantum, "quota_quantum=%d"}, | ||
121 | {Opt_barrier, "barrier"}, | ||
122 | {Opt_nobarrier, "nobarrier"}, | ||
123 | {Opt_rgrplvb, "rgrplvb"}, | ||
124 | {Opt_norgrplvb, "norgrplvb"}, | ||
125 | {Opt_loccookie, "loccookie"}, | ||
126 | {Opt_noloccookie, "noloccookie"}, | ||
127 | {Opt_error, NULL} | ||
128 | }; | ||
129 | |||
130 | /** | ||
131 | * gfs2_mount_args - Parse mount options | ||
132 | * @args: The structure into which the parsed options will be written | ||
133 | * @options: The options to parse | ||
134 | * | ||
135 | * Return: errno | ||
136 | */ | ||
137 | |||
138 | int gfs2_mount_args(struct gfs2_args *args, char *options) | ||
139 | { | ||
140 | char *o; | ||
141 | int token; | ||
142 | substring_t tmp[MAX_OPT_ARGS]; | ||
143 | int rv; | ||
144 | |||
145 | /* Split the options into tokens with the "," character and | ||
146 | process them */ | ||
147 | |||
148 | while (1) { | ||
149 | o = strsep(&options, ","); | ||
150 | if (o == NULL) | ||
151 | break; | ||
152 | if (*o == '\0') | ||
153 | continue; | ||
154 | |||
155 | token = match_token(o, tokens, tmp); | ||
156 | switch (token) { | ||
157 | case Opt_lockproto: | ||
158 | match_strlcpy(args->ar_lockproto, &tmp[0], | ||
159 | GFS2_LOCKNAME_LEN); | ||
160 | break; | ||
161 | case Opt_locktable: | ||
162 | match_strlcpy(args->ar_locktable, &tmp[0], | ||
163 | GFS2_LOCKNAME_LEN); | ||
164 | break; | ||
165 | case Opt_hostdata: | ||
166 | match_strlcpy(args->ar_hostdata, &tmp[0], | ||
167 | GFS2_LOCKNAME_LEN); | ||
168 | break; | ||
169 | case Opt_spectator: | ||
170 | args->ar_spectator = 1; | ||
171 | break; | ||
172 | case Opt_ignore_local_fs: | ||
173 | /* Retained for backwards compat only */ | ||
174 | break; | ||
175 | case Opt_localflocks: | ||
176 | args->ar_localflocks = 1; | ||
177 | break; | ||
178 | case Opt_localcaching: | ||
179 | /* Retained for backwards compat only */ | ||
180 | break; | ||
181 | case Opt_debug: | ||
182 | if (args->ar_errors == GFS2_ERRORS_PANIC) { | ||
183 | pr_warn("-o debug and -o errors=panic are mutually exclusive\n"); | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | args->ar_debug = 1; | ||
187 | break; | ||
188 | case Opt_nodebug: | ||
189 | args->ar_debug = 0; | ||
190 | break; | ||
191 | case Opt_upgrade: | ||
192 | /* Retained for backwards compat only */ | ||
193 | break; | ||
194 | case Opt_acl: | ||
195 | args->ar_posix_acl = 1; | ||
196 | break; | ||
197 | case Opt_noacl: | ||
198 | args->ar_posix_acl = 0; | ||
199 | break; | ||
200 | case Opt_quota_off: | ||
201 | case Opt_noquota: | ||
202 | args->ar_quota = GFS2_QUOTA_OFF; | ||
203 | break; | ||
204 | case Opt_quota_account: | ||
205 | args->ar_quota = GFS2_QUOTA_ACCOUNT; | ||
206 | break; | ||
207 | case Opt_quota_on: | ||
208 | case Opt_quota: | ||
209 | args->ar_quota = GFS2_QUOTA_ON; | ||
210 | break; | ||
211 | case Opt_suiddir: | ||
212 | args->ar_suiddir = 1; | ||
213 | break; | ||
214 | case Opt_nosuiddir: | ||
215 | args->ar_suiddir = 0; | ||
216 | break; | ||
217 | case Opt_data_writeback: | ||
218 | args->ar_data = GFS2_DATA_WRITEBACK; | ||
219 | break; | ||
220 | case Opt_data_ordered: | ||
221 | args->ar_data = GFS2_DATA_ORDERED; | ||
222 | break; | ||
223 | case Opt_meta: | ||
224 | args->ar_meta = 1; | ||
225 | break; | ||
226 | case Opt_discard: | ||
227 | args->ar_discard = 1; | ||
228 | break; | ||
229 | case Opt_nodiscard: | ||
230 | args->ar_discard = 0; | ||
231 | break; | ||
232 | case Opt_commit: | ||
233 | rv = match_int(&tmp[0], &args->ar_commit); | ||
234 | if (rv || args->ar_commit <= 0) { | ||
235 | pr_warn("commit mount option requires a positive numeric argument\n"); | ||
236 | return rv ? rv : -EINVAL; | ||
237 | } | ||
238 | break; | ||
239 | case Opt_statfs_quantum: | ||
240 | rv = match_int(&tmp[0], &args->ar_statfs_quantum); | ||
241 | if (rv || args->ar_statfs_quantum < 0) { | ||
242 | pr_warn("statfs_quantum mount option requires a non-negative numeric argument\n"); | ||
243 | return rv ? rv : -EINVAL; | ||
244 | } | ||
245 | break; | ||
246 | case Opt_quota_quantum: | ||
247 | rv = match_int(&tmp[0], &args->ar_quota_quantum); | ||
248 | if (rv || args->ar_quota_quantum <= 0) { | ||
249 | pr_warn("quota_quantum mount option requires a positive numeric argument\n"); | ||
250 | return rv ? rv : -EINVAL; | ||
251 | } | ||
252 | break; | ||
253 | case Opt_statfs_percent: | ||
254 | rv = match_int(&tmp[0], &args->ar_statfs_percent); | ||
255 | if (rv || args->ar_statfs_percent < 0 || | ||
256 | args->ar_statfs_percent > 100) { | ||
257 | pr_warn("statfs_percent mount option requires a numeric argument between 0 and 100\n"); | ||
258 | return rv ? rv : -EINVAL; | ||
259 | } | ||
260 | break; | ||
261 | case Opt_err_withdraw: | ||
262 | args->ar_errors = GFS2_ERRORS_WITHDRAW; | ||
263 | break; | ||
264 | case Opt_err_panic: | ||
265 | if (args->ar_debug) { | ||
266 | pr_warn("-o debug and -o errors=panic are mutually exclusive\n"); | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | args->ar_errors = GFS2_ERRORS_PANIC; | ||
270 | break; | ||
271 | case Opt_barrier: | ||
272 | args->ar_nobarrier = 0; | ||
273 | break; | ||
274 | case Opt_nobarrier: | ||
275 | args->ar_nobarrier = 1; | ||
276 | break; | ||
277 | case Opt_rgrplvb: | ||
278 | args->ar_rgrplvb = 1; | ||
279 | break; | ||
280 | case Opt_norgrplvb: | ||
281 | args->ar_rgrplvb = 0; | ||
282 | break; | ||
283 | case Opt_loccookie: | ||
284 | args->ar_loccookie = 1; | ||
285 | break; | ||
286 | case Opt_noloccookie: | ||
287 | args->ar_loccookie = 0; | ||
288 | break; | ||
289 | case Opt_error: | ||
290 | default: | ||
291 | pr_warn("invalid mount option: %s\n", o); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | } | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | /** | 47 | /** |
300 | * gfs2_jindex_free - Clear all the journal index information | 48 | * gfs2_jindex_free - Clear all the journal index information |
301 | * @sdp: The GFS2 superblock | 49 | * @sdp: The GFS2 superblock |
@@ -847,7 +595,7 @@ out: | |||
847 | * Returns: errno | 595 | * Returns: errno |
848 | */ | 596 | */ |
849 | 597 | ||
850 | static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | 598 | int gfs2_make_fs_ro(struct gfs2_sbd *sdp) |
851 | { | 599 | { |
852 | struct gfs2_holder freeze_gh; | 600 | struct gfs2_holder freeze_gh; |
853 | int error; | 601 | int error; |
@@ -1227,84 +975,6 @@ static int gfs2_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
1227 | } | 975 | } |
1228 | 976 | ||
1229 | /** | 977 | /** |
1230 | * gfs2_remount_fs - called when the FS is remounted | ||
1231 | * @sb: the filesystem | ||
1232 | * @flags: the remount flags | ||
1233 | * @data: extra data passed in (not used right now) | ||
1234 | * | ||
1235 | * Returns: errno | ||
1236 | */ | ||
1237 | |||
1238 | static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | ||
1239 | { | ||
1240 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
1241 | struct gfs2_args args = sdp->sd_args; /* Default to current settings */ | ||
1242 | struct gfs2_tune *gt = &sdp->sd_tune; | ||
1243 | int error; | ||
1244 | |||
1245 | sync_filesystem(sb); | ||
1246 | |||
1247 | spin_lock(>->gt_spin); | ||
1248 | args.ar_commit = gt->gt_logd_secs; | ||
1249 | args.ar_quota_quantum = gt->gt_quota_quantum; | ||
1250 | if (gt->gt_statfs_slow) | ||
1251 | args.ar_statfs_quantum = 0; | ||
1252 | else | ||
1253 | args.ar_statfs_quantum = gt->gt_statfs_quantum; | ||
1254 | spin_unlock(>->gt_spin); | ||
1255 | error = gfs2_mount_args(&args, data); | ||
1256 | if (error) | ||
1257 | return error; | ||
1258 | |||
1259 | /* Not allowed to change locking details */ | ||
1260 | if (strcmp(args.ar_lockproto, sdp->sd_args.ar_lockproto) || | ||
1261 | strcmp(args.ar_locktable, sdp->sd_args.ar_locktable) || | ||
1262 | strcmp(args.ar_hostdata, sdp->sd_args.ar_hostdata)) | ||
1263 | return -EINVAL; | ||
1264 | |||
1265 | /* Some flags must not be changed */ | ||
1266 | if (args_neq(&args, &sdp->sd_args, spectator) || | ||
1267 | args_neq(&args, &sdp->sd_args, localflocks) || | ||
1268 | args_neq(&args, &sdp->sd_args, meta)) | ||
1269 | return -EINVAL; | ||
1270 | |||
1271 | if (sdp->sd_args.ar_spectator) | ||
1272 | *flags |= SB_RDONLY; | ||
1273 | |||
1274 | if ((sb->s_flags ^ *flags) & SB_RDONLY) { | ||
1275 | if (*flags & SB_RDONLY) | ||
1276 | error = gfs2_make_fs_ro(sdp); | ||
1277 | else | ||
1278 | error = gfs2_make_fs_rw(sdp); | ||
1279 | } | ||
1280 | |||
1281 | sdp->sd_args = args; | ||
1282 | if (sdp->sd_args.ar_posix_acl) | ||
1283 | sb->s_flags |= SB_POSIXACL; | ||
1284 | else | ||
1285 | sb->s_flags &= ~SB_POSIXACL; | ||
1286 | if (sdp->sd_args.ar_nobarrier) | ||
1287 | set_bit(SDF_NOBARRIERS, &sdp->sd_flags); | ||
1288 | else | ||
1289 | clear_bit(SDF_NOBARRIERS, &sdp->sd_flags); | ||
1290 | spin_lock(>->gt_spin); | ||
1291 | gt->gt_logd_secs = args.ar_commit; | ||
1292 | gt->gt_quota_quantum = args.ar_quota_quantum; | ||
1293 | if (args.ar_statfs_quantum) { | ||
1294 | gt->gt_statfs_slow = 0; | ||
1295 | gt->gt_statfs_quantum = args.ar_statfs_quantum; | ||
1296 | } | ||
1297 | else { | ||
1298 | gt->gt_statfs_slow = 1; | ||
1299 | gt->gt_statfs_quantum = 30; | ||
1300 | } | ||
1301 | spin_unlock(>->gt_spin); | ||
1302 | |||
1303 | gfs2_online_uevent(sdp); | ||
1304 | return error; | ||
1305 | } | ||
1306 | |||
1307 | /** | ||
1308 | * gfs2_drop_inode - Drop an inode (test for remote unlink) | 978 | * gfs2_drop_inode - Drop an inode (test for remote unlink) |
1309 | * @inode: The inode to drop | 979 | * @inode: The inode to drop |
1310 | * | 980 | * |
@@ -1748,7 +1418,6 @@ const struct super_operations gfs2_super_ops = { | |||
1748 | .freeze_super = gfs2_freeze, | 1418 | .freeze_super = gfs2_freeze, |
1749 | .thaw_super = gfs2_unfreeze, | 1419 | .thaw_super = gfs2_unfreeze, |
1750 | .statfs = gfs2_statfs, | 1420 | .statfs = gfs2_statfs, |
1751 | .remount_fs = gfs2_remount_fs, | ||
1752 | .drop_inode = gfs2_drop_inode, | 1421 | .drop_inode = gfs2_drop_inode, |
1753 | .show_options = gfs2_show_options, | 1422 | .show_options = gfs2_show_options, |
1754 | }; | 1423 | }; |
diff --git a/fs/gfs2/super.h b/fs/gfs2/super.h index 9d49eaadb9d9..b8bf811a1305 100644 --- a/fs/gfs2/super.h +++ b/fs/gfs2/super.h | |||
@@ -24,8 +24,6 @@ static inline unsigned int gfs2_jindex_size(struct gfs2_sbd *sdp) | |||
24 | 24 | ||
25 | extern void gfs2_jindex_free(struct gfs2_sbd *sdp); | 25 | extern void gfs2_jindex_free(struct gfs2_sbd *sdp); |
26 | 26 | ||
27 | extern int gfs2_mount_args(struct gfs2_args *args, char *data); | ||
28 | |||
29 | extern struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); | 27 | extern struct gfs2_jdesc *gfs2_jdesc_find(struct gfs2_sbd *sdp, unsigned int jid); |
30 | extern int gfs2_jdesc_check(struct gfs2_jdesc *jd); | 28 | extern int gfs2_jdesc_check(struct gfs2_jdesc *jd); |
31 | 29 | ||
@@ -33,6 +31,7 @@ extern int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename, | |||
33 | struct gfs2_inode **ipp); | 31 | struct gfs2_inode **ipp); |
34 | 32 | ||
35 | extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp); | 33 | extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp); |
34 | extern int gfs2_make_fs_ro(struct gfs2_sbd *sdp); | ||
36 | extern void gfs2_online_uevent(struct gfs2_sbd *sdp); | 35 | extern void gfs2_online_uevent(struct gfs2_sbd *sdp); |
37 | extern int gfs2_statfs_init(struct gfs2_sbd *sdp); | 36 | extern int gfs2_statfs_init(struct gfs2_sbd *sdp); |
38 | extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | 37 | extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, |
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index cc0d0cf114e3..a70f7209cda3 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c | |||
@@ -14,8 +14,9 @@ | |||
14 | #include <linux/mount.h> | 14 | #include <linux/mount.h> |
15 | #include <linux/namei.h> | 15 | #include <linux/namei.h> |
16 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
17 | #include <linux/fs_context.h> | ||
18 | #include <linux/fs_parser.h> | ||
17 | #include <linux/kdev_t.h> | 19 | #include <linux/kdev_t.h> |
18 | #include <linux/parser.h> | ||
19 | #include <linux/filter.h> | 20 | #include <linux/filter.h> |
20 | #include <linux/bpf.h> | 21 | #include <linux/bpf.h> |
21 | #include <linux/bpf_trace.h> | 22 | #include <linux/bpf_trace.h> |
@@ -583,58 +584,52 @@ static const struct super_operations bpf_super_ops = { | |||
583 | 584 | ||
584 | enum { | 585 | enum { |
585 | OPT_MODE, | 586 | OPT_MODE, |
586 | OPT_ERR, | ||
587 | }; | 587 | }; |
588 | 588 | ||
589 | static const match_table_t bpf_mount_tokens = { | 589 | static const struct fs_parameter_spec bpf_param_specs[] = { |
590 | { OPT_MODE, "mode=%o" }, | 590 | fsparam_u32oct ("mode", OPT_MODE), |
591 | { OPT_ERR, NULL }, | 591 | {} |
592 | }; | ||
593 | |||
594 | static const struct fs_parameter_description bpf_fs_parameters = { | ||
595 | .name = "bpf", | ||
596 | .specs = bpf_param_specs, | ||
592 | }; | 597 | }; |
593 | 598 | ||
594 | struct bpf_mount_opts { | 599 | struct bpf_mount_opts { |
595 | umode_t mode; | 600 | umode_t mode; |
596 | }; | 601 | }; |
597 | 602 | ||
598 | static int bpf_parse_options(char *data, struct bpf_mount_opts *opts) | 603 | static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param) |
599 | { | 604 | { |
600 | substring_t args[MAX_OPT_ARGS]; | 605 | struct bpf_mount_opts *opts = fc->fs_private; |
601 | int option, token; | 606 | struct fs_parse_result result; |
602 | char *ptr; | 607 | int opt; |
603 | 608 | ||
604 | opts->mode = S_IRWXUGO; | 609 | opt = fs_parse(fc, &bpf_fs_parameters, param, &result); |
605 | 610 | if (opt < 0) | |
606 | while ((ptr = strsep(&data, ",")) != NULL) { | ||
607 | if (!*ptr) | ||
608 | continue; | ||
609 | |||
610 | token = match_token(ptr, bpf_mount_tokens, args); | ||
611 | switch (token) { | ||
612 | case OPT_MODE: | ||
613 | if (match_octal(&args[0], &option)) | ||
614 | return -EINVAL; | ||
615 | opts->mode = option & S_IALLUGO; | ||
616 | break; | ||
617 | /* We might like to report bad mount options here, but | 611 | /* We might like to report bad mount options here, but |
618 | * traditionally we've ignored all mount options, so we'd | 612 | * traditionally we've ignored all mount options, so we'd |
619 | * better continue to ignore non-existing options for bpf. | 613 | * better continue to ignore non-existing options for bpf. |
620 | */ | 614 | */ |
621 | } | 615 | return opt == -ENOPARAM ? 0 : opt; |
616 | |||
617 | switch (opt) { | ||
618 | case OPT_MODE: | ||
619 | opts->mode = result.uint_32 & S_IALLUGO; | ||
620 | break; | ||
622 | } | 621 | } |
623 | 622 | ||
624 | return 0; | 623 | return 0; |
625 | } | 624 | } |
626 | 625 | ||
627 | static int bpf_fill_super(struct super_block *sb, void *data, int silent) | 626 | static int bpf_fill_super(struct super_block *sb, struct fs_context *fc) |
628 | { | 627 | { |
629 | static const struct tree_descr bpf_rfiles[] = { { "" } }; | 628 | static const struct tree_descr bpf_rfiles[] = { { "" } }; |
630 | struct bpf_mount_opts opts; | 629 | struct bpf_mount_opts *opts = fc->fs_private; |
631 | struct inode *inode; | 630 | struct inode *inode; |
632 | int ret; | 631 | int ret; |
633 | 632 | ||
634 | ret = bpf_parse_options(data, &opts); | ||
635 | if (ret) | ||
636 | return ret; | ||
637 | |||
638 | ret = simple_fill_super(sb, BPF_FS_MAGIC, bpf_rfiles); | 633 | ret = simple_fill_super(sb, BPF_FS_MAGIC, bpf_rfiles); |
639 | if (ret) | 634 | if (ret) |
640 | return ret; | 635 | return ret; |
@@ -644,21 +639,50 @@ static int bpf_fill_super(struct super_block *sb, void *data, int silent) | |||
644 | inode = sb->s_root->d_inode; | 639 | inode = sb->s_root->d_inode; |
645 | inode->i_op = &bpf_dir_iops; | 640 | inode->i_op = &bpf_dir_iops; |
646 | inode->i_mode &= ~S_IALLUGO; | 641 | inode->i_mode &= ~S_IALLUGO; |
647 | inode->i_mode |= S_ISVTX | opts.mode; | 642 | inode->i_mode |= S_ISVTX | opts->mode; |
648 | 643 | ||
649 | return 0; | 644 | return 0; |
650 | } | 645 | } |
651 | 646 | ||
652 | static struct dentry *bpf_mount(struct file_system_type *type, int flags, | 647 | static int bpf_get_tree(struct fs_context *fc) |
653 | const char *dev_name, void *data) | 648 | { |
649 | return get_tree_nodev(fc, bpf_fill_super); | ||
650 | } | ||
651 | |||
652 | static void bpf_free_fc(struct fs_context *fc) | ||
654 | { | 653 | { |
655 | return mount_nodev(type, flags, data, bpf_fill_super); | 654 | kfree(fc->fs_private); |
655 | } | ||
656 | |||
657 | static const struct fs_context_operations bpf_context_ops = { | ||
658 | .free = bpf_free_fc, | ||
659 | .parse_param = bpf_parse_param, | ||
660 | .get_tree = bpf_get_tree, | ||
661 | }; | ||
662 | |||
663 | /* | ||
664 | * Set up the filesystem mount context. | ||
665 | */ | ||
666 | static int bpf_init_fs_context(struct fs_context *fc) | ||
667 | { | ||
668 | struct bpf_mount_opts *opts; | ||
669 | |||
670 | opts = kzalloc(sizeof(struct bpf_mount_opts), GFP_KERNEL); | ||
671 | if (!opts) | ||
672 | return -ENOMEM; | ||
673 | |||
674 | opts->mode = S_IRWXUGO; | ||
675 | |||
676 | fc->fs_private = opts; | ||
677 | fc->ops = &bpf_context_ops; | ||
678 | return 0; | ||
656 | } | 679 | } |
657 | 680 | ||
658 | static struct file_system_type bpf_fs_type = { | 681 | static struct file_system_type bpf_fs_type = { |
659 | .owner = THIS_MODULE, | 682 | .owner = THIS_MODULE, |
660 | .name = "bpf", | 683 | .name = "bpf", |
661 | .mount = bpf_mount, | 684 | .init_fs_context = bpf_init_fs_context, |
685 | .parameters = &bpf_fs_parameters, | ||
662 | .kill_sb = kill_litter_super, | 686 | .kill_sb = kill_litter_super, |
663 | }; | 687 | }; |
664 | 688 | ||