14
14
15
15
#include <linux/module.h>
16
16
#include <linux/fs.h>
17
- #include <linux/mount.h>
17
+ #include <linux/fs_context.h>
18
+ #include <linux/fs_parser.h>
18
19
#include <linux/pagemap.h>
19
20
#include <linux/init.h>
20
21
#include <linux/kobject.h>
23
24
#include <linux/fsnotify.h>
24
25
#include <linux/string.h>
25
26
#include <linux/seq_file.h>
26
- #include <linux/parser.h>
27
27
#include <linux/magic.h>
28
28
#include <linux/slab.h>
29
29
#include <linux/security.h>
@@ -77,7 +77,7 @@ static struct inode *debugfs_get_inode(struct super_block *sb)
77
77
return inode ;
78
78
}
79
79
80
- struct debugfs_mount_opts {
80
+ struct debugfs_fs_info {
81
81
kuid_t uid ;
82
82
kgid_t gid ;
83
83
umode_t mode ;
@@ -89,92 +89,74 @@ enum {
89
89
Opt_uid ,
90
90
Opt_gid ,
91
91
Opt_mode ,
92
- Opt_err
93
92
};
94
93
95
- static const match_table_t tokens = {
96
- { Opt_uid , "uid=%u" } ,
97
- { Opt_gid , "gid=%u" } ,
98
- { Opt_mode , "mode=%o" } ,
99
- {Opt_err , NULL }
94
+ static const struct fs_parameter_spec debugfs_param_specs [] = {
95
+ fsparam_u32 ( "gid" , Opt_gid ) ,
96
+ fsparam_u32oct ( "mode" , Opt_mode ) ,
97
+ fsparam_u32 ( "uid" , Opt_uid ) ,
98
+ {}
100
99
};
101
100
102
- struct debugfs_fs_info {
103
- struct debugfs_mount_opts mount_opts ;
104
- };
105
-
106
- static int debugfs_parse_options (char * data , struct debugfs_mount_opts * opts )
101
+ static int debugfs_parse_param (struct fs_context * fc , struct fs_parameter * param )
107
102
{
108
- substring_t args [MAX_OPT_ARGS ];
109
- int option ;
110
- int token ;
103
+ struct debugfs_fs_info * opts = fc -> s_fs_info ;
104
+ struct fs_parse_result result ;
111
105
kuid_t uid ;
112
106
kgid_t gid ;
113
- char * p ;
114
-
115
- opts -> opts = 0 ;
116
- opts -> mode = DEBUGFS_DEFAULT_MODE ;
117
-
118
- while ((p = strsep (& data , "," )) != NULL ) {
119
- if (!* p )
120
- continue ;
121
-
122
- token = match_token (p , tokens , args );
123
- switch (token ) {
124
- case Opt_uid :
125
- if (match_int (& args [0 ], & option ))
126
- return - EINVAL ;
127
- uid = make_kuid (current_user_ns (), option );
128
- if (!uid_valid (uid ))
129
- return - EINVAL ;
130
- opts -> uid = uid ;
131
- break ;
132
- case Opt_gid :
133
- if (match_int (& args [0 ], & option ))
134
- return - EINVAL ;
135
- gid = make_kgid (current_user_ns (), option );
136
- if (!gid_valid (gid ))
137
- return - EINVAL ;
138
- opts -> gid = gid ;
139
- break ;
140
- case Opt_mode :
141
- if (match_octal (& args [0 ], & option ))
142
- return - EINVAL ;
143
- opts -> mode = option & S_IALLUGO ;
144
- break ;
145
- /*
146
- * We might like to report bad mount options here;
147
- * but traditionally debugfs has ignored all mount options
148
- */
149
- }
150
-
151
- opts -> opts |= BIT (token );
107
+ int opt ;
108
+
109
+ opt = fs_parse (fc , debugfs_param_specs , param , & result );
110
+ if (opt < 0 )
111
+ return opt ;
112
+
113
+ switch (opt ) {
114
+ case Opt_uid :
115
+ uid = make_kuid (current_user_ns (), result .uint_32 );
116
+ if (!uid_valid (uid ))
117
+ return invalf (fc , "Unknown uid" );
118
+ opts -> uid = uid ;
119
+ break ;
120
+ case Opt_gid :
121
+ gid = make_kgid (current_user_ns (), result .uint_32 );
122
+ if (!gid_valid (gid ))
123
+ return invalf (fc , "Unknown gid" );
124
+ opts -> gid = gid ;
125
+ break ;
126
+ case Opt_mode :
127
+ opts -> mode = result .uint_32 & S_IALLUGO ;
128
+ break ;
129
+ /*
130
+ * We might like to report bad mount options here;
131
+ * but traditionally debugfs has ignored all mount options
132
+ */
152
133
}
153
134
135
+ opts -> opts |= BIT (opt );
136
+
154
137
return 0 ;
155
138
}
156
139
157
140
static void _debugfs_apply_options (struct super_block * sb , bool remount )
158
141
{
159
142
struct debugfs_fs_info * fsi = sb -> s_fs_info ;
160
143
struct inode * inode = d_inode (sb -> s_root );
161
- struct debugfs_mount_opts * opts = & fsi -> mount_opts ;
162
144
163
145
/*
164
146
* On remount, only reset mode/uid/gid if they were provided as mount
165
147
* options.
166
148
*/
167
149
168
- if (!remount || opts -> opts & BIT (Opt_mode )) {
150
+ if (!remount || fsi -> opts & BIT (Opt_mode )) {
169
151
inode -> i_mode &= ~S_IALLUGO ;
170
- inode -> i_mode |= opts -> mode ;
152
+ inode -> i_mode |= fsi -> mode ;
171
153
}
172
154
173
- if (!remount || opts -> opts & BIT (Opt_uid ))
174
- inode -> i_uid = opts -> uid ;
155
+ if (!remount || fsi -> opts & BIT (Opt_uid ))
156
+ inode -> i_uid = fsi -> uid ;
175
157
176
- if (!remount || opts -> opts & BIT (Opt_gid ))
177
- inode -> i_gid = opts -> gid ;
158
+ if (!remount || fsi -> opts & BIT (Opt_gid ))
159
+ inode -> i_gid = fsi -> gid ;
178
160
}
179
161
180
162
static void debugfs_apply_options (struct super_block * sb )
@@ -187,35 +169,33 @@ static void debugfs_apply_options_remount(struct super_block *sb)
187
169
_debugfs_apply_options (sb , true);
188
170
}
189
171
190
- static int debugfs_remount (struct super_block * sb , int * flags , char * data )
172
+ static int debugfs_reconfigure (struct fs_context * fc )
191
173
{
192
- int err ;
193
- struct debugfs_fs_info * fsi = sb -> s_fs_info ;
174
+ struct super_block * sb = fc -> root -> d_sb ;
175
+ struct debugfs_fs_info * sb_opts = sb -> s_fs_info ;
176
+ struct debugfs_fs_info * new_opts = fc -> s_fs_info ;
194
177
195
178
sync_filesystem (sb );
196
- err = debugfs_parse_options (data , & fsi -> mount_opts );
197
- if (err )
198
- goto fail ;
199
179
180
+ /* structure copy of new mount options to sb */
181
+ * sb_opts = * new_opts ;
200
182
debugfs_apply_options_remount (sb );
201
183
202
- fail :
203
- return err ;
184
+ return 0 ;
204
185
}
205
186
206
187
static int debugfs_show_options (struct seq_file * m , struct dentry * root )
207
188
{
208
189
struct debugfs_fs_info * fsi = root -> d_sb -> s_fs_info ;
209
- struct debugfs_mount_opts * opts = & fsi -> mount_opts ;
210
190
211
- if (!uid_eq (opts -> uid , GLOBAL_ROOT_UID ))
191
+ if (!uid_eq (fsi -> uid , GLOBAL_ROOT_UID ))
212
192
seq_printf (m , ",uid=%u" ,
213
- from_kuid_munged (& init_user_ns , opts -> uid ));
214
- if (!gid_eq (opts -> gid , GLOBAL_ROOT_GID ))
193
+ from_kuid_munged (& init_user_ns , fsi -> uid ));
194
+ if (!gid_eq (fsi -> gid , GLOBAL_ROOT_GID ))
215
195
seq_printf (m , ",gid=%u" ,
216
- from_kgid_munged (& init_user_ns , opts -> gid ));
217
- if (opts -> mode != DEBUGFS_DEFAULT_MODE )
218
- seq_printf (m , ",mode=%o" , opts -> mode );
196
+ from_kgid_munged (& init_user_ns , fsi -> gid ));
197
+ if (fsi -> mode != DEBUGFS_DEFAULT_MODE )
198
+ seq_printf (m , ",mode=%o" , fsi -> mode );
219
199
220
200
return 0 ;
221
201
}
@@ -229,7 +209,6 @@ static void debugfs_free_inode(struct inode *inode)
229
209
230
210
static const struct super_operations debugfs_super_operations = {
231
211
.statfs = simple_statfs ,
232
- .remount_fs = debugfs_remount ,
233
212
.show_options = debugfs_show_options ,
234
213
.free_inode = debugfs_free_inode ,
235
214
};
@@ -263,54 +242,63 @@ static const struct dentry_operations debugfs_dops = {
263
242
.d_automount = debugfs_automount ,
264
243
};
265
244
266
- static int debug_fill_super (struct super_block * sb , void * data , int silent )
245
+ static int debugfs_fill_super (struct super_block * sb , struct fs_context * fc )
267
246
{
268
247
static const struct tree_descr debug_files [] = {{"" }};
269
- struct debugfs_fs_info * fsi ;
270
248
int err ;
271
249
272
- fsi = kzalloc (sizeof (struct debugfs_fs_info ), GFP_KERNEL );
273
- sb -> s_fs_info = fsi ;
274
- if (!fsi ) {
275
- err = - ENOMEM ;
276
- goto fail ;
277
- }
278
-
279
- err = debugfs_parse_options (data , & fsi -> mount_opts );
250
+ err = simple_fill_super (sb , DEBUGFS_MAGIC , debug_files );
280
251
if (err )
281
- goto fail ;
282
-
283
- err = simple_fill_super (sb , DEBUGFS_MAGIC , debug_files );
284
- if (err )
285
- goto fail ;
252
+ return err ;
286
253
287
254
sb -> s_op = & debugfs_super_operations ;
288
255
sb -> s_d_op = & debugfs_dops ;
289
256
290
257
debugfs_apply_options (sb );
291
258
292
259
return 0 ;
293
-
294
- fail :
295
- kfree (fsi );
296
- sb -> s_fs_info = NULL ;
297
- return err ;
298
260
}
299
261
300
- static struct dentry * debug_mount (struct file_system_type * fs_type ,
301
- int flags , const char * dev_name ,
302
- void * data )
262
+ static int debugfs_get_tree (struct fs_context * fc )
303
263
{
304
264
if (!(debugfs_allow & DEBUGFS_ALLOW_API ))
305
- return ERR_PTR (- EPERM );
265
+ return - EPERM ;
266
+
267
+ return get_tree_single (fc , debugfs_fill_super );
268
+ }
269
+
270
+ static void debugfs_free_fc (struct fs_context * fc )
271
+ {
272
+ kfree (fc -> s_fs_info );
273
+ }
306
274
307
- return mount_single (fs_type , flags , data , debug_fill_super );
275
+ static const struct fs_context_operations debugfs_context_ops = {
276
+ .free = debugfs_free_fc ,
277
+ .parse_param = debugfs_parse_param ,
278
+ .get_tree = debugfs_get_tree ,
279
+ .reconfigure = debugfs_reconfigure ,
280
+ };
281
+
282
+ static int debugfs_init_fs_context (struct fs_context * fc )
283
+ {
284
+ struct debugfs_fs_info * fsi ;
285
+
286
+ fsi = kzalloc (sizeof (struct debugfs_fs_info ), GFP_KERNEL );
287
+ if (!fsi )
288
+ return - ENOMEM ;
289
+
290
+ fsi -> mode = DEBUGFS_DEFAULT_MODE ;
291
+
292
+ fc -> s_fs_info = fsi ;
293
+ fc -> ops = & debugfs_context_ops ;
294
+ return 0 ;
308
295
}
309
296
310
297
static struct file_system_type debug_fs_type = {
311
298
.owner = THIS_MODULE ,
312
299
.name = "debugfs" ,
313
- .mount = debug_mount ,
300
+ .init_fs_context = debugfs_init_fs_context ,
301
+ .parameters = debugfs_param_specs ,
314
302
.kill_sb = kill_litter_super ,
315
303
};
316
304
MODULE_ALIAS_FS ("debugfs" );
0 commit comments