83
83
#include <linux/blkdev.h>
84
84
#include <linux/backing-dev.h>
85
85
#include <linux/init.h>
86
- #include <linux/parser.h>
86
+ #include <linux/fs_context.h>
87
+ #include <linux/fs_parser.h>
87
88
#include <linux/buffer_head.h>
88
89
#include <linux/vfs.h>
89
90
#include <linux/log2.h>
90
- #include <linux/mount.h>
91
91
#include <linux/seq_file.h>
92
92
#include <linux/iversion.h>
93
93
@@ -342,120 +342,74 @@ void ufs_warning (struct super_block * sb, const char * function,
342
342
va_end (args );
343
343
}
344
344
345
- enum {
346
- Opt_type_old = UFS_MOUNT_UFSTYPE_OLD ,
347
- Opt_type_sunx86 = UFS_MOUNT_UFSTYPE_SUNx86 ,
348
- Opt_type_sun = UFS_MOUNT_UFSTYPE_SUN ,
349
- Opt_type_sunos = UFS_MOUNT_UFSTYPE_SUNOS ,
350
- Opt_type_44bsd = UFS_MOUNT_UFSTYPE_44BSD ,
351
- Opt_type_ufs2 = UFS_MOUNT_UFSTYPE_UFS2 ,
352
- Opt_type_hp = UFS_MOUNT_UFSTYPE_HP ,
353
- Opt_type_nextstepcd = UFS_MOUNT_UFSTYPE_NEXTSTEP_CD ,
354
- Opt_type_nextstep = UFS_MOUNT_UFSTYPE_NEXTSTEP ,
355
- Opt_type_openstep = UFS_MOUNT_UFSTYPE_OPENSTEP ,
356
- Opt_onerror_panic = UFS_MOUNT_ONERROR_PANIC ,
357
- Opt_onerror_lock = UFS_MOUNT_ONERROR_LOCK ,
358
- Opt_onerror_umount = UFS_MOUNT_ONERROR_UMOUNT ,
359
- Opt_onerror_repair = UFS_MOUNT_ONERROR_REPAIR ,
360
- Opt_err
345
+ enum { Opt_type , Opt_onerror };
346
+
347
+ static const struct constant_table ufs_param_ufstype [] = {
348
+ {"old" , UFS_MOUNT_UFSTYPE_OLD },
349
+ {"sunx86" , UFS_MOUNT_UFSTYPE_SUNx86 },
350
+ {"sun" , UFS_MOUNT_UFSTYPE_SUN },
351
+ {"sunos" , UFS_MOUNT_UFSTYPE_SUNOS },
352
+ {"44bsd" , UFS_MOUNT_UFSTYPE_44BSD },
353
+ {"ufs2" , UFS_MOUNT_UFSTYPE_UFS2 },
354
+ {"5xbsd" , UFS_MOUNT_UFSTYPE_UFS2 },
355
+ {"hp" , UFS_MOUNT_UFSTYPE_HP },
356
+ {"nextstep-cd" , UFS_MOUNT_UFSTYPE_NEXTSTEP_CD },
357
+ {"nextstep" , UFS_MOUNT_UFSTYPE_NEXTSTEP },
358
+ {"openstep" , UFS_MOUNT_UFSTYPE_OPENSTEP },
359
+ {}
361
360
};
362
361
363
- static const match_table_t tokens = {
364
- {Opt_type_old , "ufstype=old" },
365
- {Opt_type_sunx86 , "ufstype=sunx86" },
366
- {Opt_type_sun , "ufstype=sun" },
367
- {Opt_type_sunos , "ufstype=sunos" },
368
- {Opt_type_44bsd , "ufstype=44bsd" },
369
- {Opt_type_ufs2 , "ufstype=ufs2" },
370
- {Opt_type_ufs2 , "ufstype=5xbsd" },
371
- {Opt_type_hp , "ufstype=hp" },
372
- {Opt_type_nextstepcd , "ufstype=nextstep-cd" },
373
- {Opt_type_nextstep , "ufstype=nextstep" },
374
- {Opt_type_openstep , "ufstype=openstep" },
375
- /*end of possible ufs types */
376
- {Opt_onerror_panic , "onerror=panic" },
377
- {Opt_onerror_lock , "onerror=lock" },
378
- {Opt_onerror_umount , "onerror=umount" },
379
- {Opt_onerror_repair , "onerror=repair" },
380
- {Opt_err , NULL }
362
+ static const struct constant_table ufs_param_onerror [] = {
363
+ {"panic" , UFS_MOUNT_ONERROR_PANIC },
364
+ {"lock" , UFS_MOUNT_ONERROR_LOCK },
365
+ {"umount" , UFS_MOUNT_ONERROR_UMOUNT },
366
+ {"repair" , UFS_MOUNT_ONERROR_REPAIR },
367
+ {}
381
368
};
382
369
383
- static int ufs_parse_options (char * options , unsigned * flavour , unsigned * on_err , bool remount )
370
+ static const struct fs_parameter_spec ufs_param_spec [] = {
371
+ fsparam_enum ("ufstype" , Opt_type , ufs_param_ufstype ),
372
+ fsparam_enum ("onerror" , Opt_onerror , ufs_param_onerror ),
373
+ {}
374
+ };
375
+
376
+ struct ufs_fs_context {
377
+ unsigned int flavour , on_err ;
378
+ };
379
+
380
+ static int ufs_parse_param (struct fs_context * fc , struct fs_parameter * param )
384
381
{
385
- char * p ;
386
-
382
+ struct ufs_fs_context * ctx = fc -> fs_private ;
383
+ struct fs_parse_result result ;
384
+ int opt ;
385
+
387
386
UFSD ("ENTER\n" );
388
-
389
- if (!options )
390
- return 1 ;
391
-
392
- while ((p = strsep (& options , "," )) != NULL ) {
393
- substring_t args [MAX_OPT_ARGS ];
394
- int token ;
395
- unsigned int old = * flavour ;
396
- if (!* p )
397
- continue ;
398
387
399
- token = match_token (p , tokens , args );
400
- switch (token ) {
401
- case Opt_type_old :
402
- * flavour = UFS_MOUNT_UFSTYPE_OLD ;
403
- break ;
404
- case Opt_type_sunx86 :
405
- * flavour = UFS_MOUNT_UFSTYPE_SUNx86 ;
406
- break ;
407
- case Opt_type_sun :
408
- * flavour = UFS_MOUNT_UFSTYPE_SUN ;
409
- break ;
410
- case Opt_type_sunos :
411
- * flavour = UFS_MOUNT_UFSTYPE_SUNOS ;
412
- break ;
413
- case Opt_type_44bsd :
414
- * flavour = UFS_MOUNT_UFSTYPE_44BSD ;
415
- break ;
416
- case Opt_type_ufs2 :
417
- * flavour = UFS_MOUNT_UFSTYPE_UFS2 ;
418
- break ;
419
- case Opt_type_hp :
420
- * flavour = UFS_MOUNT_UFSTYPE_HP ;
421
- break ;
422
- case Opt_type_nextstepcd :
423
- * flavour = UFS_MOUNT_UFSTYPE_NEXTSTEP_CD ;
424
- break ;
425
- case Opt_type_nextstep :
426
- * flavour = UFS_MOUNT_UFSTYPE_NEXTSTEP ;
427
- break ;
428
- case Opt_type_openstep :
429
- * flavour = UFS_MOUNT_UFSTYPE_OPENSTEP ;
430
- break ;
431
- case Opt_onerror_panic :
432
- * on_err = UFS_MOUNT_ONERROR_PANIC ;
433
- break ;
434
- case Opt_onerror_lock :
435
- * on_err = UFS_MOUNT_ONERROR_LOCK ;
436
- break ;
437
- case Opt_onerror_umount :
438
- * on_err = UFS_MOUNT_ONERROR_UMOUNT ;
439
- break ;
440
- case Opt_onerror_repair :
441
- * on_err = UFS_MOUNT_ONERROR_REPAIR ;
442
- pr_err ("Unable to do repair on error, will lock lock instead\n" );
443
- break ;
444
- default :
445
- pr_err ("Invalid option: \"%s\" or missing value\n" , p );
388
+ opt = fs_parse (fc , ufs_param_spec , param , & result );
389
+ if (opt < 0 )
390
+ return opt ;
391
+
392
+ switch (opt ) {
393
+ case Opt_type :
394
+ if (ctx -> flavour == result .uint_32 ) /* no-op */
446
395
return 0 ;
447
- }
448
- if (* flavour == old )
449
- continue ;
450
- if (!old )
451
- continue ;
452
- if (remount )
396
+ if (fc -> purpose == FS_CONTEXT_FOR_RECONFIGURE ) {
453
397
pr_err ("ufstype can't be changed during remount\n" );
454
- else
398
+ return - EINVAL ;
399
+ }
400
+ if (!ctx -> flavour ) {
455
401
pr_err ("conflicting ufstype options\n" );
456
- return 0 ;
402
+ return - EINVAL ;
403
+ }
404
+ ctx -> flavour = result .uint_32 ;
405
+ break ;
406
+ case Opt_onerror :
407
+ ctx -> on_err = result .uint_32 ;
408
+ break ;
409
+ default :
410
+ return - EINVAL ;
457
411
}
458
- return 1 ;
412
+ return 0 ;
459
413
}
460
414
461
415
/*
@@ -760,8 +714,10 @@ static u64 ufs_max_bytes(struct super_block *sb)
760
714
return res << uspi -> s_bshift ;
761
715
}
762
716
763
- static int ufs_fill_super (struct super_block * sb , void * data , int silent )
717
+ static int ufs_fill_super (struct super_block * sb , struct fs_context * fc )
764
718
{
719
+ struct ufs_fs_context * ctx = fc -> fs_private ;
720
+ int silent = fc -> sb_flags & SB_SILENT ;
765
721
struct ufs_sb_info * sbi ;
766
722
struct ufs_sb_private_info * uspi ;
767
723
struct ufs_super_block_first * usb1 ;
@@ -799,16 +755,10 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
799
755
mutex_init (& sbi -> s_lock );
800
756
spin_lock_init (& sbi -> work_lock );
801
757
INIT_DELAYED_WORK (& sbi -> sync_work , delayed_sync_fs );
802
- /*
803
- * Set default mount options
804
- * Parse mount options
805
- */
806
- sbi -> s_flavour = 0 ;
807
- sbi -> s_on_err = UFS_MOUNT_ONERROR_LOCK ;
808
- if (!ufs_parse_options (data , & sbi -> s_flavour , & sbi -> s_on_err , false)) {
809
- pr_err ("wrong mount options\n" );
810
- goto failed ;
811
- }
758
+
759
+ sbi -> s_flavour = ctx -> flavour ;
760
+ sbi -> s_on_err = ctx -> on_err ;
761
+
812
762
if (!sbi -> s_flavour ) {
813
763
if (!silent )
814
764
pr_err ("You didn't specify the type of your ufs filesystem\n\n"
@@ -1286,13 +1236,15 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
1286
1236
return - ENOMEM ;
1287
1237
}
1288
1238
1289
- static int ufs_remount (struct super_block * sb , int * mount_flags , char * data )
1239
+ static int ufs_reconfigure (struct fs_context * fc )
1290
1240
{
1291
1241
struct ufs_sb_private_info * uspi ;
1292
1242
struct ufs_super_block_first * usb1 ;
1293
1243
struct ufs_super_block_third * usb3 ;
1294
- unsigned on_err , ufstype ;
1295
- unsigned flags ;
1244
+ struct ufs_fs_context * ctx = fc -> fs_private ;
1245
+ struct super_block * sb = fc -> root -> d_sb ;
1246
+ unsigned int ufstype ;
1247
+ unsigned int flags ;
1296
1248
1297
1249
sync_filesystem (sb );
1298
1250
mutex_lock (& UFS_SB (sb )-> s_lock );
@@ -1301,27 +1253,18 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1301
1253
usb1 = ubh_get_usb_first (uspi );
1302
1254
usb3 = ubh_get_usb_third (uspi );
1303
1255
1304
- /*
1305
- * Allow the "check" option to be passed as a remount option.
1306
- * It is not possible to change ufstype option during remount
1307
- */
1308
1256
ufstype = UFS_SB (sb )-> s_flavour ;
1309
- on_err = UFS_MOUNT_ONERROR_LOCK ;
1310
- if (!ufs_parse_options (data , & ufstype , & on_err , true)) {
1311
- mutex_unlock (& UFS_SB (sb )-> s_lock );
1312
- return - EINVAL ;
1313
- }
1314
1257
1315
- if ((bool )(* mount_flags & SB_RDONLY ) == sb_rdonly (sb )) {
1316
- UFS_SB (sb )-> s_on_err = on_err ;
1258
+ if ((bool )(fc -> sb_flags & SB_RDONLY ) == sb_rdonly (sb )) {
1259
+ UFS_SB (sb )-> s_on_err = ctx -> on_err ;
1317
1260
mutex_unlock (& UFS_SB (sb )-> s_lock );
1318
1261
return 0 ;
1319
1262
}
1320
1263
1321
1264
/*
1322
1265
* fs was mouted as rw, remounting ro
1323
1266
*/
1324
- if (* mount_flags & SB_RDONLY ) {
1267
+ if (fc -> sb_flags & SB_RDONLY ) {
1325
1268
ufs_put_super_internal (sb );
1326
1269
usb1 -> fs_time = ufs_get_seconds (sb );
1327
1270
if ((flags & UFS_ST_MASK ) == UFS_ST_SUN
@@ -1357,7 +1300,7 @@ static int ufs_remount (struct super_block *sb, int *mount_flags, char *data)
1357
1300
sb -> s_flags &= ~SB_RDONLY ;
1358
1301
#endif
1359
1302
}
1360
- UFS_SB (sb )-> s_on_err = on_err ;
1303
+ UFS_SB (sb )-> s_on_err = ctx -> on_err ;
1361
1304
mutex_unlock (& UFS_SB (sb )-> s_lock );
1362
1305
return 0 ;
1363
1306
}
@@ -1366,18 +1309,18 @@ static int ufs_show_options(struct seq_file *seq, struct dentry *root)
1366
1309
{
1367
1310
struct ufs_sb_info * sbi = UFS_SB (root -> d_sb );
1368
1311
unsigned mval = sbi -> s_flavour ;
1369
- const struct match_token * tp = tokens ;
1312
+ const struct constant_table * tp ;
1370
1313
1371
- while (tp -> token != Opt_onerror_panic && tp -> token != mval )
1314
+ tp = ufs_param_ufstype ;
1315
+ while (tp -> value && tp -> value != mval )
1372
1316
++ tp ;
1373
- BUG_ON (tp -> token == Opt_onerror_panic );
1374
- seq_printf (seq , ",%s" , tp -> pattern );
1317
+ seq_printf (seq , ",ufstype=%s" , tp -> name );
1375
1318
1319
+ tp = ufs_param_onerror ;
1376
1320
mval = sbi -> s_on_err ;
1377
- while (tp -> token != Opt_err && tp -> token != mval )
1321
+ while (tp -> value && tp -> value != mval )
1378
1322
++ tp ;
1379
- BUG_ON (tp -> token == Opt_err );
1380
- seq_printf (seq , ",%s" , tp -> pattern );
1323
+ seq_printf (seq , ",onerror=%s" , tp -> name );
1381
1324
1382
1325
return 0 ;
1383
1326
}
@@ -1471,21 +1414,57 @@ static const struct super_operations ufs_super_ops = {
1471
1414
.put_super = ufs_put_super ,
1472
1415
.sync_fs = ufs_sync_fs ,
1473
1416
.statfs = ufs_statfs ,
1474
- .remount_fs = ufs_remount ,
1475
1417
.show_options = ufs_show_options ,
1476
1418
};
1477
1419
1478
- static struct dentry * ufs_mount (struct file_system_type * fs_type ,
1479
- int flags , const char * dev_name , void * data )
1420
+ static int ufs_get_tree (struct fs_context * fc )
1480
1421
{
1481
- return mount_bdev (fs_type , flags , dev_name , data , ufs_fill_super );
1422
+ return get_tree_bdev (fc , ufs_fill_super );
1423
+ }
1424
+
1425
+ static void ufs_free_fc (struct fs_context * fc )
1426
+ {
1427
+ kfree (fc -> fs_private );
1428
+ }
1429
+
1430
+ static const struct fs_context_operations ufs_context_ops = {
1431
+ .parse_param = ufs_parse_param ,
1432
+ .get_tree = ufs_get_tree ,
1433
+ .reconfigure = ufs_reconfigure ,
1434
+ .free = ufs_free_fc ,
1435
+ };
1436
+
1437
+ static int ufs_init_fs_context (struct fs_context * fc )
1438
+ {
1439
+ struct ufs_fs_context * ctx ;
1440
+
1441
+ ctx = kzalloc (sizeof (* ctx ), GFP_KERNEL );
1442
+ if (!ctx )
1443
+ return - ENOMEM ;
1444
+
1445
+ if (fc -> purpose == FS_CONTEXT_FOR_RECONFIGURE ) {
1446
+ struct super_block * sb = fc -> root -> d_sb ;
1447
+ struct ufs_sb_info * sbi = UFS_SB (sb );
1448
+
1449
+ ctx -> flavour = sbi -> s_flavour ;
1450
+ ctx -> on_err = sbi -> s_on_err ;
1451
+ } else {
1452
+ ctx -> flavour = 0 ;
1453
+ ctx -> on_err = UFS_MOUNT_ONERROR_LOCK ;
1454
+ }
1455
+
1456
+ fc -> fs_private = ctx ;
1457
+ fc -> ops = & ufs_context_ops ;
1458
+
1459
+ return 0 ;
1482
1460
}
1483
1461
1484
1462
static struct file_system_type ufs_fs_type = {
1485
1463
.owner = THIS_MODULE ,
1486
1464
.name = "ufs" ,
1487
- .mount = ufs_mount ,
1488
1465
.kill_sb = kill_block_super ,
1466
+ .init_fs_context = ufs_init_fs_context ,
1467
+ .parameters = ufs_param_spec ,
1489
1468
.fs_flags = FS_REQUIRES_DEV ,
1490
1469
};
1491
1470
MODULE_ALIAS_FS ("ufs" );
0 commit comments