nsfs.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include <linux/mount.h>
  2. #include <linux/file.h>
  3. #include <linux/fs.h>
  4. #include <linux/proc_ns.h>
  5. #include <linux/magic.h>
  6. #include <linux/ktime.h>
  7. static struct vfsmount *nsfs_mnt;
  8. static const struct file_operations ns_file_operations = {
  9. .llseek = no_llseek,
  10. };
  11. static char *ns_dname(struct dentry *dentry, char *buffer, int buflen)
  12. {
  13. struct inode *inode = d_inode(dentry);
  14. const struct proc_ns_operations *ns_ops = dentry->d_fsdata;
  15. return dynamic_dname(dentry, buffer, buflen, "%s:[%lu]",
  16. ns_ops->name, inode->i_ino);
  17. }
  18. static void ns_prune_dentry(struct dentry *dentry)
  19. {
  20. struct inode *inode = d_inode(dentry);
  21. if (inode) {
  22. struct ns_common *ns = inode->i_private;
  23. atomic_long_set(&ns->stashed, 0);
  24. }
  25. }
  26. const struct dentry_operations ns_dentry_operations =
  27. {
  28. .d_prune = ns_prune_dentry,
  29. .d_delete = always_delete_dentry,
  30. .d_dname = ns_dname,
  31. };
  32. static void nsfs_evict(struct inode *inode)
  33. {
  34. struct ns_common *ns = inode->i_private;
  35. clear_inode(inode);
  36. ns->ops->put(ns);
  37. }
  38. void *ns_get_path(struct path *path, struct task_struct *task,
  39. const struct proc_ns_operations *ns_ops)
  40. {
  41. struct vfsmount *mnt = mntget(nsfs_mnt);
  42. struct qstr qname = { .name = "", };
  43. struct dentry *dentry;
  44. struct inode *inode;
  45. struct ns_common *ns;
  46. unsigned long d;
  47. again:
  48. ns = ns_ops->get(task);
  49. if (!ns) {
  50. mntput(mnt);
  51. return ERR_PTR(-ENOENT);
  52. }
  53. rcu_read_lock();
  54. d = atomic_long_read(&ns->stashed);
  55. if (!d)
  56. goto slow;
  57. dentry = (struct dentry *)d;
  58. if (!lockref_get_not_dead(&dentry->d_lockref))
  59. goto slow;
  60. rcu_read_unlock();
  61. ns_ops->put(ns);
  62. got_it:
  63. path->mnt = mnt;
  64. path->dentry = dentry;
  65. return NULL;
  66. slow:
  67. rcu_read_unlock();
  68. inode = new_inode_pseudo(mnt->mnt_sb);
  69. if (!inode) {
  70. ns_ops->put(ns);
  71. mntput(mnt);
  72. return ERR_PTR(-ENOMEM);
  73. }
  74. inode->i_ino = ns->inum;
  75. inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
  76. inode->i_flags |= S_IMMUTABLE;
  77. inode->i_mode = S_IFREG | S_IRUGO;
  78. inode->i_fop = &ns_file_operations;
  79. inode->i_private = ns;
  80. dentry = d_alloc_pseudo(mnt->mnt_sb, &qname);
  81. if (!dentry) {
  82. iput(inode);
  83. mntput(mnt);
  84. return ERR_PTR(-ENOMEM);
  85. }
  86. d_instantiate(dentry, inode);
  87. dentry->d_fsdata = (void *)ns_ops;
  88. d = atomic_long_cmpxchg(&ns->stashed, 0, (unsigned long)dentry);
  89. if (d) {
  90. d_delete(dentry); /* make sure ->d_prune() does nothing */
  91. dput(dentry);
  92. cpu_relax();
  93. goto again;
  94. }
  95. goto got_it;
  96. }
  97. int ns_get_name(char *buf, size_t size, struct task_struct *task,
  98. const struct proc_ns_operations *ns_ops)
  99. {
  100. struct ns_common *ns;
  101. int res = -ENOENT;
  102. ns = ns_ops->get(task);
  103. if (ns) {
  104. res = snprintf(buf, size, "%s:[%u]", ns_ops->name, ns->inum);
  105. ns_ops->put(ns);
  106. }
  107. return res;
  108. }
  109. struct file *proc_ns_fget(int fd)
  110. {
  111. struct file *file;
  112. file = fget(fd);
  113. if (!file)
  114. return ERR_PTR(-EBADF);
  115. if (file->f_op != &ns_file_operations)
  116. goto out_invalid;
  117. return file;
  118. out_invalid:
  119. fput(file);
  120. return ERR_PTR(-EINVAL);
  121. }
  122. static const struct super_operations nsfs_ops = {
  123. .statfs = simple_statfs,
  124. .evict_inode = nsfs_evict,
  125. };
  126. static struct dentry *nsfs_mount(struct file_system_type *fs_type,
  127. int flags, const char *dev_name, void *data)
  128. {
  129. return mount_pseudo(fs_type, "nsfs:", &nsfs_ops,
  130. &ns_dentry_operations, NSFS_MAGIC);
  131. }
  132. static struct file_system_type nsfs = {
  133. .name = "nsfs",
  134. .mount = nsfs_mount,
  135. .kill_sb = kill_anon_super,
  136. };
  137. void __init nsfs_init(void)
  138. {
  139. nsfs_mnt = kern_mount(&nsfs);
  140. if (IS_ERR(nsfs_mnt))
  141. panic("can't set nsfs up\n");
  142. nsfs_mnt->mnt_sb->s_flags &= ~MS_NOUSER;
  143. }