2424#include <linux/pid_namespace.h>
2525#include <linux/uaccess.h>
2626#include <linux/fs.h>
27+ #include <linux/fs_context.h>
28+ #include <linux/fs_parser.h>
2729#include <linux/vmalloc.h>
2830
2931#include <linux/coda.h>
@@ -87,10 +89,10 @@ void coda_destroy_inodecache(void)
8789 kmem_cache_destroy (coda_inode_cachep );
8890}
8991
90- static int coda_remount (struct super_block * sb , int * flags , char * data )
92+ static int coda_reconfigure (struct fs_context * fc )
9193{
92- sync_filesystem (sb );
93- * flags |= SB_NOATIME ;
94+ sync_filesystem (fc -> root -> d_sb );
95+ fc -> sb_flags |= SB_NOATIME ;
9496 return 0 ;
9597}
9698
@@ -102,78 +104,102 @@ static const struct super_operations coda_super_operations =
102104 .evict_inode = coda_evict_inode ,
103105 .put_super = coda_put_super ,
104106 .statfs = coda_statfs ,
105- .remount_fs = coda_remount ,
106107};
107108
108- static int get_device_index (struct coda_mount_data * data )
109+ struct coda_fs_context {
110+ int idx ;
111+ };
112+
113+ enum {
114+ Opt_fd ,
115+ };
116+
117+ static const struct fs_parameter_spec coda_param_specs [] = {
118+ fsparam_fd ("fd" , Opt_fd ),
119+ {}
120+ };
121+
122+ static int coda_parse_fd (struct fs_context * fc , int fd )
109123{
124+ struct coda_fs_context * ctx = fc -> fs_private ;
110125 struct fd f ;
111126 struct inode * inode ;
112127 int idx ;
113128
114- if (data == NULL ) {
115- pr_warn ("%s: Bad mount data\n" , __func__ );
116- return -1 ;
117- }
118-
119- if (data -> version != CODA_MOUNT_VERSION ) {
120- pr_warn ("%s: Bad mount version\n" , __func__ );
121- return -1 ;
122- }
123-
124- f = fdget (data -> fd );
129+ f = fdget (fd );
125130 if (!f .file )
126- goto Ebadf ;
131+ return - EBADF ;
127132 inode = file_inode (f .file );
128133 if (!S_ISCHR (inode -> i_mode ) || imajor (inode ) != CODA_PSDEV_MAJOR ) {
129134 fdput (f );
130- goto Ebadf ;
135+ return invalf ( fc , "code: Not coda psdev" ) ;
131136 }
132137
133138 idx = iminor (inode );
134139 fdput (f );
135140
136- if (idx < 0 || idx >= MAX_CODADEVS ) {
137- pr_warn ("%s: Bad minor number\n" , __func__ );
138- return -1 ;
141+ if (idx < 0 || idx >= MAX_CODADEVS )
142+ return invalf (fc , "coda: Bad minor number" );
143+ ctx -> idx = idx ;
144+ return 0 ;
145+ }
146+
147+ static int coda_parse_param (struct fs_context * fc , struct fs_parameter * param )
148+ {
149+ struct fs_parse_result result ;
150+ int opt ;
151+
152+ opt = fs_parse (fc , coda_param_specs , param , & result );
153+ if (opt < 0 )
154+ return opt ;
155+
156+ switch (opt ) {
157+ case Opt_fd :
158+ return coda_parse_fd (fc , result .uint_32 );
139159 }
140160
141- return idx ;
142- Ebadf :
143- pr_warn ("%s: Bad file\n" , __func__ );
144- return -1 ;
161+ return 0 ;
162+ }
163+
164+ /*
165+ * Parse coda's binary mount data form. We ignore any errors and go with index
166+ * 0 if we get one for backward compatibility.
167+ */
168+ static int coda_parse_monolithic (struct fs_context * fc , void * _data )
169+ {
170+ struct coda_mount_data * data = _data ;
171+
172+ if (!data )
173+ return invalf (fc , "coda: Bad mount data" );
174+
175+ if (data -> version != CODA_MOUNT_VERSION )
176+ return invalf (fc , "coda: Bad mount version" );
177+
178+ coda_parse_fd (fc , data -> fd );
179+ return 0 ;
145180}
146181
147- static int coda_fill_super (struct super_block * sb , void * data , int silent )
182+ static int coda_fill_super (struct super_block * sb , struct fs_context * fc )
148183{
184+ struct coda_fs_context * ctx = fc -> fs_private ;
149185 struct inode * root = NULL ;
150186 struct venus_comm * vc ;
151187 struct CodaFid fid ;
152188 int error ;
153- int idx ;
154-
155- if (task_active_pid_ns (current ) != & init_pid_ns )
156- return - EINVAL ;
157-
158- idx = get_device_index ((struct coda_mount_data * ) data );
159189
160- /* Ignore errors in data, for backward compatibility */
161- if (idx == -1 )
162- idx = 0 ;
163-
164- pr_info ("%s: device index: %i\n" , __func__ , idx );
190+ infof (fc , "coda: device index: %i\n" , ctx -> idx );
165191
166- vc = & coda_comms [idx ];
192+ vc = & coda_comms [ctx -> idx ];
167193 mutex_lock (& vc -> vc_mutex );
168194
169195 if (!vc -> vc_inuse ) {
170- pr_warn ( "%s : No pseudo device\n" , __func__ );
196+ errorf ( fc , "coda : No pseudo device" );
171197 error = - EINVAL ;
172198 goto unlock_out ;
173199 }
174200
175201 if (vc -> vc_sb ) {
176- pr_warn ( "%s : Device already mounted\n" , __func__ );
202+ errorf ( fc , "coda : Device already mounted" );
177203 error = - EBUSY ;
178204 goto unlock_out ;
179205 }
@@ -313,18 +339,45 @@ static int coda_statfs(struct dentry *dentry, struct kstatfs *buf)
313339 return 0 ;
314340}
315341
316- /* init_coda: used by filesystems.c to register coda */
342+ static int coda_get_tree (struct fs_context * fc )
343+ {
344+ if (task_active_pid_ns (current ) != & init_pid_ns )
345+ return - EINVAL ;
317346
318- static struct dentry * coda_mount (struct file_system_type * fs_type ,
319- int flags , const char * dev_name , void * data )
347+ return get_tree_nodev (fc , coda_fill_super );
348+ }
349+
350+ static void coda_free_fc (struct fs_context * fc )
320351{
321- return mount_nodev (fs_type , flags , data , coda_fill_super );
352+ kfree (fc -> fs_private );
353+ }
354+
355+ static const struct fs_context_operations coda_context_ops = {
356+ .free = coda_free_fc ,
357+ .parse_param = coda_parse_param ,
358+ .parse_monolithic = coda_parse_monolithic ,
359+ .get_tree = coda_get_tree ,
360+ .reconfigure = coda_reconfigure ,
361+ };
362+
363+ static int coda_init_fs_context (struct fs_context * fc )
364+ {
365+ struct coda_fs_context * ctx ;
366+
367+ ctx = kzalloc (sizeof (struct coda_fs_context ), GFP_KERNEL );
368+ if (!ctx )
369+ return - ENOMEM ;
370+
371+ fc -> fs_private = ctx ;
372+ fc -> ops = & coda_context_ops ;
373+ return 0 ;
322374}
323375
324376struct file_system_type coda_fs_type = {
325377 .owner = THIS_MODULE ,
326378 .name = "coda" ,
327- .mount = coda_mount ,
379+ .init_fs_context = coda_init_fs_context ,
380+ .parameters = coda_param_specs ,
328381 .kill_sb = kill_anon_super ,
329382 .fs_flags = FS_BINARY_MOUNTDATA ,
330383};
0 commit comments