anonymous_inode.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. https://stackoverflow.com/questions/4508998/what-is-anonymous-inode
  3. anon_inode_getfd example:
  4. - get an anonymous inode via ioctl from a debugfs entry
  5. - read jiffies from that inode
  6. This method allows getting multiple file descriptors from a single filesystem,
  7. which reduces namespace pollution.
  8. */
  9. #include <asm/uaccess.h> /* copy_from_user, copy_to_user */
  10. #include <linux/anon_inodes.h>
  11. #include <linux/debugfs.h>
  12. #include <linux/errno.h> /* EFAULT */
  13. #include <linux/fs.h>
  14. #include <linux/jiffies.h>
  15. #include <linux/kernel.h> /* min */
  16. #include <linux/module.h>
  17. #include <linux/printk.h> /* printk */
  18. #include "anonymous_inode.h"
  19. MODULE_LICENSE("GPL");
  20. static struct dentry *dir;
  21. static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off)
  22. {
  23. char kbuf[1024];
  24. size_t ret;
  25. ret = snprintf(kbuf, sizeof(kbuf), "%llu", (unsigned long long)jiffies);
  26. if (copy_to_user(buf, kbuf, ret)) {
  27. ret = -EFAULT;
  28. }
  29. return ret;
  30. }
  31. static const struct file_operations fops_anon = {
  32. .read = read,
  33. };
  34. static long unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long argp)
  35. {
  36. int fd;
  37. switch (cmd) {
  38. case LKMC_ANONYMOUS_INODE_GET_FD:
  39. fd = anon_inode_getfd(
  40. "random",
  41. &fops_anon,
  42. NULL,
  43. O_RDONLY | O_CLOEXEC
  44. );
  45. if (copy_to_user((void __user *)argp, &fd, sizeof(fd))) {
  46. return -EFAULT;
  47. }
  48. break;
  49. default:
  50. return -EINVAL;
  51. break;
  52. }
  53. return 0;
  54. }
  55. static const struct file_operations fops_ioctl = {
  56. .unlocked_ioctl = unlocked_ioctl
  57. };
  58. static int myinit(void)
  59. {
  60. dir = debugfs_create_dir("lkmc_anonymous_inode", 0);
  61. debugfs_create_file("f", 0, dir, NULL, &fops_ioctl);
  62. return 0;
  63. }
  64. static void myexit(void)
  65. {
  66. debugfs_remove_recursive(dir);
  67. }
  68. module_init(myinit)
  69. module_exit(myexit)