anonymous_inode.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 <linux/anon_inodes.h>
  10. #include <linux/debugfs.h>
  11. #include <linux/errno.h> /* EFAULT */
  12. #include <linux/fs.h>
  13. #include <linux/jiffies.h>
  14. #include <linux/kernel.h> /* min */
  15. #include <linux/module.h>
  16. #include <linux/printk.h> /* printk */
  17. #include <linux/uaccess.h> /* copy_from_user */
  18. #include "anonymous_inode.h"
  19. static struct dentry *debugfs_file;
  20. static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off)
  21. {
  22. char kbuf[1024];
  23. size_t ret;
  24. ret = snprintf(kbuf, sizeof(kbuf), "%llu", (unsigned long long)jiffies);
  25. if (copy_to_user(buf, kbuf, ret)) {
  26. ret = -EFAULT;
  27. }
  28. return ret;
  29. }
  30. static const struct file_operations fops_anon = {
  31. .read = read,
  32. };
  33. static long unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long argp)
  34. {
  35. int fd;
  36. switch (cmd) {
  37. case LKMC_ANONYMOUS_INODE_GET_FD:
  38. fd = anon_inode_getfd(
  39. "random",
  40. &fops_anon,
  41. NULL,
  42. O_RDONLY | O_CLOEXEC
  43. );
  44. if (copy_to_user((void __user *)argp, &fd, sizeof(fd))) {
  45. return -EFAULT;
  46. }
  47. break;
  48. default:
  49. return -EINVAL;
  50. break;
  51. }
  52. return 0;
  53. }
  54. static const struct file_operations fops_ioctl = {
  55. .owner = THIS_MODULE,
  56. .unlocked_ioctl = unlocked_ioctl
  57. };
  58. static int myinit(void)
  59. {
  60. debugfs_file = debugfs_create_file("lkmc_anonymous_inode", 0, NULL, NULL, &fops_ioctl);
  61. return 0;
  62. }
  63. static void myexit(void)
  64. {
  65. debugfs_remove(debugfs_file);
  66. }
  67. module_init(myinit)
  68. module_exit(myexit)
  69. MODULE_LICENSE("GPL");