@@ -46,19 +46,40 @@ int lookup_constant(const struct constant_table *tbl, const char *name, int not_
46
46
}
47
47
EXPORT_SYMBOL (lookup_constant );
48
48
49
+ static inline bool is_flag (const struct fs_parameter_spec * p )
50
+ {
51
+ return p -> type == fs_param_is_flag ;
52
+ }
53
+
49
54
static const struct fs_parameter_spec * fs_lookup_key (
50
55
const struct fs_parameter_spec * desc ,
51
- const char * name )
56
+ struct fs_parameter * param , bool * negated )
52
57
{
53
- const struct fs_parameter_spec * p ;
54
- if (!desc )
55
- return NULL ;
56
-
57
- for (p = desc ; p -> name ; p ++ )
58
- if (strcmp (p -> name , name ) == 0 )
58
+ const struct fs_parameter_spec * p , * other = NULL ;
59
+ const char * name = param -> key ;
60
+ bool want_flag = param -> type == fs_value_is_flag ;
61
+
62
+ * negated = false;
63
+ for (p = desc ; p -> name ; p ++ ) {
64
+ if (strcmp (p -> name , name ) != 0 )
65
+ continue ;
66
+ if (likely (is_flag (p ) == want_flag ))
59
67
return p ;
60
-
61
- return NULL ;
68
+ other = p ;
69
+ }
70
+ if (want_flag ) {
71
+ if (name [0 ] == 'n' && name [1 ] == 'o' && name [2 ]) {
72
+ for (p = desc ; p -> name ; p ++ ) {
73
+ if (strcmp (p -> name , name + 2 ) != 0 )
74
+ continue ;
75
+ if (!(p -> flags & fs_param_neg_with_no ))
76
+ continue ;
77
+ * negated = true;
78
+ return p ;
79
+ }
80
+ }
81
+ }
82
+ return other ;
62
83
}
63
84
64
85
/*
@@ -88,123 +109,77 @@ int __fs_parse(struct p_log *log,
88
109
const struct constant_table * e ;
89
110
int ret = - ENOPARAM , b ;
90
111
91
- result -> negated = false;
92
112
result -> uint_64 = 0 ;
93
113
94
- p = fs_lookup_key (desc , param -> key );
95
- if (!p ) {
96
- /* If we didn't find something that looks like "noxxx", see if
97
- * "xxx" takes the "no"-form negative - but only if there
98
- * wasn't an value.
99
- */
100
- if (param -> type != fs_value_is_flag )
101
- goto unknown_parameter ;
102
- if (param -> key [0 ] != 'n' || param -> key [1 ] != 'o' || !param -> key [2 ])
103
- goto unknown_parameter ;
104
-
105
- p = fs_lookup_key (desc , param -> key + 2 );
106
- if (!p )
107
- goto unknown_parameter ;
108
- if (!(p -> flags & fs_param_neg_with_no ))
109
- goto unknown_parameter ;
110
- result -> boolean = false;
111
- result -> negated = true;
112
- }
114
+ p = fs_lookup_key (desc , param , & result -> negated );
115
+ if (!p )
116
+ return - ENOPARAM ;
113
117
114
118
if (p -> flags & fs_param_deprecated )
115
119
warn_plog (log , "Deprecated parameter '%s'" , param -> key );
116
120
117
- if (result -> negated )
118
- goto okay ;
119
-
120
- /* Certain parameter types only take a string and convert it. */
121
- switch (p -> type ) {
122
- case __fs_param_wasnt_defined :
123
- return - EINVAL ;
124
- case fs_param_is_u32 :
125
- case fs_param_is_u32_octal :
126
- case fs_param_is_u32_hex :
127
- case fs_param_is_s32 :
128
- case fs_param_is_u64 :
129
- case fs_param_is_enum :
130
- case fs_param_is_string :
131
- if (param -> type == fs_value_is_string ) {
132
- if (p -> flags & fs_param_v_optional )
133
- break ;
134
- if (!* param -> string )
135
- goto bad_value ;
136
- break ;
137
- }
138
- if (param -> type == fs_value_is_flag ) {
139
- if (p -> flags & fs_param_v_optional )
140
- goto okay ;
141
- }
142
- goto bad_value ;
143
- default :
144
- break ;
145
- }
146
-
147
121
/* Try to turn the type we were given into the type desired by the
148
122
* parameter and give an error if we can't.
149
123
*/
150
124
switch (p -> type ) {
125
+ case __fs_param_wasnt_defined :
126
+ return - EINVAL ;
151
127
case fs_param_is_flag :
152
128
if (param -> type != fs_value_is_flag )
153
129
return inval_plog (log , "Unexpected value for '%s'" ,
154
130
param -> key );
155
- result -> boolean = true ;
131
+ result -> boolean = ! result -> negated ;
156
132
goto okay ;
157
-
158
133
case fs_param_is_bool :
159
- switch (param -> type ) {
160
- case fs_value_is_flag :
161
- result -> boolean = true;
162
- goto okay ;
163
- case fs_value_is_string :
164
- if (param -> size == 0 ) {
165
- result -> boolean = true;
166
- goto okay ;
167
- }
168
- b = lookup_constant (bool_names , param -> string , -1 );
169
- if (b == -1 )
170
- goto bad_value ;
171
- result -> boolean = b ;
172
- goto okay ;
173
- default :
134
+ if (param -> type != fs_value_is_string )
174
135
goto bad_value ;
175
- }
176
-
136
+ b = lookup_constant (bool_names , param -> string , -1 );
137
+ if (b == -1 )
138
+ goto bad_value ;
139
+ result -> boolean = b ;
140
+ goto okay ;
177
141
case fs_param_is_u32 :
142
+ if (param -> type != fs_value_is_string )
143
+ goto bad_value ;
178
144
ret = kstrtouint (param -> string , 0 , & result -> uint_32 );
179
145
goto maybe_okay ;
180
146
case fs_param_is_u32_octal :
147
+ if (param -> type != fs_value_is_string )
148
+ goto bad_value ;
181
149
ret = kstrtouint (param -> string , 8 , & result -> uint_32 );
182
150
goto maybe_okay ;
183
151
case fs_param_is_u32_hex :
152
+ if (param -> type != fs_value_is_string )
153
+ goto bad_value ;
184
154
ret = kstrtouint (param -> string , 16 , & result -> uint_32 );
185
155
goto maybe_okay ;
186
156
case fs_param_is_s32 :
157
+ if (param -> type != fs_value_is_string )
158
+ goto bad_value ;
187
159
ret = kstrtoint (param -> string , 0 , & result -> int_32 );
188
160
goto maybe_okay ;
189
161
case fs_param_is_u64 :
162
+ if (param -> type != fs_value_is_string )
163
+ goto bad_value ;
190
164
ret = kstrtoull (param -> string , 0 , & result -> uint_64 );
191
165
goto maybe_okay ;
192
-
193
166
case fs_param_is_enum :
167
+ if (param -> type != fs_value_is_string )
168
+ goto bad_value ;
194
169
e = __lookup_constant (p -> data , param -> string );
195
170
if (e ) {
196
171
result -> uint_32 = e -> value ;
197
172
goto okay ;
198
173
}
199
174
goto bad_value ;
200
-
201
175
case fs_param_is_string :
176
+ if (param -> type != fs_value_is_string || !* param -> string )
177
+ goto bad_value ;
202
178
goto okay ;
203
179
case fs_param_is_blob :
204
180
if (param -> type != fs_value_is_blob )
205
181
goto bad_value ;
206
182
goto okay ;
207
-
208
183
case fs_param_is_fd : {
209
184
switch (param -> type ) {
210
185
case fs_value_is_string :
@@ -221,7 +196,6 @@ int __fs_parse(struct p_log *log,
221
196
goto bad_value ;
222
197
goto maybe_okay ;
223
198
}
224
-
225
199
case fs_param_is_blockdev :
226
200
case fs_param_is_path :
227
201
goto okay ;
@@ -237,8 +211,6 @@ int __fs_parse(struct p_log *log,
237
211
238
212
bad_value :
239
213
return inval_plog (log , "Bad value for '%s'" , param -> key );
240
- unknown_parameter :
241
- return - ENOPARAM ;
242
214
}
243
215
EXPORT_SYMBOL (__fs_parse );
244
216
@@ -382,6 +354,8 @@ bool fs_validate_description(const char *name,
382
354
/* Check for duplicate parameter names */
383
355
for (p2 = desc ; p2 < param ; p2 ++ ) {
384
356
if (strcmp (param -> name , p2 -> name ) == 0 ) {
357
+ if (is_flag (param ) != is_flag (p2 ))
358
+ continue ;
385
359
pr_err ("VALIDATE %s: PARAM[%s]: Duplicate\n" ,
386
360
name , param -> name );
387
361
good = false;
0 commit comments