Commit | Line | Data |
---|---|---|
31d921c7 DH |
1 | /* Filesystem parameter description and parser |
2 | * | |
3 | * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved. | |
4 | * Written by David Howells (dhowells@redhat.com) | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public Licence | |
8 | * as published by the Free Software Foundation; either version | |
9 | * 2 of the Licence, or (at your option) any later version. | |
10 | */ | |
11 | ||
12 | #ifndef _LINUX_FS_PARSER_H | |
13 | #define _LINUX_FS_PARSER_H | |
14 | ||
15 | #include <linux/fs_context.h> | |
16 | ||
17 | struct path; | |
18 | ||
19 | struct constant_table { | |
20 | const char *name; | |
21 | int value; | |
22 | }; | |
23 | ||
24 | /* | |
25 | * The type of parameter expected. | |
26 | */ | |
27 | enum fs_parameter_type { | |
28 | __fs_param_wasnt_defined, | |
29 | fs_param_is_flag, | |
30 | fs_param_is_bool, | |
31 | fs_param_is_u32, | |
32 | fs_param_is_u32_octal, | |
33 | fs_param_is_u32_hex, | |
34 | fs_param_is_s32, | |
35 | fs_param_is_u64, | |
36 | fs_param_is_enum, | |
37 | fs_param_is_string, | |
38 | fs_param_is_blob, | |
39 | fs_param_is_blockdev, | |
40 | fs_param_is_path, | |
41 | fs_param_is_fd, | |
42 | nr__fs_parameter_type, | |
43 | }; | |
44 | ||
45 | /* | |
46 | * Specification of the type of value a parameter wants. | |
47 | * | |
48 | * Note that the fsparam_flag(), fsparam_string(), fsparam_u32(), ... macros | |
49 | * should be used to generate elements of this type. | |
50 | */ | |
51 | struct fs_parameter_spec { | |
52 | const char *name; | |
53 | u8 opt; /* Option number (returned by fs_parse()) */ | |
54 | enum fs_parameter_type type:8; /* The desired parameter type */ | |
55 | unsigned short flags; | |
56 | #define fs_param_v_optional 0x0001 /* The value is optional */ | |
57 | #define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */ | |
58 | #define fs_param_neg_with_empty 0x0004 /* "xxx=" is negative param */ | |
59 | #define fs_param_deprecated 0x0008 /* The param is deprecated */ | |
60 | }; | |
61 | ||
62 | struct fs_parameter_enum { | |
63 | u8 opt; /* Option number (as fs_parameter_spec::opt) */ | |
64 | char name[14]; | |
65 | u8 value; | |
66 | }; | |
67 | ||
68 | struct fs_parameter_description { | |
69 | const char name[16]; /* Name for logging purposes */ | |
70 | const struct fs_parameter_spec *specs; /* List of param specifications */ | |
71 | const struct fs_parameter_enum *enums; /* Enum values */ | |
72 | }; | |
73 | ||
74 | /* | |
75 | * Result of parse. | |
76 | */ | |
77 | struct fs_parse_result { | |
78 | bool negated; /* T if param was "noxxx" */ | |
79 | bool has_value; /* T if value supplied to param */ | |
80 | union { | |
81 | bool boolean; /* For spec_bool */ | |
82 | int int_32; /* For spec_s32/spec_enum */ | |
83 | unsigned int uint_32; /* For spec_u32{,_octal,_hex}/spec_enum */ | |
84 | u64 uint_64; /* For spec_u64 */ | |
85 | }; | |
86 | }; | |
87 | ||
88 | extern int fs_parse(struct fs_context *fc, | |
89 | const struct fs_parameter_description *desc, | |
90 | struct fs_parameter *value, | |
91 | struct fs_parse_result *result); | |
92 | extern int fs_lookup_param(struct fs_context *fc, | |
93 | struct fs_parameter *param, | |
94 | bool want_bdev, | |
95 | struct path *_path); | |
96 | ||
97 | extern int __lookup_constant(const struct constant_table tbl[], size_t tbl_size, | |
98 | const char *name, int not_found); | |
99 | #define lookup_constant(t, n, nf) __lookup_constant(t, ARRAY_SIZE(t), (n), (nf)) | |
100 | ||
101 | #ifdef CONFIG_VALIDATE_FS_PARSER | |
102 | extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, | |
103 | int low, int high, int special); | |
104 | extern bool fs_validate_description(const struct fs_parameter_description *desc); | |
105 | #else | |
106 | static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size, | |
107 | int low, int high, int special) | |
108 | { return true; } | |
109 | static inline bool fs_validate_description(const struct fs_parameter_description *desc) | |
110 | { return true; } | |
111 | #endif | |
112 | ||
113 | /* | |
114 | * Parameter type, name, index and flags element constructors. Use as: | |
115 | * | |
116 | * fsparam_xxxx("foo", Opt_foo) | |
117 | * | |
118 | * If existing helpers are not enough, direct use of __fsparam() would | |
119 | * work, but any such case is probably a sign that new helper is needed. | |
120 | * Helpers will remain stable; low-level implementation may change. | |
121 | */ | |
122 | #define __fsparam(TYPE, NAME, OPT, FLAGS) \ | |
123 | { \ | |
124 | .name = NAME, \ | |
125 | .opt = OPT, \ | |
126 | .type = TYPE, \ | |
127 | .flags = FLAGS \ | |
128 | } | |
129 | ||
130 | #define fsparam_flag(NAME, OPT) __fsparam(fs_param_is_flag, NAME, OPT, 0) | |
131 | #define fsparam_flag_no(NAME, OPT) \ | |
132 | __fsparam(fs_param_is_flag, NAME, OPT, \ | |
133 | fs_param_neg_with_no) | |
134 | #define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0) | |
135 | #define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0) | |
136 | #define fsparam_u32oct(NAME, OPT) \ | |
137 | __fsparam(fs_param_is_u32_octal, NAME, OPT, 0) | |
138 | #define fsparam_u32hex(NAME, OPT) \ | |
139 | __fsparam(fs_param_is_u32_hex, NAME, OPT, 0) | |
140 | #define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0) | |
141 | #define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0) | |
142 | #define fsparam_enum(NAME, OPT) __fsparam(fs_param_is_enum, NAME, OPT, 0) | |
143 | #define fsparam_string(NAME, OPT) \ | |
144 | __fsparam(fs_param_is_string, NAME, OPT, 0) | |
145 | #define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0) | |
146 | #define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0) | |
147 | #define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0) | |
148 | #define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0) | |
149 | ||
150 | ||
151 | #endif /* _LINUX_FS_PARSER_H */ |