Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 288846
b: refs/heads/master
c: d6e4868
h: refs/heads/master
v: v3
  • Loading branch information
Ludwig Nussel authored and Greg Kroah-Hartman committed Jan 26, 2012
1 parent 176e5ee commit 64555ba
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 3 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9875bb480cc89d9b690f7028aadf7e58454f0dae
refs/heads/master: d6e486868cde585842d55ba3b6ec57af090fc343
5 changes: 4 additions & 1 deletion trunk/Documentation/filesystems/debugfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ Debugfs is typically mounted with a command like:

mount -t debugfs none /sys/kernel/debug

(Or an equivalent /etc/fstab line).
(Or an equivalent /etc/fstab line).
The debugfs root directory is accessible by anyone by default. To
restrict access to the tree the "uid", "gid" and "mode" mount
options can be used.

Note that the debugfs API is exported GPL-only to modules.

Expand Down
149 changes: 148 additions & 1 deletion trunk/fs/debugfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,13 @@
#include <linux/debugfs.h>
#include <linux/fsnotify.h>
#include <linux/string.h>
#include <linux/seq_file.h>
#include <linux/parser.h>
#include <linux/magic.h>
#include <linux/slab.h>

#define DEBUGFS_DEFAULT_MODE 0755

static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;
static bool debugfs_registered;
Expand Down Expand Up @@ -125,11 +129,154 @@ static inline int debugfs_positive(struct dentry *dentry)
return dentry->d_inode && !d_unhashed(dentry);
}

struct debugfs_mount_opts {
uid_t uid;
gid_t gid;
umode_t mode;
};

enum {
Opt_uid,
Opt_gid,
Opt_mode,
Opt_err
};

static const match_table_t tokens = {
{Opt_uid, "uid=%u"},
{Opt_gid, "gid=%u"},
{Opt_mode, "mode=%o"},
{Opt_err, NULL}
};

struct debugfs_fs_info {
struct debugfs_mount_opts mount_opts;
};

static int debugfs_parse_options(char *data, struct debugfs_mount_opts *opts)
{
substring_t args[MAX_OPT_ARGS];
int option;
int token;
char *p;

opts->mode = DEBUGFS_DEFAULT_MODE;

while ((p = strsep(&data, ",")) != NULL) {
if (!*p)
continue;

token = match_token(p, tokens, args);
switch (token) {
case Opt_uid:
if (match_int(&args[0], &option))
return -EINVAL;
opts->uid = option;
break;
case Opt_gid:
if (match_octal(&args[0], &option))
return -EINVAL;
opts->gid = option;
break;
case Opt_mode:
if (match_octal(&args[0], &option))
return -EINVAL;
opts->mode = option & S_IALLUGO;
break;
/*
* We might like to report bad mount options here;
* but traditionally debugfs has ignored all mount options
*/
}
}

return 0;
}

static int debugfs_apply_options(struct super_block *sb)
{
struct debugfs_fs_info *fsi = sb->s_fs_info;
struct inode *inode = sb->s_root->d_inode;
struct debugfs_mount_opts *opts = &fsi->mount_opts;

inode->i_mode &= ~S_IALLUGO;
inode->i_mode |= opts->mode;

inode->i_uid = opts->uid;
inode->i_gid = opts->gid;

return 0;
}

static int debugfs_remount(struct super_block *sb, int *flags, char *data)
{
int err;
struct debugfs_fs_info *fsi = sb->s_fs_info;

err = debugfs_parse_options(data, &fsi->mount_opts);
if (err)
goto fail;

debugfs_apply_options(sb);

fail:
return err;
}

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

if (opts->uid != 0)
seq_printf(m, ",uid=%u", opts->uid);
if (opts->gid != 0)
seq_printf(m, ",gid=%u", opts->gid);
if (opts->mode != DEBUGFS_DEFAULT_MODE)
seq_printf(m, ",mode=%o", opts->mode);

return 0;
}

static const struct super_operations debugfs_super_operations = {
.statfs = simple_statfs,
.remount_fs = debugfs_remount,
.show_options = debugfs_show_options,
};

static int debug_fill_super(struct super_block *sb, void *data, int silent)
{
static struct tree_descr debug_files[] = {{""}};
struct debugfs_fs_info *fsi;
int err;

save_mount_options(sb, data);

fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL);
sb->s_fs_info = fsi;
if (!fsi) {
err = -ENOMEM;
goto fail;
}

err = debugfs_parse_options(data, &fsi->mount_opts);
if (err)
goto fail;

err = simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
if (err)
goto fail;

sb->s_op = &debugfs_super_operations;

debugfs_apply_options(sb);

return 0;

return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
fail:
kfree(fsi);
sb->s_fs_info = NULL;
return err;
}

static struct dentry *debug_mount(struct file_system_type *fs_type,
Expand Down

0 comments on commit 64555ba

Please sign in to comment.