aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux/filesystem.txt
blob: d97f64fa0d272cbb02b0a25569bb2b123b958a0e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
# Copyright 2018 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

include <uapi/linux/mount.h>
include <linux/fs.h>
include <linux/fcntl.h>

mount(src ptr[in, blockdev_filename], dst ptr[in, filename], type ptr[in, string[filesystem]], flags flags[mount_flags], data ptr[in, string, opt])
umount2(path ptr[in, filename], flags flags[umount_flags])

mount$bpf(src const[0], dst ptr[in, filename], type ptr[in, string["bpf"]], flags flags[mount_flags], opts ptr[in, fs_options[bpf_options]])
mount$overlay(src const[0], dst ptr[in, filename], type ptr[in, string["overlay"]], flags flags[mount_flags], opts ptr[in, fs_options[overlay_options]])
mount$binder(src const[0], dst ptr[in, filename], type ptr[in, string["binder"]], flags flags[mount_flags], opts ptr[in, fs_options[binder_options]])
mount$tmpfs(src const[0], dst ptr[in, filename], type ptr[in, string["tmpfs"]], flags flags[mount_flags], opts ptr[in, fs_options[tmpfs_options]])
mount$cgroup(src const[0], dst ptr[in, filename], type ptr[in, string["cgroup"]], flags flags[mount_flags], opts ptr[in, fs_options[cgroup_options]])
mount$cgroup2(src const[0], dst ptr[in, filename], type ptr[in, string["cgroup2"]], flags flags[mount_flags], opts ptr[in, fs_options[cgroup2_options]])
mount$afs(src ptr[in, afs_source], dst ptr[in, filename], type ptr[in, string["afs"]], flags flags[mount_flags], opts ptr[in, fs_options[afs_options]])

# A bind mount ignores the filesystem type argument, but
# pkg/host/syscalls_linux.go:isSupportedFilesystem() requires one in
# /proc/filesystems.  Use a common and valid filesystem string ("pipefs") to
# pass the check.
mount$bind(src ptr[in, filename], dst ptr[in, filename], type ptr[in, string["pipefs"]], flags flags[mount_flags], data const[0])

# esdfs is ChromeOS-specific:
# https://chromium.googlesource.com/chromiumos/third_party/kernel/+/d2c1fb9fcdb53%5E%21/
mount$esdfs(src ptr[in, filename], dst ptr[in, filename], type ptr[in, string["esdfs"]], flags flags[mount_flags], opts ptr[in, fs_options[esdfs_options]])

# TODO: pvfs2 requires some device/source, but it looks unused:
# https://elixir.bootlin.com/linux/v6.1-rc6/source/fs/orangefs/super.c#L488
# Instead it sends requests to some pvfs2-req character device,
# and somebody is supposed to answer these requests with ioctls.
# But the deivce is not even created in /dev, somebody is supposed to mknod it.
# And it's major number is unknown (printed to console in debug mode only):
# https://elixir.bootlin.com/linux/v6.1-rc6/source/fs/orangefs/devorangefs-req.c#L803
# It does not look usable.
mount$pvfs2(src ptr[in, string["unused"]], dst ptr[in, filename], type ptr[in, string["pvfs2"]], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]])

# TODO: nfs source is "hostname:export_path", but we also needs to setup port,
# protocol and other options, and most importantly we need the server to reply to RPCs.
# There is something called nfsd (fs/nfsd) which may help and which we need to test as well.
mount$nfs(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["nfs"]], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]])
mount$nfs4(src ptr[in, string], dst ptr[in, filename], type ptr[in, string["nfs4"]], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]])

resource fd_fscontext[fd]

fsopen(type ptr[in, string[filesystem]], flags flags[fsopen_flags]) fd_fscontext
fspick(dfd fd_dir[opt], path ptr[in, filename], flags flags[fspick_flags]) fd_fscontext
fsconfig$FSCONFIG_SET_FLAG(fd fd_fscontext, cmd const[FSCONFIG_SET_FLAG], key ptr[in, string[fsconfig_flag_params]], value const[0], aux const[0])
fsconfig$FSCONFIG_SET_STRING(fd fd_fscontext, cmd const[FSCONFIG_SET_STRING], key ptr[in, string], value ptr[in, string], aux const[0])
fsconfig$FSCONFIG_SET_BINARY(fd fd_fscontext, cmd const[FSCONFIG_SET_BINARY], key ptr[in, string], value ptr[in, array[int8]], aux bytesize[value])
fsconfig$FSCONFIG_SET_PATH(fd fd_fscontext, cmd const[FSCONFIG_SET_PATH], key ptr[in, string], value ptr[in, filename], aux fd_dir[opt])
fsconfig$FSCONFIG_SET_PATH_EMPTY(fd fd_fscontext, cmd const[FSCONFIG_SET_PATH_EMPTY], key ptr[in, string], value ptr[in, filename], aux fd_dir[opt])
fsconfig$FSCONFIG_SET_FD(fd fd_fscontext, cmd const[FSCONFIG_SET_FD], key ptr[in, string], value const[0], aux fd)
fsconfig$FSCONFIG_CMD_CREATE(fd fd_fscontext, cmd const[FSCONFIG_CMD_CREATE], key const[0], value const[0], aux const[0])
fsconfig$FSCONFIG_CMD_RECONFIGURE(fd fd_fscontext, cmd const[FSCONFIG_CMD_RECONFIGURE], key const[0], value const[0], aux const[0])
fsmount(fs_fd fd_fscontext, flags flags[fsmount_flags], attr_flags flags[fsmount_attr_flags]) fd
move_mount(from_dfd fd_dir[opt], from_pathname ptr[in, filename], to_dfd fd_dir[opt], to_pathname ptr[in, filename], flags flags[move_mount_flags])
open_tree(dfd fd_dir[opt], filename ptr[in, filename], flags flags[open_tree_flags]) fd
mount_setattr(dfd fd_dir[opt], filename ptr[in, filename], flags flags[mount_setattr_flags], args ptr[in, mount_attr], size bytesize[args])

open_tree_flags = AT_EMPTY_PATH, AT_NO_AUTOMOUNT, AT_RECURSIVE, AT_SYMLINK_NOFOLLOW, OPEN_TREE_CLONE, OPEN_TREE_CLOEXEC

mount_setattr_flags = AT_EMPTY_PATH, AT_NO_AUTOMOUNT, AT_RECURSIVE, AT_SYMLINK_NOFOLLOW

mount_attr {
	attr_set	flags[mount_attr_flags, int64]
	attr_clr	flags[mount_attr_flags, int64]
	propagation	flags[mount_attr_propagation_flags, int64]
	userns_fd	align64[fd_userns]
}

mount_attr_flags = MOUNT_ATTR_IDMAP, fsmount_attr_flags
mount_attr_propagation_flags = MS_UNBINDABLE, MS_PRIVATE, MS_SLAVE, MS_SHARED
fsmount_flags = FSMOUNT_CLOEXEC
fsopen_flags = FSOPEN_CLOEXEC
fspick_flags = FSPICK_CLOEXEC
fsmount_attr_flags = MOUNT_ATTR_RDONLY, MOUNT_ATTR_NOSUID, MOUNT_ATTR_NODEV, MOUNT_ATTR_NOEXEC, MOUNT_ATTR__ATIME, MOUNT_ATTR_NODIRATIME
move_mount_flags = MOVE_MOUNT_F_SYMLINKS, MOVE_MOUNT_F_AUTOMOUNTS, MOVE_MOUNT_F_EMPTY_PATH, MOVE_MOUNT_T_SYMLINKS, MOVE_MOUNT_T_AUTOMOUNTS, MOVE_MOUNT_T_EMPTY_PATH, MOVE_MOUNT_SET_GROUP, MOVE_MOUNT_BENEATH
fsconfig_flag_params = "dirsync", "lazytime", "mand", "posixacl", "ro", "sync", "async", "nolazytime", "nomand", "rw", "silent"

filesystem = "sysfs", "rootfs", "ramfs", "tmpfs", "devtmpfs", "debugfs", "securityfs", "sockfs", "pipefs", "anon_inodefs", "devpts", "hugetlbfs", "vfat", "ecryptfs", "fuseblk", "fuse", "rpc_pipefs", "nfs", "nfs4", "nfsd", "binfmt_misc", "autofs", "xfs", "jfs", "msdos", "ntfs", "ntfs3", "minix", "hfs", "hfsplus", "qnx4", "ufs", "btrfs", "configfs", "ncpfs", "qnx6", "exofs", "befs", "vxfs", "gfs2", "gfs2meta", "fusectl", "bfs", "nsfs", "efs", "cifs", "efivarfs", "affs", "tracefs", "bdev", "ocfs2", "ocfs2_dlmfs", "hpfs", "proc", "afs", "reiserfs", "jffs2", "romfs", "aio", "sysv", "v7", "udf", "ceph", "pstore", "adfs", "9p", "hostfs", "squashfs", "cramfs", "iso9660", "coda", "nilfs2", "logfs", "overlay", "f2fs", "omfs", "ubifs", "openpromfs", "bpf", "cgroup", "cgroup2", "cpuset", "mqueue", "aufs", "selinuxfs", "dax", "erofs", "virtiofs", "exfat", "binder", "zonefs", "pvfs2", "incremental-fs", "esdfs", "smb3", "gadgetfs", ext4_types

blockdev_filename [
	filename	filename
	nbd		nbd_filename
	loop		loop_filename
	nullb		string["/dev/nullb0"]
	rnullb		string["/dev/rnullb0"]
	md0		string["/dev/md0"]
	sg0		string["/dev/sg0"]
	sr0		string["/dev/sr0"]
] [varlen]

nbd_filename {
	prefix	stringnoz["/dev/nbd"]
# NEED: this does not support formatting numbers larger than 9.
	id	proc['0', 1, int8]
	z	const[0, int8]
} [packed]

loop_filename {
	prefix	stringnoz["/dev/loop"]
# NEED: this does not support formatting numbers larger than 9.
	id	proc['0', 1, int8]
	z	const[0, int8]
} [packed]

syz_read_part_table(size len[img], img ptr[in, compressed_image]) (timeout[200], no_generate, no_minimize)

define SYZ_MOUNT_IMAGE_TIMEOUT	4000

syz_mount_image$vfat(fs ptr[in, string["vfat"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[vfat_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.vfat -n"])
syz_mount_image$msdos(fs ptr[in, string["msdos"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[msdos_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.msdos -n"])
syz_mount_image$bfs(fs ptr[in, string["bfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$xfs(fs ptr[in, string["xfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[xfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["xfs_repair -n"])
syz_mount_image$minix(fs ptr[in, string["minix"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.minix"])
syz_mount_image$reiserfs(fs ptr[in, string["reiserfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[reiserfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.reiserfs -n"])
syz_mount_image$hfs(fs ptr[in, string["hfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[hfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$hfsplus(fs ptr[in, string["hfsplus"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[hfsplus_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$iso9660(fs ptr[in, string["iso9660"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[iso9660_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$gfs2(fs ptr[in, string["gfs2"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[gfs2_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.gfs2 -n"])
syz_mount_image$jfs(fs ptr[in, string["jfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[jfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.jfs -n"])
syz_mount_image$btrfs(fs ptr[in, string["btrfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[btrfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["btrfsck --readonly"])
syz_mount_image$ntfs(fs ptr[in, string["ntfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ntfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$ntfs3(fs ptr[in, string["ntfs3"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ntfs3_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$ext4(fs ptr[in, string[ext4_types]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ext4_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.ext4 -n"])
syz_mount_image$f2fs(fs ptr[in, string["f2fs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[f2fs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.f2fs"])
syz_mount_image$ocfs2(fs ptr[in, string["ocfs2"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ocfs2_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.ocfs2 -n"])
syz_mount_image$erofs(fs ptr[in, string["erofs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[erofs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.erofs"])
syz_mount_image$exfat(fs ptr[in, string["exfat"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[exfat_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.exfat -n"])
syz_mount_image$cramfs(fs ptr[in, string["cramfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize, fsck["fsck.cramfs"])
syz_mount_image$romfs(fs ptr[in, string["romfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$efs(fs ptr[in, string["efs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$jffs2(fs ptr[in, string["jffs2"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[jffs2_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$nilfs2(fs ptr[in, string["nilfs2"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[nilfs2_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$squashfs(fs ptr[in, string["squashfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[squashfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$udf(fs ptr[in, string["udf"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[udf_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$bcachefs(fs ptr[in, string["bcachefs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[bcachefs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)

# TODO: zonefs needs a zoned block device:
# https://elixir.bootlin.com/linux/v6.1-rc6/source/fs/zonefs/super.c#L1768
# So currnetly the mount always fails.
# These docs say such devices can be emulated with nullb, but need special setup:
# https://zonedstorage.io/docs/getting-started/zbd-emulation
# https://btrfs.wiki.kernel.org/index.php/Zoned
syz_mount_image$zonefs(fs ptr[in, string["zonefs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[zonefs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)

# TODO: ubifs needs a special ubi device:
# https://elixir.bootlin.com/linux/v6.1-rc6/source/fs/ubifs/super.c#L2063
# So currnetly the mount always fails.
syz_mount_image$ubifs(fs ptr[in, string["ubifs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ubifs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)

# TODO: add mount options for the following file systems.
syz_mount_image$adfs(fs ptr[in, string["adfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[adfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$affs(fs ptr[in, string["affs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[affs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$befs(fs ptr[in, string["befs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$vxfs(fs ptr[in, string["vxfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[vxfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$omfs(fs ptr[in, string["omfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[omfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$hpfs(fs ptr[in, string["hpfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[hpfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$qnx4(fs ptr[in, string["qnx4"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$qnx6(fs ptr[in, string["qnx6"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[qnx6_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$sysv(fs ptr[in, string["sysv"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$ufs(fs ptr[in, string["ufs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[ufs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$gfs2meta(fs ptr[in, string["gfs2meta"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)
syz_mount_image$v7(fs ptr[in, string["v7"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[stringnoz]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)

# Note: tmpfs does not need an image, but we use this in tests.
syz_mount_image$tmpfs(fs ptr[in, string["tmpfs"]], dir ptr[in, filename], flags flags[mount_flags], opts ptr[in, fs_options[tmpfs_options]], chdir bool8, size len[img], img ptr[in, compressed_image]) fd_dir (timeout[SYZ_MOUNT_IMAGE_TIMEOUT], no_generate, no_minimize)

type fs_options[ELEMS] {
	elems	array[fs_opt_elem[ELEMS]]
	common	array[fs_opt_elem[fs_options_common]]
	null	const[0, int8]
} [packed]

type fs_opt_elem[ELEMS] {
	elem	ELEMS
	comma	const[',', int8]
} [packed]

type fs_opt[NAME, TYPE] {
	name	stringnoz[NAME]
	eq	const['=', int8]
	val	TYPE
} [packed]

type fs_opt_nodelim[NAME, TYPE] {
	name	stringnoz[NAME]
	val	TYPE
} [packed]

type fs_opt_str[NAME] fs_opt[NAME, stringnoz]
type fs_opt_dec[NAME, VAL] fs_opt[NAME, fmt[dec, VAL]]
type fs_opt_hex[NAME, VAL] fs_opt[NAME, fmt[hex, VAL]]
type fs_opt_oct[NAME, VAL] fs_opt[NAME, fmt[oct, VAL]]
type fs_opt_dec_suffix[NAME] fs_opt[NAME, array[flags[fs_opt_digits_suffix, int8]]]
type fs_opt_filename[NAME] fs_opt[NAME, stringnoz[filename]]
type fs_opt_codepage[NAME] fs_opt[NAME, stringnoz[codepages_names]]
type fs_opt_cp_num[NAME] fs_opt[NAME, stringnoz[codepage_nums]]

fs_opt_digits_suffix = '-', 'x', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'k', 'm', 'g', 't', 'p', 'e', '%'

fs_options_common [
	flag			stringnoz[fsconfig_flag_params]

# SELinux options:
	context			fs_opt["context", stringnoz[selinux_user_context]]
	fscontext		fs_opt["fscontext", stringnoz[selinux_user_context]]
	rootcontext		fs_opt["rootcontext", stringnoz[selinux_user_context]]
	defcontext		fs_opt["defcontext", stringnoz[selinux_user_context]]
	seclabel		stringnoz["seclabel"]

# Smack options:
	smackfsdef		fs_opt_str["smackfsdef"]
	smackfsfloor		fs_opt_str["smackfsfloor"]
	smackfshat		fs_opt_str["smackfshat"]
	smackfsroot		fs_opt_str["smackfsroot"]
	smackfstransmute	fs_opt_str["smackfstransmute"]

# IMA options:
	measure			stringnoz["measure"]
	dont_measure		stringnoz["dont_measure"]
	appraise		stringnoz["appraise"]
	dont_appraise		stringnoz["dont_appraise"]
	audit			stringnoz["audit"]
	hash			stringnoz["hash"]
	dont_hash		stringnoz["dont_hash"]
	permit_directio		stringnoz["permit_directio"]
	obj_user		fs_opt_str["obj_user"]
	obj_role		fs_opt_str["obj_role"]
	obj_type		fs_opt_str["obj_type"]
	subj_user		fs_opt_str["subj_user"]
	subj_role		fs_opt_str["subj_role"]
	subj_type		fs_opt_str["subj_type"]
	func			fs_opt["func", stringnoz[ima_funcs]]
	mask			fs_opt["mask", stringnoz[ima_masks]]
	fsmagic			fs_opt_hex["fsmagic", intptr]
	fsname			fs_opt_str["fsname"]
	fsuuid			fs_opt["fsuuid", uuid_str]
	uid_eq			fs_opt_dec["uid", uid]
	euid_eq			fs_opt_dec["euid", uid]
	fowner_eq		fs_opt_dec["fowner", uid]
	uid_gt			fs_opt_nodelim["uid>", fmt[dec, uid]]
	euid_gt			fs_opt_nodelim["euid>", fmt[dec, uid]]
	fowner_gt		fs_opt_nodelim["fowner>", fmt[dec, uid]]
	uid_lt			fs_opt_nodelim["uid<", fmt[dec, uid]]
	euid_lt			fs_opt_nodelim["euid<", fmt[dec, uid]]
	fowner_lt		fs_opt_nodelim["fowner<", fmt[dec, uid]]
	appraise_type		stringnoz["appraise_type=imasig"]
	pcr			fs_opt_dec["pcr", int64[0:64]]
] [varlen]

uuid_str {
	p0	array[flags[hex_chars, int8], 8]
	d0	const['-', int8]
	p1	array[flags[hex_chars, int8], 4]
	d1	const['-', int8]
	p2	array[flags[hex_chars, int8], 4]
	d2	const['-', int8]
	p3	array[flags[hex_chars, int8], 4]
	d3	const['-', int8]
	p4	array[flags[hex_chars, int8], 8]
}

hex_chars = '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'

ima_funcs = "FILE_CHECK", "PATH_CHECK", "MODULE_CHECK", "FIRMWARE_CHECK", "FILE_MMAP", "MMAP_CHECK", "BPRM_CHECK", "CREDS_CHECK", "KEXEC_KERNEL_CHECK", "KEXEC_INITRAMFS_CHECK", "POLICY_CHECK"
ima_masks = "MAY_EXEC", "MAY_WRITE", "MAY_READ", "MAY_APPEND", "^MAY_EXEC", "^MAY_WRITE", "^MAY_READ", "^MAY_APPEND"

msdos_options [
	fat	fat_options
	nodots	stringnoz["nodots"]
	dots	stringnoz["dots"]
] [varlen]

vfat_options [
	fat		fat_options
	iocharset	fs_opt_codepage["iocharset"]
	rodir		stringnoz["rodir"]
	utf8no		stringnoz["utf8=0"]
	utf8		stringnoz["utf8=1"]
	uni_xlateno	stringnoz["uni_xlate=0"]
	uni_xlate	stringnoz["uni_xlate=1"]
	numtail		stringnoz["nonumtail=0"]
	nonumtail	stringnoz["nnonumtail=1"]
	shortname_lower	stringnoz["shortname=lower"]
	shortname_win95	stringnoz["shortname=win95"]
	shortname_winnt	stringnoz["shortname=winnt"]
	shortname_mixed	stringnoz["shortname=mixed"]
] [varlen]

fat_options [
	check_relaxed	stringnoz["check=relaxed"]
	check_strict	stringnoz["check=strict"]
	check_normal	stringnoz["check=normal"]
	usefree		stringnoz["usefree"]
	nocase		stringnoz["nocase"]
	quiet		stringnoz["quiet"]
	showexec	stringnoz["showexec"]
	debug		stringnoz["debug"]
	sys_immutable	stringnoz["sys_immutable"]
	flush		stringnoz["flush"]
	tz_utc		stringnoz["tz=UTC"]
	errors_continue	stringnoz["errors=continue"]
	errors_remount	stringnoz["errors=remount-ro"]
	discard		stringnoz["discard"]
	nfs		stringnoz["nfs"]
	nfs_nostale_ro	stringnoz["nfs=nostale_ro"]
	nfs_stale_rw	stringnoz["nfs=stale_rw"]
	dos1xfloppy	stringnoz["dos1xfloppy"]
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	umask		fs_opt_oct["umask", int32]
	dmask		fs_opt_oct["dmask", int32]
	fmask		fs_opt_oct["fmask", int32]
	allow_utime	fs_opt_oct["allow_utime", int32]
	time_offset	fs_opt_hex["time_offset", int32[-1440:1440]]
	codepage	fs_opt_cp_num["codepage"]
] [varlen]

xfs_options [
	wsync		stringnoz["wsync"]
	noalign		stringnoz["noalign"]
	swalloc		stringnoz["swalloc"]
	nouuid		stringnoz["nouuid"]
	mtpt		stringnoz["mtpt"]
	grpid		stringnoz["grpid"]
	nogrpid		stringnoz["nogrpid"]
	bsdgroups	stringnoz["bsdgroups"]
	sysvgroups	stringnoz["sysvgroups"]
	norecovery	stringnoz["norecovery"]
	inode64		stringnoz["inode64"]
	inode32		stringnoz["inode32"]
	ikeep		stringnoz["ikeep"]
	noikeep		stringnoz["noikeep"]
	largeio		stringnoz["largeio"]
	nolargeio	stringnoz["nolargeio"]
	attr2		stringnoz["attr2"]
	noattr2		stringnoz["noattr2"]
	filestreams	stringnoz["filestreams"]
	quota		stringnoz["quota"]
	noquota		stringnoz["noquota"]
	lazytime	stringnoz["lazytime"]
	nolazytime	stringnoz["nolazytime"]
	usrquota	stringnoz["usrquota"]
	grpquota	stringnoz["grpquota"]
	prjquota	stringnoz["prjquota"]
	uquota		stringnoz["uquota"]
	gquota		stringnoz["gquota"]
	pquota		stringnoz["pquota"]
	uqnoenforce	stringnoz["uqnoenforce"]
	gqnoenforce	stringnoz["gqnoenforce"]
	pqnoenforce	stringnoz["pqnoenforce"]
	qnoenforce	stringnoz["qnoenforce"]
	discard		stringnoz["discard"]
	nodiscard	stringnoz["nodiscard"]
	dax		stringnoz["dax"]
	dax_inode	stringnoz["dax=inode"]
	dax_always	stringnoz["dax=always"]
	dax_never	stringnoz["dax=never"]
	barrier		stringnoz["barrier"]
	nobarrier	stringnoz["nobarrier"]
	logbufs		fs_opt_dec["logbufs", int32[-1:8]]
	biosize		fs_opt_dec["biosize", int32]
	sunit		fs_opt_hex["sunit", int32]
	swidth		fs_opt_hex["swidth", int32]
	logbsize	fs_opt_dec_suffix["logbsize"]
	allocsize	fs_opt_dec_suffix["allocsize"]
	logdev		fs_opt_filename["logdev"]
	rtdev		fs_opt_filename["rtdev"]
] [varlen]

reiserfs_options [
	tails_on		stringnoz["tails=on"]
	tails_off		stringnoz["tails=off"]
	tails_small		stringnoz["tails=small"]
	notail			stringnoz["notail"]
	conv			stringnoz["conv"]
	noattrs			stringnoz["noattrs"]
	expose_privroot		stringnoz["expose_privroot"]
	user_xattr		stringnoz["user_xattr"]
	nouser_xattr		stringnoz["nouser_xattr"]
	acl			stringnoz["acl"]
	noacl			stringnoz["noacl"]
	replayonly		stringnoz["replayonly"]
	nolargeio		stringnoz["nolargeio"]
	usrquota		stringnoz["usrquota"]
	grpquota		stringnoz["grpquota"]
	noquota			stringnoz["noquota"]
	usrjquota		stringnoz["usrjquota"]
	usrjquota_file		stringnoz["usrjquota=syz"]
	grpjquota		stringnoz["grpjquota"]
	commit			fs_opt_hex["commit", int32]
	resize			fs_opt_hex["resize", int32]
	resize_auto		stringnoz["resize=auto"]
	jdev			fs_opt_filename["jdev"]
	jqfmt_vfsold		stringnoz["jqfmt=vfsold"]
	jqfmt_vfsv0		stringnoz["jqfmt=vfsv0"]
	hash_tea		stringnoz["hash=tea"]
	hash_rupasov		stringnoz["hash=rupasov"]
	hash_r5			stringnoz["hash=r5"]
	balloc_noborder		stringnoz["block-allocator=noborder"]
	balloc_border		stringnoz["block-allocator=border"]
	balloc_no_unhash_reloc	stringnoz["block-allocator=no_unhashed_relocation"]
	balloc_hashed_reloc	stringnoz["block-allocator=hashed_relocation"]
	balloc_test4		stringnoz["block-allocator=test4"]
	balloc_notest4		stringnoz["block-allocator=notest4"]
	barrier_none		stringnoz["barrier=none"]
	barrier_flush		stringnoz["barrier=flush"]
	data_ordered		stringnoz["data=ordered"]
	data_journal		stringnoz["data=journal"]
	data_writeback		stringnoz["data=writeback"]
	errors_continue		stringnoz["errors=continue"]
	errors_ro_remount	stringnoz["errors=ro-remount"]
] [varlen]

hfs_options [
	quiet		stringnoz["quiet"]
	umask		fs_opt_oct["umask", int32]
	file_umask	fs_opt_oct["file_umask", int32]
	dir_umask	fs_opt_oct["dir_umask", int32]
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	part		fs_opt_hex["part", int32]
	session		fs_opt_hex["session", int32]
	type		fs_opt["type", array[int8, 4]]
	creator		fs_opt["creator", array[int8, 4]]
	codepage	fs_opt_codepage["codepage"]
	iocharset	fs_opt_codepage["iocharset"]
] [varlen]

hfsplus_options [
	decompose	stringnoz["decompose"]
	nodecompose	stringnoz["nodecompose"]
	barrier		stringnoz["barrier"]
	nobarrier	stringnoz["nobarrier"]
	force		stringnoz["force"]
	umask		fs_opt_oct["umask", int32]
	type		fs_opt["type", array[int8, 4]]
	creator		fs_opt["creator", array[int8, 4]]
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	part		fs_opt_hex["part", int32]
	session		fs_opt_hex["session", int32]
	nls		fs_opt_codepage["nls"]
] [varlen]

iso9660_options [
	norock		stringnoz["norock"]
	nojoliet	stringnoz["nojoliet"]
	unhide		stringnoz["unhide"]
	hide		stringnoz["hide"]
	showassoc	stringnoz["showassoc"]
	cruft		stringnoz["cruft"]
	utf8		stringnoz["utf8"]
	map_acorn	stringnoz["map=acorn"]
	map_normal	stringnoz["map=normal"]
	map_off		stringnoz["map=off"]
	check_relaxed	stringnoz["check=relaxed"]
	check_strict	stringnoz["check=strict"]
	overriderock	stringnoz["overriderockperm"]
	nocompress	stringnoz["nocompress"]
	session		fs_opt_hex["session", int32[0:98]]
	sbsector	fs_opt_hex["sbsector", int32]
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	mode		fs_opt_hex["mode", int32]
	dmode		fs_opt_hex["dmode", int32]
	block		fs_opt_hex["block", flags[iso9660_blocks]]
	iocharset	fs_opt_codepage["iocharset"]
] [varlen]

iso9660_blocks = 512, 1024, 2048

# Note that the "debug" option has been omitted since it's equivalent to "errors=panic".
gfs2_options [
	spectator		stringnoz["spectator"]
	norecovery		stringnoz["norecovery"]
	ignore_local_fs		stringnoz["ignore_local_fs"]
	localflocks		stringnoz["localflocks"]
	localcaching		stringnoz["localcaching"]
	nodebug			stringnoz["nodebug"]
	upgrade			stringnoz["upgrade"]
	acl			stringnoz["acl"]
	noacl			stringnoz["noacl"]
	quota_off		stringnoz["quota=off"]
	quota_account		stringnoz["quota=account"]
	quota_on		stringnoz["quota=on"]
	quota_quiet		stringnoz["quota=quiet"]
	quota			stringnoz["quota"]
	noquota			stringnoz["noquota"]
	suiddir			stringnoz["suiddir"]
	nosuiddir		stringnoz["nosuiddir"]
	data_writeback		stringnoz["data=writeback"]
	data_ordered		stringnoz["data=ordered"]
	meta			stringnoz["meta"]
	discard			stringnoz["discard"]
	nodiscard		stringnoz["nodiscard"]
	errors_withdraw		stringnoz["errors=withdraw"]
	barrier			stringnoz["barrier"]
	nobarrier		stringnoz["nobarrier"]
	rgrplvb			stringnoz["rgrplvb"]
	norgrplvb		stringnoz["norgrplvb"]
	loccookie		stringnoz["loccookie"]
	noloccookie		stringnoz["noloccookie"]
	commit			fs_opt_hex["commit", int32]
	statfs_quantum		fs_opt_hex["statfs_quantum", int32]
	statfs_percent		fs_opt_hex["statfs_percent", int32]
	quota_quantum		fs_opt_hex["quota_quantum", int32]
	lockproto_dlm		stringnoz["lockproto=dlm"]
	lockproto_nolock	stringnoz["lockproto=lock_nolock"]
	locktable		fs_opt_str["locktable"]
	hostdata		fs_opt_str["hostdata"]
] [varlen]

jfs_options [
	integrity	stringnoz["integrity"]
	nointegrity	stringnoz["nointegrity"]
	resize		stringnoz["resize"]
	noquota		stringnoz["noquota"]
	quota		stringnoz["quota"]
	usrquota	stringnoz["usrquota"]
	grpquota	stringnoz["grpquota"]
	discard		stringnoz["discard"]
	nodiscard	stringnoz["nodiscard"]
	iocharset	fs_opt_codepage["iocharset"]
	errors_continue	stringnoz["errors=continue"]
	errors_remount	stringnoz["errors=remount-ro"]
	resize_size	fs_opt_hex["resize", int32]
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	umask		fs_opt_hex["umask", int32]
	discard_size	fs_opt_hex["discard", int32]
] [varlen]

btrfs_options [
	degraded		stringnoz["degraded"]
	nodatasum		stringnoz["nodatasum"]
	datasum			stringnoz["datasum"]
	nodatacow		stringnoz["nodatacow"]
	datacow			stringnoz["datacow"]
	nobarrier		stringnoz["nobarrier"]
	barrier			stringnoz["barrier"]
	compress		stringnoz["compress"]
	compress_force		stringnoz["compress-force"]
	ssd			stringnoz["ssd"]
	ssd_spread		stringnoz["ssd_spread"]
	nossd_spread		stringnoz["nossd_spread"]
	nossd			stringnoz["nossd"]
	acl			stringnoz["acl"]
	noacl			stringnoz["noacl"]
	notreelog		stringnoz["notreelog"]
	treelog			stringnoz["treelog"]
	flushoncommit		stringnoz["flushoncommit"]
	noflushoncommit		stringnoz["noflushoncommit"]
	discard			stringnoz["discard"]
	nodiscard		stringnoz["nodiscard"]
	discard_sync		stringnoz["discard=sync"]
	discard_async		stringnoz["discard=async"]
	fatal_errors_bug	stringnoz["fatal_errors=bug"]
	space_cache		stringnoz["space_cache"]
	clear_cache		stringnoz["clear_cache"]
	user_subvol_rm		stringnoz["user_subvol_rm_allowed"]
	enospc_debug		stringnoz["enospc_debug"]
	noenospc_debug		stringnoz["noenospc_debug"]
	autodefrag		stringnoz["autodefrag"]
	noautodefrag		stringnoz["noautodefrag"]
	inode_cache		stringnoz["inode_cache"]
	noinode_cache		stringnoz["noinode_cache"]
	nospace_cache		stringnoz["nospace_cache"]
	usebackuproot		stringnoz["usebackuproot"]
	skip_balance		stringnoz["skip_balance"]
	check_int		stringnoz["check_int"]
	check_int_data		stringnoz["check_int_data"]
	rescan_uuid_tree	stringnoz["rescan_uuid_tree"]
	fragment_data		stringnoz["fragment=data"]
	fragment_metadata	stringnoz["fragment=metadata"]
	fragment_all		stringnoz["fragment=all"]
	ref_verify		stringnoz["ref_verify"]
	metadata_ratio		fs_opt_hex["metadata_ratio", int32]
	check_int_print_mask	fs_opt_hex["check_int_print_mask", int32]
	commit			fs_opt_hex["commit", int32]
	thread_pool		fs_opt_hex["thread_pool", int32]
	device			fs_opt_filename["device"]
	subvolid		fs_opt_hex["subvolid", int64]
	subvol			fs_opt_str["subvol"]
	max_inline		fs_opt_dec_suffix["max_inline"]
	compress_algo		fs_opt["compress", stringnoz[btrfs_compress_algos]]
	compress_force_algo	fs_opt["compress-force", stringnoz[btrfs_compress_algos]]
	space_cache_v1		stringnoz["space_cache=v1"]
	space_cache_v2		stringnoz["space_cache=v2"]
	rescue			fs_opt["rescue", stringnoz[btrfs_rescue_opts]]
] [varlen]

btrfs_compress_algos = "zlib", "lzo", "zstd", "no"
btrfs_rescue_opts = "usebackuproot", "nologreplay", "ignorebadroots", "ibadroots", "ignoredatacsums", "ignoremetacsums", "ignoresuperflags", "idatacsums", "imetacsums", "isuperflags", "all"

ntfs_options [
	uid			fs_opt_hex["uid", uid]
	gid			fs_opt_hex["gid", gid]
	umask			fs_opt_oct["umask", int32]
	fmask			fs_opt_oct["fmask", int32]
	dmask			fs_opt_oct["dmask", int32]
	mft_zone_multiplier	fs_opt_hex["mft_zone_multiplier", int32[-1:4]]
	show_sys_files_no	stringnoz["show_sys_files=no"]
	show_sys_files_yes	stringnoz["show_sys_files=yes"]
	case_sensitive_no	stringnoz["case_sensitive=no"]
	case_sensitive_yes	stringnoz["case_sensitive=yes"]
	disable_sparse_no	stringnoz["disable_sparse=no"]
	disable_sparse_yes	stringnoz["disable_sparse=yes"]
	errors_remount		stringnoz["errors=remount-ro"]
	errors_continue		stringnoz["errors=continue"]
	errors_recover		stringnoz["errors=recover"]
	nls			fs_opt_codepage["nls"]
	utf8			stringnoz["utf8"]
] [varlen]

ntfs3_options [
	uid			fs_opt_hex["uid", uid]
	gid			fs_opt_hex["gid", gid]
	umask			fs_opt_oct["umask", int32]
	fmask			fs_opt_oct["fmask", int32]
	dmask			fs_opt_oct["dmask", int32]
	noacsrules		stringnoz["noacsrules"]
	hidden			stringnoz["hidden"]
	nohidden		stringnoz["nohidden"]
	sys_immutable		stringnoz["sys_immutable"]
	nosys_immutable		stringnoz["nosys_immutable"]
	discard			stringnoz["discard"]
	nodiscard		stringnoz["discard"]
	force			stringnoz["force"]
	noforce			stringnoz["noforce"]
	sparse			stringnoz["sparse"]
	nosparse		stringnoz["nosparse"]
	hide_dot_files		stringnoz["hide_dot_files"]
	nohide_dot_files	stringnoz["nohide_dot_files"]
	windows_names		stringnoz["windows_names"]
	nowindows_names		stringnoz["windows_names"]
	showmeta		stringnoz["showmeta"]
	noshowmeta		stringnoz["noshowmeta"]
	prealloc		stringnoz["prealloc"]
	noprealloc		stringnoz["noprealloc"]
	acl			stringnoz["acl"]
	noacl			stringnoz["noacl"]
	iocharset		fs_opt_codepage["iocharset"]
	case			stringnoz["case"]
	nocase			stringnoz["nocase"]
] [varlen]

ext4_options [
	bsddf				stringnoz["bsddf"]
	minixdf				stringnoz["minixdf"]
	grpid				stringnoz["grpid"]
	bsdgroups			stringnoz["bsdgroups"]
	nogrpid				stringnoz["nogrpid"]
	sysvgroups			stringnoz["sysvgroups"]
	errors_continue			stringnoz["errors=continue"]
	errors_remount			stringnoz["errors=remount-ro"]
	nouid32				stringnoz["nouid32"]
	debug				stringnoz["debug"]
	oldalloc			stringnoz["oldalloc"]
	orlov				stringnoz["orlov"]
	user_xattr			stringnoz["user_xattr"]
	nouser_xattr			stringnoz["nouser_xattr"]
	acl				stringnoz["acl"]
	noacl				stringnoz["noacl"]
	norecovery			stringnoz["norecovery"]
	noload				stringnoz["noload"]
	nobh				stringnoz["nobh"]
	bh				stringnoz["bh"]
	journal_checksum		stringnoz["journal_checksum"]
	nojournal_checksum		stringnoz["nojournal_checksum"]
	journal_async_commit		stringnoz["journal_async_commit"]
	abort				stringnoz["abort"]
	data_journal			stringnoz["data=journal"]
	data_ordered			stringnoz["data=ordered"]
	data_writeback			stringnoz["data=writeback"]
	data_err_abort			stringnoz["data_err=abort"]
	data_err_ignore			stringnoz["data_err=ignore"]
	usrjquota			stringnoz["usrjquota="]
	grpjquota			stringnoz["grpjquota="]
	jqfmt_vfsold			stringnoz["jqfmt=vfsold"]
	jqfmt_vfsv0			stringnoz["jqfmt=vfsv0"]
	jqfmt_vfsv1			stringnoz["jqfmt=vfsv1"]
	grpquota			stringnoz["grpquota"]
	noquota				stringnoz["noquota"]
	quota				stringnoz["quota"]
	usrquota			stringnoz["usrquota"]
	prjquota			stringnoz["prjquota"]
	barrier				stringnoz["barrier"]
	nobarrier			stringnoz["nobarrier"]
	i_version			stringnoz["i_version"]
	dax				stringnoz["dax"]
	dax_always			stringnoz["dax=always"]
	dax_inode			stringnoz["dax=inode"]
	dax_never			stringnoz["dax=never"]
	delalloc			stringnoz["delalloc"]
	lazytime			stringnoz["lazytime"]
	nolazytime			stringnoz["nolazytime"]
	nodelalloc			stringnoz["nodelalloc"]
	mblk_io_submit			stringnoz["mblk_io_submit"]
	nomblk_io_submit		stringnoz["nomblk_io_submit"]
	block_validity			stringnoz["block_validity"]
	noblock_validity		stringnoz["noblock_validity"]
	auto_da_alloc			stringnoz["auto_da_alloc"]
	noauto_da_alloc			stringnoz["noauto_da_alloc"]
	dioread_nolock			stringnoz["dioread_nolock"]
	nodioread_nolock		stringnoz["nodioread_nolock"]
	dioread_lock			stringnoz["dioread_lock"]
	discard				stringnoz["discard"]
	nodiscard			stringnoz["nodiscard"]
	init_itable			stringnoz["init_itable"]
	noinit_itable			stringnoz["noinit_itable"]
	test_dummy_encryption		stringnoz["test_dummy_encryption"]
	test_dummy_encryption_v1	stringnoz["test_dummy_encryption=v1"]
	nombcache			stringnoz["nombcache"]
	inlinecrypt			stringnoz["inlinecrypt"]
	mb_optimize_scan		fs_opt_hex["mb_optimize_scan", int32[0:1]]
	resgid				fs_opt_hex["resgid", gid]
	resuid				fs_opt_hex["resuid", uid]
	sb				fs_opt_hex["sb", int32]
	commit				fs_opt_hex["commit", int32]
	min_batch_time			fs_opt_hex["min_batch_time", int32]
	max_batch_time			fs_opt_hex["max_batch_time", int32]
	journal_dev			fs_opt_hex["journal_dev", int32]
	barrier_val			fs_opt_hex["barrier", int32]
	stripe				fs_opt_hex["stripe", int32]
	debug_want_extra_isize		fs_opt_hex["debug_want_extra_isize", int32]
	inode_readahead_blks		fs_opt_hex["inode_readahead_blks", flags[ext4_inode_readahead_blks]]
	journal_ioprio			fs_opt_hex["journal_ioprio", int32[0:7]]
	auto_da_alloc_val		fs_opt_hex["auto_da_alloc", int32]
	init_itable_val			fs_opt_hex["init_itable", int32]
	max_dir_size_kb			fs_opt_hex["max_dir_size_kb", int32]
	journal_path			fs_opt_filename["journal_path"]
	grpjquota_path			fs_opt_filename["grpjquota"]
	usrjquota_path			fs_opt_filename["usrjquota"]
] [varlen]

ext4_types = "ext4", "ext3", "ext2"
ext4_inode_readahead_blks = 0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000

f2fs_options [
	background_gc_sync		stringnoz["background_gc=sync"]
	background_gc_off		stringnoz["background_gc=off"]
	background_gc_on		stringnoz["background_gc=on"]
	disable_roll_forward		stringnoz["disable_roll_forward"]
	norecovery			stringnoz["norecovery"]
	discard				stringnoz["discard"]
	nodiscard			stringnoz["nodiscard"]
	noheap				stringnoz["no_heap"]
	heap				stringnoz["heap"]
	user_xattr			stringnoz["user_xattr"]
	nouser_xattr			stringnoz["nouser_xattr"]
	acl				stringnoz["acl"]
	noacl				stringnoz["noacl"]
	six_active_logs			stringnoz["active_logs=6"]
	four_active_logs		stringnoz["active_logs=4"]
	two_active_logs			stringnoz["active_logs=2"]
	disable_ext_identify		stringnoz["disable_ext_identify"]
	inline_xattr			stringnoz["inline_xattr"]
	noinline_xattr			stringnoz["noinline_xattr"]
	inline_xattr_size		fs_opt_hex["inline_xattr_size", int32]
	inline_data			stringnoz["inline_data"]
	noinline_data			stringnoz["noinline_data"]
	inline_dentry			stringnoz["inline_dentry"]
	noinline_dentry			stringnoz["noinline_dentry"]
	flush_merge			stringnoz["flush_merge"]
	noflush_merge			stringnoz["noflush_merge"]
	barrier				stringnoz["barrier"]
	nobarrier			stringnoz["nobarrier"]
	fastboot			stringnoz["fastboot"]
	extent_cache			stringnoz["extent_cache"]
	noextent_cache			stringnoz["noextent_cache"]
	data_flush			stringnoz["data_flush"]
	reserve_root			fs_opt_dec["reserver_root", int32]
	adaptive_mode			stringnoz["mode=adaptive"]
	lfs_mode			stringnoz["mode=lfs"]
	segment_mode			stringnoz["mode=fragment:segment"]
	block_mode			stringnoz["mode=fragment:block"]
	io_bits				fs_opt_dec["io_bits", int32[0:256]]
	fault_injection			fs_opt_dec["fault_injection", int32]
	fault_type			fs_opt_dec["fault_type", int32]
	resgid				fs_opt_hex["resgid", gid]
	resuid				fs_opt_hex["resuid", uid]
	lazytime			stringnoz["lazytime"]
	nolazytime			stringnoz["nolazytime"]
	quota				stringnoz["quota"]
	noquota				stringnoz["noquota"]
	usrquota			fs_opt_str["usrquota"]
	grpquota			fs_opt_str["grpquota"]
	prjquota			fs_opt_str["prjquota"]
	usrjquota			fs_opt_str["usrjquota"]
	grpjquota			fs_opt_str["grpjquota"]
	prjjquota			fs_opt_str["prjjquota"]
	jqfmt_vfsold			stringnoz["jqfmt=vfsold"]
	jqfmt_vfsv0			stringnoz["jqfmt=vfsv0"]
	jqfmt_vfsv1			stringnoz["jqfmt=vfsv1"]
	whint_mode_user			stringnoz["whint_mode=user-based"]
	whint_mode_off			stringnoz["whint_mode=off"]
	whint_mode_fs			stringnoz["whint_mode=fs-based"]
	alloc_mode_def			stringnoz["alloc_mode=default"]
	alloc_mode_reuse		stringnoz["alloc_mode=reuse"]
	fsync_mode_posix		stringnoz["fsync_mode=posix"]
	fsync_mode_strict		stringnoz["fsync_mode=strict"]
	test_dummy_encryption		stringnoz["test_dummy_encryption"]
	test_dummy_encryption_v1	stringnoz["test_dummy_encryption=v1"]
	errors_continue			stringnoz["errors=continue"]
	errors_remount			stringnoz["errors=remount-ro"]
	inlinecrypt			stringnoz["inlinecrypt"]
	checkpoint_diasble		stringnoz["checkpoint=disable"]
	checkpoint_enable		stringnoz["checkpoint=enable"]
	checkpoint_merge		stringnoz["checkpoint=merge"]
	nocheckpoint_merge		stringnoz["nocheckpoint_merge"]
	compress_chksum			stringnoz["compress_chksum"]
	compress_cache			stringnoz["compress_cache"]
	atgc				stringnoz["atgc"]
	gc_merge			stringnoz["gc_merge"]
	nogc_merge			stringnoz["nogc_merge"]
	discard_unit_block		stringnoz["discard_unit=block"]
	discard_unit_segment		stringnoz["discard_unit=segment"]
	discard_unit_section		stringnoz["discard_unit=section"]
	memory_normal			stringnoz["memory=normal"]
	memory_low			stringnoz["memory=low"]
	age_extent_cache		stringnoz["age_extent_cache"]
] [varlen]

ocfs2_options [
	barrier			fs_opt_dec["barrier", int32]
	err_ro			stringnoz["errors=remount-ro"]
	intr			stringnoz["intr"]
	nointr			stringnoz["nointr"]
	heartbeat_none		stringnoz["heartbeat=none"]
	heartbeat_local		stringnoz["heartbeat=local"]
	heartbeat_global	stringnoz["heartbeat=global"]
	data_ordered		stringnoz["data=ordered"]
	data_writeback		stringnoz["data=writeback"]
	atime_quantum		fs_opt_dec["atime_quantum", int32]
	preferred_slot		fs_opt_dec["preferred_slot", int32]
	commit			fs_opt_dec["commit", int32]
	localalloc		fs_opt_dec["localalloc", int32]
	localflocks		stringnoz["localflocks"]
	cluster_stack		stringnoz["cluster_stack=o2cb"]
	user_xattr		stringnoz["user_xattr"]
	nouser_xattr		stringnoz["nouser_xattr"]
	inode64			stringnoz["inode64"]
	acl			stringnoz["acl"]
	noacl			stringnoz["noacl"]
	usrquota		stringnoz["usrquota"]
	grpquota		stringnoz["grpquota"]
	coherency_buffered	stringnoz["coherency=buffered"]
	coherency_full		stringnoz["coherency=full"]
	resv_level		fs_opt_dec["resv_level", int32[0:9]]
	dir_resv_level		fs_opt_dec["dir_resv_level", int32[0:9]]
	journal_async_commit	stringnoz["journal_async_commit"]
	err_cont		stringnoz["errors=continue"]
] [varlen]

bpf_options [
	uid	fs_opt_hex["uid", uid]
	gid	fs_opt_hex["gid", gid]
	mode	fs_opt_oct["mode", int32]
] [varlen]

overlay_options [
	lowerdir		fs_opt_filename["lowerdir"]
	upperdir		fs_opt_filename["upperdir"]
	workdir			fs_opt_filename["workdir"]
	redirect_dir_on		stringnoz["redirect_dir=on"]
	redirect_dir_off	stringnoz["redirect_dir=off"]
	redirect_dir_follow	stringnoz["redirect_dir=follow"]
	redirect_dir_nofollow	stringnoz["redirect_dir=nofollow"]
	default_permissions	stringnoz["default_permissions"]
	index_on		stringnoz["index=on"]
	index_off		stringnoz["index=off"]
	uuid_on			stringnoz["uuid=on"]
	uuid_off		stringnoz["uuid=off"]
	uuid_auto		stringnoz["uuid=auto"]
	uuid_null		stringnoz["uuid=null"]
	nfs_export_on		stringnoz["nfs_export=on"]
	nfs_export_off		stringnoz["nfs_export=off"]
	userxattr		stringnoz["userxattr"]
	xino_on			stringnoz["xino=on"]
	xino_off		stringnoz["xino=off"]
	xino_auto		stringnoz["xino=auto"]
	metacopy_on		stringnoz["metacopy=on"]
	metacopy_off		stringnoz["metacopy=off"]
	verity_on		stringnoz["verity=on"]
	verity_off		stringnoz["verity=off"]
	verity_require		stringnoz["verity=require"]
	volatile		stringnoz["volatile"]
] [varlen]

binder_options [
	max	fs_opt_dec["max", int32[0:4]]
	stats	stringnoz["stats=global"]
] [varlen]

erofs_options [
	user_xattr			stringnoz["user_xattr"]
	nouser_xattr			stringnoz["nouser_xattr"]
	acl				stringnoz["acl"]
	noacl				stringnoz["noacl"]
	fault_injection			fs_opt_hex["fault_injection", int32]
	cache_strategy_disabled		stringnoz["cache_strategy=disabled"]
	cache_strategy_readahead	stringnoz["cache_strategy=readahead"]
	cache_strategy_readaround	stringnoz["cache_strategy=readaround"]
	dax				stringnoz["dax"]
	dax_always			stringnoz["dax=always"]
	dax_never			stringnoz["dax=never"]
] [varlen]

exfat_options [
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	umask		fs_opt_oct["umask", int32]
	dmask		fs_opt_oct["dmask", int32]
	fmask		fs_opt_oct["fmask", int32]
	allow_utime	fs_opt_oct["allow_utime", int32]
	codepage	fs_opt_codepage["codepage"]
	iocharset	fs_opt_codepage["iocharset"]
	namecase	stringnoz["namecase=1"]
	errors_remount	stringnoz["errors=remount-ro"]
	errors_continue	stringnoz["errors=continue"]
	utf8		stringnoz["utf8"]
	discard		stringnoz["discard"]
	keep_last_dots	stringnoz["keep_last_dots"]
	sys_tz		stringnoz["sys_tz"]
	time_offset	fs_opt_hex["time_offset", int32]
	zero_size_dir	stringnoz["zero_size_dir"]
] [varlen]

# TODO: afs should be configured via /proc/fs/afs/{cells,servers} (see fs/afs/proc.c).
# Without that mounting of afs will fail.
afs_source [
	none	string["none"]
	cell	afs_cell_source
] [varlen]

afs_cell_source {
	prefix	flags[afs_cell_prefix, int8]
	cell	stringnoz[afs_cells]
	volname	stringnoz[afs_volnames]
	suffix	stringnoz[afs_suffixes]
	z	const[0, int8]
} [packed]

afs_cell_prefix = '%', '#'
afs_cells = "", "syz0:", "syz1:"
afs_volnames = "syz0", "syz1"
afs_suffixes = "", ".readonly", ".backup"

afs_options [
	autocell	stringnoz["autocell"]
	dyn		stringnoz["dyn"]
	flock_local	stringnoz["flock=local"]
	flock_openafs	stringnoz["flock=openafs"]
	flock_strict	stringnoz["flock=strict"]
	flock_write	stringnoz["flock=write"]
] [varlen]

tmpfs_options [
	uid				fs_opt_hex["uid", uid]
	gid				fs_opt_hex["gid", gid]
	mode				fs_opt_oct["mode", int32]
	nr_blocks			fs_opt_dec_suffix["nr_blocks"]
	nr_inodes			fs_opt_dec_suffix["nr_inodes"]
	size				fs_opt_dec_suffix["size"]
	huge_never			stringnoz["huge=never"]
	huge_always			stringnoz["huge=always"]
	huge_within_size		stringnoz["huge=within_size"]
	huge_advise			stringnoz["huge=advise"]
	mpol				fs_opt["mpol", tmpfs_mpol]
	inode32				stringnoz["inode32"]
	inode64				stringnoz["indo64"]
	noswap				stringnoz["noswap"]
	quota				stringnoz["quota"]
	usrquota			stringnoz["usrquota"]
	grpquota			stringnoz["grpquota"]
	usrquota_block_hardlimit	fs_opt_dec_suffix["usrquota_block_hardlimit"]
	usrquota_inode_hardlimit	fs_opt_dec_suffix["usrquota_inode_hardlimit"]
	grpquota_block_hardlimit	fs_opt_dec_suffix["grpquota_block_hardlimit"]
	grpquota_inode_hardlimit	fs_opt_dec_suffix["grpquota_inode_hardlimit"]
] [varlen]

tmpfs_mpol {
	policy	stringnoz[tmpfs_mpol_policy]
	flags	stringnoz[tmpfs_mpol_flags]
	nodes	optional[tmpfs_mpol_nodes]
} [packed]

tmpfs_mpol_nodes {
	colon	const[':', int8]
	nodes	array[flags[tmpfs_mpol_node_chars, int8]]
}

tmpfs_mpol_policy = "default", "prefer", "bind", "interleave", "local"
tmpfs_mpol_flags = "", "=static", "=relative"
tmpfs_mpol_node_chars = '-', ':', '/', ',', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'

zonefs_options [
	errors_remount_ro	stringnoz["errors=remount-ro"]
	errors_zone_ro		stringnoz["errors=zone-ro"]
	errors_zone_offline	stringnoz["errors=zone-offline"]
	errors_repair		stringnoz["errors=repair"]
	explicit_open		stringnoz["explicit-open"]
] [varlen]

jffs2_options [
	compr_none	stringnoz["compr=none"]
	compr_lzo	stringnoz["compr=lzo"]
	compr_zlib	stringnoz["compr=zlib"]
	rp_size		fs_opt_dec["rp_size", int32]
] [varlen]

nilfs2_options [
	barrier			stringnoz["barrier"]
	nobarrier		stringnoz["nobarrier"]
	norecovery		stringnoz["norecovery"]
	discard			stringnoz["discard"]
	nodiscard		stringnoz["nodiscard"]
	snapshot		fs_opt_hex["cp", int32[0:3]]
	order_relaxed		stringnoz["order=relaxed"]
	order_strict		stringnoz["order=strict"]
	errors_continue		stringnoz["errors=continue"]
	errors_remount_ro	stringnoz["errors=remount-ro"]
] [varlen]

squashfs_options [
	errors		stringnoz["errors=continue"]
	threads_str	fs_opt["threads", stringnoz[squashfs_thread]]
	threads_num	fs_opt_dec["threads", int32]
] [varlen]

squashfs_thread = "single", "multi", "percpu"

ubifs_options [
	fast_unmount	stringnoz["fast_unmount"]
	norm_unmount	stringnoz["norm_unmount"]
	bulk_read	stringnoz["bulk_read"]
	no_bulk_read	stringnoz["no_bulk_read"]
	chk_data_crc	stringnoz["chk_data_crc"]
	no_chk_data_crc	stringnoz["no_chk_data_crc"]
	compr_none	stringnoz["compr=none"]
	compr_lzo	stringnoz["compr=lzo"]
	compr_zlib	stringnoz["compr=zlib"]
	compr_zstd	stringnoz["compr=zstd"]
	auth_key	fs_opt_str["auth_key"]
	auth_hash_name	fs_opt["auth_hash_name", stringnoz[ubifs_auth_hash_name]]
] [varlen]

adfs_options [
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	ownmask		fs_opt_oct["ownmask", int32]
	othmask		fs_opt_oct["othmask", int32]
	ftsuffix	fs_opt_dec["ftsuffix", int32]
] [varlen]

affs_options [
	bs		fs_opt_hex["bs", flags[affs_bs]]
	mode		fs_opt_oct["mode", int32]
	mufs		stringnoz["mufs"]
	notruncate	stringnoz["nofilenametruncate"]
	protect		stringnoz["protect"]
	reserved	fs_opt_dec["reserved", int32]
	root		fs_opt_dec["root", int32]
	setuid		fs_opt_hex["setuid", uid]
	setgid		fs_opt_hex["setgid", gid]
	verbose		stringnoz["verbose"]
] [varlen]

affs_bs = 512, 1024, 2048, 4096

vxfs_options [
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	iocharset	fs_opt_codepage["iocharset"]
	debug		stringnoz["debug"]
] [varlen]

omfs_options [
	uid	fs_opt_hex["uid", uid]
	gid	fs_opt_hex["gid", gid]
	umask	fs_opt_oct["umask", int32]
	dmask	fs_opt_oct["dmask", int32]
	fmask	fs_opt_oct["fmask", int32]
] [varlen]

hpfs_options [
	help		stringnoz["help"]
	uid		fs_opt_hex["uid", uid]
	gid		fs_opt_hex["gid", gid]
	umask		fs_opt_oct["umask", int32]
	case_lower	stringnoz["case=lower"]
	case_asis	stringnoz["case=asis"]
	check_none	stringnoz["check=none"]
	check_normal	stringnoz["check=normal"]
	check_strict	stringnoz["check=strict"]
	err_cont	stringnoz["errors=continue"]
	err_ro		stringnoz["errors=remount-ro"]
	eas_no		stringnoz["eas=no"]
	eas_ro		stringnoz["ear=ro"]
	eas_rw		stringnoz["eas=rw"]
	chkdsk_no	stringnoz["chkdsk=no"]
	chkdsk_errors	stringnoz["chkdsk=errors"]
	chkdsk_always	stringnoz["chkdsk=always"]
	timeshift	fs_opt_dec["timeshift", int32]
] [varlen]

qnx6_options [
	mmi_fs	stringnoz["mmi_fs"]
] [varlen]

# We could use more hash names, but the problem is that alg_hash_name is 0-terminated.
ubifs_auth_hash_name = "crc32", "ghash", "md5", "sha1"

udf_options [
	novrs		stringnoz["novrs"]
	nostrict	stringnoz["nostrict"]
	unhide		stringnoz["unhide"]
	undelete	stringnoz["undelete"]
	noadinicb	stringnoz["noadinicb"]
	adinicb		stringnoz["adinicb"]
	shortad		stringnoz["shortad"]
	longad		stringnoz["longad"]
	utf8		stringnoz["utf8"]
	iocharset	fs_opt_codepage["iocharset"]
	uid_forget	stringnoz["uid=forget"]
	uid_ignore	stringnoz["uid=ignore"]
	gid_forget	stringnoz["gid=forget"]
	gid_ignore	stringnoz["gid=ignore"]
	gid		fs_opt_dec["gid", gid]
	uid		fs_opt_dec["uid", uid]
	umask		fs_opt_oct["umask", int32]
	mode		fs_opt_oct["mode", int32]
	dmode		fs_opt_oct["dmode", int32]
	bs		fs_opt_dec["bs", int32]
	session		fs_opt_dec["session", int32]
	lastblock	fs_opt_dec["lastblock", int32]
	anchor		fs_opt_dec["anchor", int32]
	volume		fs_opt_dec["volume", int32]
	partition	fs_opt_dec["partition", int32]
	fileset		fs_opt_dec["fileset", int32]
	rootdir		fs_opt_dec["rootdir", int32]
] [varlen]

esdfs_options [
	lower		fs_opt_str["lower"]
	upper		fs_opt_str["upper"]
	derive		fs_opt["derive", stringnoz[esdfs_derive]]
	confine		stringnoz["confine"]
	noconfine	stringnoz["noconfine"]
	derive_gid	stringnoz["derive_gid"]
	default_normal	stringnoz["default_normal"]
	dl_loc		fs_opt_str["dl_loc"]
	dl_uid		fs_opt_oct["dl_uid", uid]
	dl_gid		fs_opt_oct["dl_gid", gid]
	ns_fd		fs_opt_oct["ns_fd", fd_namespace]
	fsuid		fs_opt_oct["fsuid", uid]
	fsgid		fs_opt_oct["fsgid", gid]
	gid		fs_opt_oct["gid", gid]
	mask		fs_opt_oct["mask", int32]
	userid		fs_opt_oct["userid", uid]
	multiuser	stringnoz["multiuser"]
] [varlen]

esdfs_derive = "none", "legacy", "unified", "multi", "public"

bcachefs_options [
	metadata_checksum		fs_opt["metadata_checksum", stringnoz[bcachefs_checksum]]
	data_checksum			fs_opt["data_checksum", stringnoz[bcachefs_checksum]]
	compression			fs_opt["compression", stringnoz[bcachefs_compression]]
	background_compression		fs_opt["background_compression", stringnoz[bcachefs_compression]]
	str_hash			fs_opt["str_hash", stringnoz[bcachefs_str_hash]]
	nocow				stringnoz["nocow"]
	errors_continue			stringnoz["errors=continue"]
	errors_fix_safe			stringnoz["errors=fix_safe"]
	errors_ro			stringnoz["error=ro"]
	metadata_replicas		fs_opt_hex["metadata_replicas", int32[1:4]]
	data_replicas			fs_opt_hex["data_replicas", int32[1:4]]
	metadata_replicas_required	fs_opt_hex["metadata_replicas_required", int32[1:4]]
	data_replicas_required		fs_opt_hex["data_replicas_required", int32[1:4]]
	erasure_code			stringnoz["erasure_code"]
	inodes_32bit			stringnoz["inodes_32bit"]
	shared_inode_numbers		stringnoz["shard_inode_numbers"]
	inodes_use_key_cache		stringnoz["inodes_use_key_cache"]
	btree_node_mem_ptr_optimization	stringnoz["btree_node_mem_ptr_optimization"]
	gc_reserve_percent		fs_opt_hex["gc_reserve_percent", int32[5:21]]
	gc_reserve_bytes		fs_opt_hex["gc_reserve_bytes", int32]
	root_reserve_percent		fs_opt_hex["root_reserve_percent", int32[0:100]]
	wide_macs			stringnoz["wide_macs"]
	inline_data			stringnoz["inline_data"]
	acl				stringnoz["acl"]
	usrquota			stringnoz["usrquota"]
	grpquota			stringnoz["grpquota"]
	prjquota			stringnoz["prjquota"]
	degraded			stringnoz["degraded"]
	very_degraded			stringnoz["very_degraded"]
	no_splitbrain_check		stringnoz["no_splitbrain_check"]
	discard				stringnoz["discard"]
	verbose				stringnoz["verbose"]
	journal_flush_delay		fs_opt_hex["journal_flush_delay", int32]
	journal_flush_disabled		stringnoz["journal_flush_disabled"]
	journal_reclaim_delay		fs_opt_hex["journal_reclaim_delay", int32]
	move_bytes_in_flight		fs_opt_hex["move_bytes_in_flight", int32]
	move_ios_in_flight		fs_opt_hex["move_ios_in_flight", int32[1:1024]]
	fsck				stringnoz["fsck"]
	fsck_memory_usage_percent	fs_opt_hex["fsck_memory_usage_percent", int32[20:70]]
	fix_errors			fs_opt["fix_errors", stringnoz[bcachefs_fix_errors]]
	ratelimit_errors		stringnoz["ratelimit_errors"]
	nochanges			stringnoz["nochanges"]
	norecovery			stringnoz["norecovery"]
	recovery_pass_last		fs_opt["recovery_pass_last", stringnoz[bcachefs_recovery_pass_last]]
	journal_transaction_names	stringnoz["journal_transaction_names"]
	allocator_stuck_timeout		fs_opt_hex["allocator_stuck_timeout", int16]
	noexcl				stringnoz["noexcl"]
	direct_io			stringnoz["direct_io"]
	sb				fs_opt_hex["sb", int32]
	read_only			stringnoz["read_only"]
	reconstruct_alloc		stringnoz["reconstruct_alloc"]
	version_upgrade			fs_opt["version_upgrade", stringnoz[bcachefs_version_upgrade]]
	nocow_enabled			stringnoz["nocow_enabled"]
	no_data_io			stringnoz["no_data_io"]
	btree_node_prefetch		stringnoz["btree_node_prefetch"]
] [varlen]

bcachefs_checksum = "none", "crc32c", "crc64", "xxhash"
bcachefs_compression = "none", "lz4", "gzip", "zstd"
bcachefs_str_hash = "crc32c", "crc64", "siphash"
bcachefs_fix_errors = "exit", "yes", "no", "ask"
bcachefs_version_upgrade = "compatible", "incompatible", "none"
bcachefs_recovery_pass_last = "scan_for_btree_nodes", "check_topology", "accounting_read", "alloc_read", "stripes_read", "initialize_subvolumes", "snapshots_read", "check_allocations", "trans_mark_dev_sbs", "fs_journal_alloc", "set_may_go_rw", "journal_replay", "check_alloc_info", "check_lrus", "check_btree_backpointers", "check_backpointers_to_extents", "check_extents_to_backpointers", "check_alloc_to_lru_refs", "fs_freespace_init", "bucket_gens_init", "reconstruct_snapshots", "check_snapshot_trees", "check_snapshots", "check_subvols", "check_subvol_children", "delete_dead_snapshots", "fs_upgrade_for_subvolumes", "check_inodes", "check_extents", "check_indirect_extents", "check_dirents", "check_xattrs", "check_root", "check_subvolume_structure", "check_directory_structure", "check_nlinks", "resume_logged_ops", "delete_dead_inodes", "fix_reflink_p", "set_fs_needs_rebalance"

cgroup_options [
	all		stringnoz["all"]
	clone_children	stringnoz["clone_children"]
	cpuset_v2_mode	stringnoz["cpuset_v2_mode"]
	name		fs_opt_str["name"]
	none		stringnoz["none"]
	noprefix	stringnoz["noprefix"]
	release_agent	fs_opt_filename["release_agent"]
	xattr		stringnoz["xattr"]
	favordynmods	stringnoz["favordynmods"]
	nofavordynmods	stringnoz["nofavordynmods"]
	subsystem	stringnoz[cgroup_subsystems]
] [varlen]

cgroup2_options [
	nsdelegate			stringnoz["nsdelegate"]
	favordynmods			stringnoz["favordynmods"]
	memory_localevents		stringnoz["memory_localevents"]
	memory_recursiveprot		stringnoz["memory_recursiveprot"]
	memory_hugetlb_accounting	stringnoz["memory_hugetlb_accounting"]
	pids_localevents		stringnoz["pids_localevents"]
	subsystem			stringnoz[cgroup_subsystems]
] [varlen]

ufs_options [
	type	fs_opt["type", stringnoz[ufs_type]]
	onerror	fs_opt["onerror", stringnoz[ufs_onerror]]
] [varlen]

ufs_type = "old", "sunx86", "sun", "sunos", "44bsd", "ufs2", "5xbsd", "hp", "nextstep-cd", "nextstep", "openstep"
ufs_onerror = "lock", "umount", "repair"

codepage_nums = "1250", "1251", "1255", "437", "737", "775", "850", "852", "855", "857", "860", "861", "862", "863", "864", "865", "866", "869", "874", "932", "936", "949", "950"
codepages_names = "macceltic", "maccenteuro", "maccroatian", "maccyrillic", "macgaelic", "macgreek", "maciceland", "macinuit", "macroman", "macromanian", "macturkish", "ascii", "default", "cp1250", "cp1251", "cp1255", "cp437", "cp737", "cp775", "cp850", "cp852", "cp855", "cp857", "cp860", "cp861", "cp862", "cp863", "cp864", "cp865", "cp866", "cp869", "cp874", "cp932", "cp936", "cp949", "cp950", "euc-jp", "iso8859-13", "iso8859-14", "iso8859-15", "iso8859-1", "iso8859-2", "iso8859-3", "iso8859-4", "iso8859-5", "iso8859-6", "iso8859-7", "iso8859-9", "koi8-r", "koi8-ru", "koi8-u", "utf8", "none"
mount_flags = MS_BIND, MS_DIRSYNC, MS_MANDLOCK, MS_MOVE, MS_NOATIME, MS_NODEV, MS_NODIRATIME, MS_NOEXEC, MS_NOSUID, MS_RDONLY, MS_RELATIME, MS_REMOUNT, MS_SILENT, MS_STRICTATIME, MS_SYNCHRONOUS, MS_REC, MS_POSIXACL, MS_UNBINDABLE, MS_PRIVATE, MS_SLAVE, MS_SHARED, MS_I_VERSION, MS_LAZYTIME
umount_flags = MNT_FORCE, MNT_DETACH, MNT_EXPIRE, UMOUNT_NOFOLLOW