Skip to content

Commit a20971c

Browse files
dhowellsbrauner
authored andcommitted
vfs: Convert debugfs to use the new mount API
Convert the debugfs filesystem to the new internal mount API as the old one will be obsoleted and removed. This allows greater flexibility in communication of mount parameters between userspace, the VFS and the filesystem. See Documentation/filesystems/mount_api.txt for more information. Signed-off-by: David Howells <dhowells@redhat.com> Co-developed-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Eric Sandeen <sandeen@redhat.com> [sandeen: forward port to modern kernel, fix remounting] Link: https://lore.kernel.org/r/49d1f108-46e3-443f-85a3-6dd730c5d076@redhat.com cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> cc: Rafael J. Wysocki <rafael@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 8f27829 commit a20971c

File tree

1 file changed

+93
-105
lines changed

1 file changed

+93
-105
lines changed

fs/debugfs/inode.c

Lines changed: 93 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414

1515
#include <linux/module.h>
1616
#include <linux/fs.h>
17-
#include <linux/mount.h>
17+
#include <linux/fs_context.h>
18+
#include <linux/fs_parser.h>
1819
#include <linux/pagemap.h>
1920
#include <linux/init.h>
2021
#include <linux/kobject.h>
@@ -23,7 +24,6 @@
2324
#include <linux/fsnotify.h>
2425
#include <linux/string.h>
2526
#include <linux/seq_file.h>
26-
#include <linux/parser.h>
2727
#include <linux/magic.h>
2828
#include <linux/slab.h>
2929
#include <linux/security.h>
@@ -77,7 +77,7 @@ static struct inode *debugfs_get_inode(struct super_block *sb)
7777
return inode;
7878
}
7979

80-
struct debugfs_mount_opts {
80+
struct debugfs_fs_info {
8181
kuid_t uid;
8282
kgid_t gid;
8383
umode_t mode;
@@ -89,92 +89,74 @@ enum {
8989
Opt_uid,
9090
Opt_gid,
9191
Opt_mode,
92-
Opt_err
9392
};
9493

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+
{}
10099
};
101100

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)
107102
{
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;
111105
kuid_t uid;
112106
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+
*/
152133
}
153134

135+
opts->opts |= BIT(opt);
136+
154137
return 0;
155138
}
156139

157140
static void _debugfs_apply_options(struct super_block *sb, bool remount)
158141
{
159142
struct debugfs_fs_info *fsi = sb->s_fs_info;
160143
struct inode *inode = d_inode(sb->s_root);
161-
struct debugfs_mount_opts *opts = &fsi->mount_opts;
162144

163145
/*
164146
* On remount, only reset mode/uid/gid if they were provided as mount
165147
* options.
166148
*/
167149

168-
if (!remount || opts->opts & BIT(Opt_mode)) {
150+
if (!remount || fsi->opts & BIT(Opt_mode)) {
169151
inode->i_mode &= ~S_IALLUGO;
170-
inode->i_mode |= opts->mode;
152+
inode->i_mode |= fsi->mode;
171153
}
172154

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;
175157

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;
178160
}
179161

180162
static void debugfs_apply_options(struct super_block *sb)
@@ -187,35 +169,33 @@ static void debugfs_apply_options_remount(struct super_block *sb)
187169
_debugfs_apply_options(sb, true);
188170
}
189171

190-
static int debugfs_remount(struct super_block *sb, int *flags, char *data)
172+
static int debugfs_reconfigure(struct fs_context *fc)
191173
{
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;
194177

195178
sync_filesystem(sb);
196-
err = debugfs_parse_options(data, &fsi->mount_opts);
197-
if (err)
198-
goto fail;
199179

180+
/* structure copy of new mount options to sb */
181+
*sb_opts = *new_opts;
200182
debugfs_apply_options_remount(sb);
201183

202-
fail:
203-
return err;
184+
return 0;
204185
}
205186

206187
static int debugfs_show_options(struct seq_file *m, struct dentry *root)
207188
{
208189
struct debugfs_fs_info *fsi = root->d_sb->s_fs_info;
209-
struct debugfs_mount_opts *opts = &fsi->mount_opts;
210190

211-
if (!uid_eq(opts->uid, GLOBAL_ROOT_UID))
191+
if (!uid_eq(fsi->uid, GLOBAL_ROOT_UID))
212192
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))
215195
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);
219199

220200
return 0;
221201
}
@@ -229,7 +209,6 @@ static void debugfs_free_inode(struct inode *inode)
229209

230210
static const struct super_operations debugfs_super_operations = {
231211
.statfs = simple_statfs,
232-
.remount_fs = debugfs_remount,
233212
.show_options = debugfs_show_options,
234213
.free_inode = debugfs_free_inode,
235214
};
@@ -263,54 +242,63 @@ static const struct dentry_operations debugfs_dops = {
263242
.d_automount = debugfs_automount,
264243
};
265244

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)
267246
{
268247
static const struct tree_descr debug_files[] = {{""}};
269-
struct debugfs_fs_info *fsi;
270248
int err;
271249

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);
280251
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;
286253

287254
sb->s_op = &debugfs_super_operations;
288255
sb->s_d_op = &debugfs_dops;
289256

290257
debugfs_apply_options(sb);
291258

292259
return 0;
293-
294-
fail:
295-
kfree(fsi);
296-
sb->s_fs_info = NULL;
297-
return err;
298260
}
299261

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)
303263
{
304264
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+
}
306274

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;
308295
}
309296

310297
static struct file_system_type debug_fs_type = {
311298
.owner = THIS_MODULE,
312299
.name = "debugfs",
313-
.mount = debug_mount,
300+
.init_fs_context = debugfs_init_fs_context,
301+
.parameters = debugfs_param_specs,
314302
.kill_sb = kill_litter_super,
315303
};
316304
MODULE_ALIAS_FS("debugfs");

0 commit comments

Comments
 (0)