42_little-penguin/ass09/main.c
2024-08-07 12:33:08 +02:00

81 lines
1.8 KiB
C

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/seq_file.h>
#include <linux/fs.h>
#include <linux/mount.h>
#include <linux/path.h>
#include <linux/proc_fs.h>
#include <linux/nsproxy.h>
#include <../fs/mount.h>
#define PROCFS_MAX_SIZE 1024
#define PROCFS_NAME "mymounts"
MODULE_LICENSE("GPL");
static int ft_proc_open(struct inode *inode, struct file *file);
static struct proc_dir_entry *proc_file;
static const struct proc_ops proc_file_ops = {
.proc_open = ft_proc_open,
.proc_read = seq_read,
.proc_lseek = seq_lseek,
.proc_release = single_release,
};
static void show_mount(struct seq_file *m, struct mount *mnt)
{
struct path mnt_path = {
.dentry = mnt->mnt.mnt_root,
.mnt = &mnt->mnt
};
seq_printf(m, "%-15s", mnt->mnt_devname);
seq_path(m, &mnt_path, " \t\n\\");
seq_putc(m, '\n');
}
static void traverse_mount_tree(struct seq_file *m, struct rb_node *node)
{
struct mount *mnt;
if (!node)
return;
mnt = rb_entry(node, struct mount, mnt_node);
show_mount(m, mnt);
traverse_mount_tree(m, node->rb_left);
traverse_mount_tree(m, node->rb_right);
}
static int ft_proc_show(struct seq_file *m, void *v)
{
struct rb_root *root = &current->nsproxy->mnt_ns->mounts;
traverse_mount_tree(m, root->rb_node);
return 0;
}
static int ft_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, ft_proc_show, NULL);
}
static int __init mymounts_init(void)
{
proc_file = proc_create(PROCFS_NAME, 0644, NULL, &proc_file_ops);
if (proc_file == NULL) {
proc_remove(proc_file);
pr_err("could not initialize /proc/%s\n", PROCFS_NAME);
return -ENOMEM;
}
return 0;
}
static void __exit mymounts_exit(void)
{
proc_remove(proc_file);
}
module_init(mymounts_init);
module_exit(mymounts_exit);