99#include "orangefs-kernel.h"
1010#include "orangefs-bufmap.h"
1111
12- #include <linux/parser.h>
1312#include <linux/hashtable.h>
1413#include <linux/seq_file.h>
1514
@@ -22,18 +21,16 @@ LIST_HEAD(orangefs_superblocks);
2221DEFINE_SPINLOCK (orangefs_superblocks_lock );
2322
2423enum {
25- Opt_intr ,
2624 Opt_acl ,
25+ Opt_intr ,
2726 Opt_local_lock ,
28-
29- Opt_err
3027};
3128
32- static const match_table_t tokens = {
33- { Opt_acl , "acl" } ,
34- { Opt_intr , "intr" } ,
35- { Opt_local_lock , "local_lock" } ,
36- { Opt_err , NULL }
29+ const struct fs_parameter_spec orangefs_fs_param_spec [] = {
30+ fsparam_flag ( "acl" , Opt_acl ) ,
31+ fsparam_flag ( "intr" , Opt_intr ) ,
32+ fsparam_flag ( "local_lock" , Opt_local_lock ) ,
33+ {}
3734};
3835
3936uint64_t orangefs_features ;
@@ -51,48 +48,30 @@ static int orangefs_show_options(struct seq_file *m, struct dentry *root)
5148 return 0 ;
5249}
5350
54- static int parse_mount_options (struct super_block * sb , char * options ,
55- int silent )
51+ static int orangefs_parse_param (struct fs_context * fc ,
52+ struct fs_parameter * param )
5653{
57- struct orangefs_sb_info_s * orangefs_sb = ORANGEFS_SB (sb );
58- substring_t args [MAX_OPT_ARGS ];
59- char * p ;
60-
61- /*
62- * Force any potential flags that might be set from the mount
63- * to zero, ie, initialize to unset.
64- */
65- sb -> s_flags &= ~SB_POSIXACL ;
66- orangefs_sb -> flags &= ~ORANGEFS_OPT_INTR ;
67- orangefs_sb -> flags &= ~ORANGEFS_OPT_LOCAL_LOCK ;
68-
69- while ((p = strsep (& options , "," )) != NULL ) {
70- int token ;
71-
72- if (!* p )
73- continue ;
74-
75- token = match_token (p , tokens , args );
76- switch (token ) {
77- case Opt_acl :
78- sb -> s_flags |= SB_POSIXACL ;
79- break ;
80- case Opt_intr :
81- orangefs_sb -> flags |= ORANGEFS_OPT_INTR ;
82- break ;
83- case Opt_local_lock :
84- orangefs_sb -> flags |= ORANGEFS_OPT_LOCAL_LOCK ;
85- break ;
86- default :
87- goto fail ;
88- }
54+ struct orangefs_sb_info_s * orangefs_sb = fc -> s_fs_info ;
55+ struct fs_parse_result result ;
56+ int opt ;
57+
58+ opt = fs_parse (fc , orangefs_fs_param_spec , param , & result );
59+ if (opt < 0 )
60+ return opt ;
61+
62+ switch (opt ) {
63+ case Opt_acl :
64+ fc -> sb_flags |= SB_POSIXACL ;
65+ break ;
66+ case Opt_intr :
67+ orangefs_sb -> flags |= ORANGEFS_OPT_INTR ;
68+ break ;
69+ case Opt_local_lock :
70+ orangefs_sb -> flags |= ORANGEFS_OPT_LOCAL_LOCK ;
71+ break ;
8972 }
9073
9174 return 0 ;
92- fail :
93- if (!silent )
94- gossip_err ("Error: mount option [%s] is not supported.\n" , p );
95- return - EINVAL ;
9675}
9776
9877static void orangefs_inode_cache_ctor (void * req )
@@ -223,10 +202,20 @@ static int orangefs_statfs(struct dentry *dentry, struct kstatfs *buf)
223202 * Remount as initiated by VFS layer. We just need to reparse the mount
224203 * options, no need to signal pvfs2-client-core about it.
225204 */
226- static int orangefs_remount_fs (struct super_block * sb , int * flags , char * data )
205+ static int orangefs_reconfigure (struct fs_context * fc )
227206{
228- gossip_debug (GOSSIP_SUPER_DEBUG , "orangefs_remount_fs: called\n" );
229- return parse_mount_options (sb , data , 1 );
207+ struct super_block * sb = fc -> root -> d_sb ;
208+ struct orangefs_sb_info_s * orangefs_sb = ORANGEFS_SB (sb );
209+ struct orangefs_sb_info_s * revised = fc -> s_fs_info ;
210+ unsigned int flags ;
211+
212+ flags = orangefs_sb -> flags ;
213+ flags &= ~(ORANGEFS_OPT_INTR | ORANGEFS_OPT_LOCAL_LOCK );
214+ flags |= revised -> flags ;
215+ WRITE_ONCE (orangefs_sb -> flags , flags );
216+
217+ gossip_debug (GOSSIP_SUPER_DEBUG , "orangefs_reconfigure: called\n" );
218+ return 0 ;
230219}
231220
232221/*
@@ -319,7 +308,6 @@ static const struct super_operations orangefs_s_ops = {
319308 .write_inode = orangefs_write_inode ,
320309 .drop_inode = generic_delete_inode ,
321310 .statfs = orangefs_statfs ,
322- .remount_fs = orangefs_remount_fs ,
323311 .show_options = orangefs_show_options ,
324312};
325313
@@ -410,8 +398,8 @@ static int orangefs_unmount(int id, __s32 fs_id, const char *devname)
410398}
411399
412400static int orangefs_fill_sb (struct super_block * sb ,
413- struct orangefs_fs_mount_response * fs_mount ,
414- void * data , int silent )
401+ struct fs_context * fc ,
402+ struct orangefs_fs_mount_response * fs_mount )
415403{
416404 int ret ;
417405 struct inode * root ;
@@ -424,12 +412,6 @@ static int orangefs_fill_sb(struct super_block *sb,
424412 ORANGEFS_SB (sb )-> fs_id = fs_mount -> fs_id ;
425413 ORANGEFS_SB (sb )-> id = fs_mount -> id ;
426414
427- if (data ) {
428- ret = parse_mount_options (sb , data , silent );
429- if (ret )
430- return ret ;
431- }
432-
433415 /* Hang the xattr handlers off the superblock */
434416 sb -> s_xattr = orangefs_xattr_handlers ;
435417 sb -> s_magic = ORANGEFS_SUPER_MAGIC ;
@@ -470,30 +452,24 @@ static int orangefs_fill_sb(struct super_block *sb,
470452 return 0 ;
471453}
472454
473- struct dentry * orangefs_mount (struct file_system_type * fst ,
474- int flags ,
475- const char * devname ,
476- void * data )
455+ static int orangefs_get_tree (struct fs_context * fc )
477456{
478457 int ret ;
479458 struct super_block * sb = ERR_PTR (- EINVAL );
480459 struct orangefs_kernel_op_s * new_op ;
481- struct dentry * d = ERR_PTR (- EINVAL );
460+
461+ if (!fc -> source )
462+ return invalf (fc , "Device name not specified.\n" );
482463
483464 gossip_debug (GOSSIP_SUPER_DEBUG ,
484465 "orangefs_mount: called with devname %s\n" ,
485- devname );
486-
487- if (!devname ) {
488- gossip_err ("ERROR: device name not specified.\n" );
489- return ERR_PTR (- EINVAL );
490- }
466+ fc -> source );
491467
492468 new_op = op_alloc (ORANGEFS_VFS_OP_FS_MOUNT );
493469 if (!new_op )
494- return ERR_PTR ( - ENOMEM ) ;
470+ return - ENOMEM ;
495471
496- strscpy (new_op -> upcall .req .fs_mount .orangefs_config_server , devname );
472+ strscpy (new_op -> upcall .req .fs_mount .orangefs_config_server , fc -> source );
497473
498474 gossip_debug (GOSSIP_SUPER_DEBUG ,
499475 "Attempting ORANGEFS Mount via host %s\n" ,
@@ -511,37 +487,27 @@ struct dentry *orangefs_mount(struct file_system_type *fst,
511487 goto free_op ;
512488 }
513489
514- sb = sget ( fst , NULL , set_anon_super , flags , NULL );
490+ sb = sget_fc ( fc , NULL , set_anon_super_fc );
515491
516492 if (IS_ERR (sb )) {
517- d = ERR_CAST (sb );
493+ ret = PTR_ERR (sb );
518494 orangefs_unmount (new_op -> downcall .resp .fs_mount .id ,
519- new_op -> downcall .resp .fs_mount .fs_id , devname );
520- goto free_op ;
521- }
522-
523- /* alloc and init our private orangefs sb info */
524- sb -> s_fs_info = kzalloc (sizeof (struct orangefs_sb_info_s ), GFP_KERNEL );
525- if (!ORANGEFS_SB (sb )) {
526- d = ERR_PTR (- ENOMEM );
495+ new_op -> downcall .resp .fs_mount .fs_id ,
496+ fc -> source );
527497 goto free_op ;
528498 }
529499
530- ret = orangefs_fill_sb (sb ,
531- & new_op -> downcall .resp .fs_mount , data ,
532- flags & SB_SILENT ? 1 : 0 );
500+ /* init our private orangefs sb info */
501+ ret = orangefs_fill_sb (sb , fc , & new_op -> downcall .resp .fs_mount );
533502
534- if (ret ) {
535- d = ERR_PTR (ret );
503+ if (ret )
536504 goto free_sb_and_op ;
537- }
538505
539506 /*
540507 * on successful mount, store the devname and data
541508 * used
542509 */
543- strscpy (ORANGEFS_SB (sb )-> devname , devname );
544-
510+ strscpy (ORANGEFS_SB (sb )-> devname , fc -> source );
545511
546512 /* mount_pending must be cleared */
547513 ORANGEFS_SB (sb )-> mount_pending = 0 ;
@@ -564,7 +530,7 @@ struct dentry *orangefs_mount(struct file_system_type *fst,
564530 if (orangefs_userspace_version >= 20906 ) {
565531 new_op = op_alloc (ORANGEFS_VFS_OP_FEATURES );
566532 if (!new_op )
567- return ERR_PTR ( - ENOMEM ) ;
533+ return - ENOMEM ;
568534 new_op -> upcall .req .features .features = 0 ;
569535 ret = service_operation (new_op , "orangefs_features" , 0 );
570536 orangefs_features = new_op -> downcall .resp .features .features ;
@@ -573,7 +539,8 @@ struct dentry *orangefs_mount(struct file_system_type *fst,
573539 orangefs_features = 0 ;
574540 }
575541
576- return dget (sb -> s_root );
542+ fc -> root = dget (sb -> s_root );
543+ return 0 ;
577544
578545free_sb_and_op :
579546 /* Will call orangefs_kill_sb with sb not in list. */
@@ -589,7 +556,43 @@ struct dentry *orangefs_mount(struct file_system_type *fst,
589556
590557 op_release (new_op );
591558
592- return d ;
559+ return ret ;
560+ }
561+
562+ static void orangefs_free_fc (struct fs_context * fc )
563+ {
564+ kfree (fc -> s_fs_info );
565+ }
566+
567+ static const struct fs_context_operations orangefs_context_ops = {
568+ .free = orangefs_free_fc ,
569+ .parse_param = orangefs_parse_param ,
570+ .get_tree = orangefs_get_tree ,
571+ .reconfigure = orangefs_reconfigure ,
572+ };
573+
574+ /*
575+ * Set up the filesystem mount context.
576+ */
577+ int orangefs_init_fs_context (struct fs_context * fc )
578+ {
579+ struct orangefs_sb_info_s * osi ;
580+
581+ osi = kzalloc (sizeof (struct orangefs_sb_info_s ), GFP_KERNEL );
582+ if (!osi )
583+ return - ENOMEM ;
584+
585+ /*
586+ * Force any potential flags that might be set from the mount
587+ * to zero, ie, initialize to unset.
588+ */
589+ fc -> sb_flags_mask &= ~SB_POSIXACL ;
590+ osi -> flags &= ~ORANGEFS_OPT_INTR ;
591+ osi -> flags &= ~ORANGEFS_OPT_LOCAL_LOCK ;
592+
593+ fc -> s_fs_info = osi ;
594+ fc -> ops = & orangefs_context_ops ;
595+ return 0 ;
593596}
594597
595598void orangefs_kill_sb (struct super_block * sb )
0 commit comments