@@ -43,7 +43,7 @@ module_param_named(metacopy, ovl_metacopy_def, bool, 0644);
43
43
MODULE_PARM_DESC (metacopy ,
44
44
"Default to on or off for the metadata only copy up feature" );
45
45
46
- enum {
46
+ enum ovl_opt {
47
47
Opt_lowerdir ,
48
48
Opt_upperdir ,
49
49
Opt_workdir ,
@@ -238,19 +238,8 @@ static int ovl_mount_dir_noesc(const char *name, struct path *path)
238
238
pr_err ("failed to resolve '%s': %i\n" , name , err );
239
239
goto out ;
240
240
}
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
- }
250
241
return 0 ;
251
242
252
- out_put :
253
- path_put_init (path );
254
243
out :
255
244
return err ;
256
245
}
@@ -268,68 +257,90 @@ static void ovl_unescape(char *s)
268
257
}
269
258
}
270
259
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 )
272
261
{
273
262
int err = - ENOMEM ;
274
263
char * tmp = kstrdup (name , GFP_KERNEL );
275
264
276
265
if (tmp ) {
277
266
ovl_unescape (tmp );
278
267
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
- }
286
268
kfree (tmp );
287
269
}
288
270
return err ;
289
271
}
290
272
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 )
293
275
{
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 );
300
278
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 );
304
281
305
282
/*
306
283
* Check whether upper path is read-only here to report failures
307
284
* early. Don't forget to recheck when the superblock is created
308
285
* as the mount attributes could change.
309
286
*/
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 );
313
292
}
293
+ return 0 ;
294
+ }
314
295
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 ;
320
302
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 );
331
314
}
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 ;
333
344
}
334
345
335
346
static 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)
417
428
for (nr = 0 ; nr < nr_lower ; nr ++ , l ++ ) {
418
429
memset (l , 0 , sizeof (* l ));
419
430
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);
421
436
if (err )
422
437
goto out_put ;
423
438
@@ -505,10 +520,8 @@ static int ovl_parse_param(struct fs_context *fc, struct fs_parameter *param)
505
520
err = ovl_parse_param_lowerdir (param -> string , fc );
506
521
break ;
507
522
case Opt_upperdir :
508
- fallthrough ;
509
523
case Opt_workdir :
510
- err = ovl_parse_param_upperdir (param -> string , fc ,
511
- (Opt_workdir == opt ));
524
+ err = ovl_parse_layer (fc , param , opt );
512
525
break ;
513
526
case Opt_default_permissions :
514
527
config -> default_permissions = true;
0 commit comments