nsfs.c 3.8 KB

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