@@ -43,7 +43,7 @@ module_param_named(metacopy, ovl_metacopy_def, bool, 0644);
4343MODULE_PARM_DESC (metacopy ,
4444 "Default to on or off for the metadata only copy up feature" );
4545
46- enum {
46+ enum ovl_opt {
4747 Opt_lowerdir ,
4848 Opt_upperdir ,
4949 Opt_workdir ,
@@ -238,19 +238,8 @@ static int ovl_mount_dir_noesc(const char *name, struct path *path)
238238 pr_err ("failed to resolve '%s': %i\n" , name , err );
239239 goto out ;
240240 }
241- err = - EINVAL ;
242- if (ovl_dentry_weird (path -> dentry )) {
243- pr_err ("filesystem on '%s' not supported\n" , name );
244- goto out_put ;
245- }
246- if (!d_is_dir (path -> dentry )) {
247- pr_err ("'%s' not a directory\n" , name );
248- goto out_put ;
249- }
250241 return 0 ;
251242
252- out_put :
253- path_put_init (path );
254243out :
255244 return err ;
256245}
@@ -268,68 +257,90 @@ static void ovl_unescape(char *s)
268257 }
269258}
270259
271- static int ovl_mount_dir (const char * name , struct path * path , bool upper )
260+ static int ovl_mount_dir (const char * name , struct path * path )
272261{
273262 int err = - ENOMEM ;
274263 char * tmp = kstrdup (name , GFP_KERNEL );
275264
276265 if (tmp ) {
277266 ovl_unescape (tmp );
278267 err = ovl_mount_dir_noesc (tmp , path );
279-
280- if (!err && upper && path -> dentry -> d_flags & DCACHE_OP_REAL ) {
281- pr_err ("filesystem on '%s' not supported as upperdir\n" ,
282- tmp );
283- path_put_init (path );
284- err = - EINVAL ;
285- }
286268 kfree (tmp );
287269 }
288270 return err ;
289271}
290272
291- static int ovl_parse_param_upperdir ( const char * name , struct fs_context * fc ,
292- bool workdir )
273+ static int ovl_mount_dir_check ( struct fs_context * fc , const struct path * path ,
274+ enum ovl_opt layer , const char * name , bool upper )
293275{
294- int err ;
295- struct ovl_fs * ofs = fc -> s_fs_info ;
296- struct ovl_config * config = & ofs -> config ;
297- struct ovl_fs_context * ctx = fc -> fs_private ;
298- struct path path ;
299- char * dup ;
276+ if (ovl_dentry_weird (path -> dentry ))
277+ return invalfc (fc , "filesystem on %s not supported" , name );
300278
301- err = ovl_mount_dir (name , & path , true);
302- if (err )
303- return err ;
279+ if (!d_is_dir (path -> dentry ))
280+ return invalfc (fc , "%s is not a directory" , name );
304281
305282 /*
306283 * Check whether upper path is read-only here to report failures
307284 * early. Don't forget to recheck when the superblock is created
308285 * as the mount attributes could change.
309286 */
310- if (__mnt_is_readonly (path .mnt )) {
311- path_put (& path );
312- return - EINVAL ;
287+ if (upper ) {
288+ if (path -> dentry -> d_flags & DCACHE_OP_REAL )
289+ return invalfc (fc , "filesystem on %s not supported as upperdir" , name );
290+ if (__mnt_is_readonly (path -> mnt ))
291+ return invalfc (fc , "filesystem on %s is read-only" , name );
313292 }
293+ return 0 ;
294+ }
314295
315- dup = kstrdup (name , GFP_KERNEL );
316- if (!dup ) {
317- path_put (& path );
318- return - ENOMEM ;
319- }
296+ static void ovl_add_layer (struct fs_context * fc , enum ovl_opt layer ,
297+ struct path * path , char * * pname )
298+ {
299+ struct ovl_fs * ofs = fc -> s_fs_info ;
300+ struct ovl_config * config = & ofs -> config ;
301+ struct ovl_fs_context * ctx = fc -> fs_private ;
320302
321- if (workdir ) {
322- kfree (config -> workdir );
323- config -> workdir = dup ;
324- path_put (& ctx -> work );
325- ctx -> work = path ;
326- } else {
327- kfree (config -> upperdir );
328- config -> upperdir = dup ;
329- path_put (& ctx -> upper );
330- ctx -> upper = path ;
303+ switch (layer ) {
304+ case Opt_workdir :
305+ swap (config -> workdir , * pname );
306+ swap (ctx -> work , * path );
307+ break ;
308+ case Opt_upperdir :
309+ swap (config -> upperdir , * pname );
310+ swap (ctx -> upper , * path );
311+ break ;
312+ default :
313+ WARN_ON (1 );
331314 }
332- return 0 ;
315+ }
316+
317+ static int ovl_parse_layer (struct fs_context * fc , struct fs_parameter * param ,
318+ enum ovl_opt layer )
319+ {
320+ char * name = kstrdup (param -> string , GFP_KERNEL );
321+ bool upper = (layer == Opt_upperdir || layer == Opt_workdir );
322+ struct path path ;
323+ int err ;
324+
325+ if (!name )
326+ return - ENOMEM ;
327+
328+ err = ovl_mount_dir (name , & path );
329+ if (err )
330+ goto out_free ;
331+
332+ err = ovl_mount_dir_check (fc , & path , layer , name , upper );
333+ if (err )
334+ goto out_put ;
335+
336+ /* Store the user provided path string in ctx to show in mountinfo */
337+ ovl_add_layer (fc , layer , & path , & name );
338+
339+ out_put :
340+ path_put (& path );
341+ out_free :
342+ kfree (name );
343+ return err ;
333344}
334345
335346static void ovl_reset_lowerdirs (struct ovl_fs_context * ctx )
@@ -417,7 +428,11 @@ static int ovl_parse_param_lowerdir(const char *name, struct fs_context *fc)
417428 for (nr = 0 ; nr < nr_lower ; nr ++ , l ++ ) {
418429 memset (l , 0 , sizeof (* l ));
419430
420- err = ovl_mount_dir (iter , & l -> path , false);
431+ err = ovl_mount_dir (iter , & l -> path );
432+ if (err )
433+ goto out_put ;
434+
435+ err = ovl_mount_dir_check (fc , & l -> path , Opt_lowerdir , iter , false);
421436 if (err )
422437 goto out_put ;
423438
@@ -505,10 +520,8 @@ static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param)
505520 err = ovl_parse_param_lowerdir (param -> string , fc );
506521 break ;
507522 case Opt_upperdir :
508- fallthrough ;
509523 case Opt_workdir :
510- err = ovl_parse_param_upperdir (param -> string , fc ,
511- (Opt_workdir == opt ));
524+ err = ovl_parse_layer (fc , param , opt );
512525 break ;
513526 case Opt_default_permissions :
514527 config -> default_permissions = true;
0 commit comments