/* https://stackoverflow.com/questions/4508998/what-is-anonymous-inode anon_inode_getfd example: - get an anonymous inode via ioctl from a debugfs entry - read jiffies from that inode This method allows getting multiple file descriptors from a single filesystem, which reduces namespace pollution. */ #include /* copy_from_user, copy_to_user */ #include #include #include /* EFAULT */ #include #include #include /* min */ #include #include /* printk */ #include "anonymous_inode.h" MODULE_LICENSE("GPL"); static struct dentry *dir; static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off) { char kbuf[1024]; size_t ret; ret = snprintf(kbuf, sizeof(kbuf), "%llu", (unsigned long long)jiffies); if (copy_to_user(buf, kbuf, ret)) { ret = -EFAULT; } return ret; } static const struct file_operations fops_anon = { .read = read, }; static long unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long argp) { int fd; switch (cmd) { case LKMC_ANONYMOUS_INODE_GET_FD: fd = anon_inode_getfd( "random", &fops_anon, NULL, O_RDONLY | O_CLOEXEC ); if (copy_to_user((void __user *)argp, &fd, sizeof(fd))) { return -EFAULT; } break; default: return -EINVAL; break; } return 0; } static const struct file_operations fops_ioctl = { .owner = THIS_MODULE, .unlocked_ioctl = unlocked_ioctl }; static int myinit(void) { dir = debugfs_create_dir("lkmc_anonymous_inode", 0); debugfs_create_file("f", 0, dir, NULL, &fops_ioctl); return 0; } static void myexit(void) { debugfs_remove_recursive(dir); } module_init(myinit) module_exit(myexit)