dynroot.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /* AFS dynamic root handling
  2. *
  3. * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public Licence
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the Licence, or (at your option) any later version.
  10. */
  11. #include <linux/fs.h>
  12. #include <linux/namei.h>
  13. #include <linux/dns_resolver.h>
  14. #include "internal.h"
  15. const struct file_operations afs_dynroot_file_operations = {
  16. .open = dcache_dir_open,
  17. .release = dcache_dir_close,
  18. .iterate_shared = dcache_readdir,
  19. .llseek = dcache_dir_lseek,
  20. };
  21. /*
  22. * Probe to see if a cell may exist. This prevents positive dentries from
  23. * being created unnecessarily.
  24. */
  25. static int afs_probe_cell_name(struct dentry *dentry)
  26. {
  27. struct afs_cell *cell;
  28. const char *name = dentry->d_name.name;
  29. size_t len = dentry->d_name.len;
  30. int ret;
  31. /* Names prefixed with a dot are R/W mounts. */
  32. if (name[0] == '.') {
  33. if (len == 1)
  34. return -EINVAL;
  35. name++;
  36. len--;
  37. }
  38. cell = afs_lookup_cell_rcu(afs_d2net(dentry), name, len);
  39. if (!IS_ERR(cell)) {
  40. afs_put_cell(afs_d2net(dentry), cell);
  41. return 0;
  42. }
  43. ret = dns_query("afsdb", name, len, "", NULL, NULL);
  44. if (ret == -ENODATA)
  45. ret = -EDESTADDRREQ;
  46. return ret;
  47. }
  48. /*
  49. * Try to auto mount the mountpoint with pseudo directory, if the autocell
  50. * operation is setted.
  51. */
  52. struct inode *afs_try_auto_mntpt(struct dentry *dentry, struct inode *dir)
  53. {
  54. struct afs_vnode *vnode = AFS_FS_I(dir);
  55. struct inode *inode;
  56. int ret = -ENOENT;
  57. _enter("%p{%pd}, {%x:%u}",
  58. dentry, dentry, vnode->fid.vid, vnode->fid.vnode);
  59. if (!test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
  60. goto out;
  61. ret = afs_probe_cell_name(dentry);
  62. if (ret < 0)
  63. goto out;
  64. inode = afs_iget_pseudo_dir(dir->i_sb, false);
  65. if (IS_ERR(inode)) {
  66. ret = PTR_ERR(inode);
  67. goto out;
  68. }
  69. _leave("= %p", inode);
  70. return inode;
  71. out:
  72. _leave("= %d", ret);
  73. return ret == -ENOENT ? NULL : ERR_PTR(ret);
  74. }
  75. /*
  76. * Look up @cell in a dynroot directory. This is a substitution for the
  77. * local cell name for the net namespace.
  78. */
  79. static struct dentry *afs_lookup_atcell(struct dentry *dentry)
  80. {
  81. struct afs_cell *cell;
  82. struct afs_net *net = afs_d2net(dentry);
  83. struct dentry *ret;
  84. unsigned int seq = 0;
  85. char *name;
  86. int len;
  87. if (!net->ws_cell)
  88. return ERR_PTR(-ENOENT);
  89. ret = ERR_PTR(-ENOMEM);
  90. name = kmalloc(AFS_MAXCELLNAME + 1, GFP_KERNEL);
  91. if (!name)
  92. goto out_p;
  93. rcu_read_lock();
  94. do {
  95. read_seqbegin_or_lock(&net->cells_lock, &seq);
  96. cell = rcu_dereference_raw(net->ws_cell);
  97. if (cell) {
  98. len = cell->name_len;
  99. memcpy(name, cell->name, len + 1);
  100. }
  101. } while (need_seqretry(&net->cells_lock, seq));
  102. done_seqretry(&net->cells_lock, seq);
  103. rcu_read_unlock();
  104. ret = ERR_PTR(-ENOENT);
  105. if (!cell)
  106. goto out_n;
  107. ret = lookup_one_len(name, dentry->d_parent, len);
  108. /* We don't want to d_add() the @cell dentry here as we don't want to
  109. * the cached dentry to hide changes to the local cell name.
  110. */
  111. out_n:
  112. kfree(name);
  113. out_p:
  114. return ret;
  115. }
  116. /*
  117. * Look up an entry in a dynroot directory.
  118. */
  119. static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry,
  120. unsigned int flags)
  121. {
  122. _enter("%pd", dentry);
  123. ASSERTCMP(d_inode(dentry), ==, NULL);
  124. if (dentry->d_name.len >= AFSNAMEMAX) {
  125. _leave(" = -ENAMETOOLONG");
  126. return ERR_PTR(-ENAMETOOLONG);
  127. }
  128. if (dentry->d_name.len == 5 &&
  129. memcmp(dentry->d_name.name, "@cell", 5) == 0)
  130. return afs_lookup_atcell(dentry);
  131. return d_splice_alias(afs_try_auto_mntpt(dentry, dir), dentry);
  132. }
  133. const struct inode_operations afs_dynroot_inode_operations = {
  134. .lookup = afs_dynroot_lookup,
  135. };
  136. /*
  137. * Dirs in the dynamic root don't need revalidation.
  138. */
  139. static int afs_dynroot_d_revalidate(struct dentry *dentry, unsigned int flags)
  140. {
  141. return 1;
  142. }
  143. /*
  144. * Allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
  145. * sleep)
  146. * - called from dput() when d_count is going to 0.
  147. * - return 1 to request dentry be unhashed, 0 otherwise
  148. */
  149. static int afs_dynroot_d_delete(const struct dentry *dentry)
  150. {
  151. return d_really_is_positive(dentry);
  152. }
  153. const struct dentry_operations afs_dynroot_dentry_operations = {
  154. .d_revalidate = afs_dynroot_d_revalidate,
  155. .d_delete = afs_dynroot_d_delete,
  156. .d_release = afs_d_release,
  157. .d_automount = afs_d_automount,
  158. };
  159. /*
  160. * Create a manually added cell mount directory.
  161. * - The caller must hold net->proc_cells_lock
  162. */
  163. int afs_dynroot_mkdir(struct afs_net *net, struct afs_cell *cell)
  164. {
  165. struct super_block *sb = net->dynroot_sb;
  166. struct dentry *root, *subdir;
  167. int ret;
  168. if (!sb || atomic_read(&sb->s_active) == 0)
  169. return 0;
  170. /* Let the ->lookup op do the creation */
  171. root = sb->s_root;
  172. inode_lock(root->d_inode);
  173. subdir = lookup_one_len(cell->name, root, cell->name_len);
  174. if (IS_ERR(subdir)) {
  175. ret = PTR_ERR(subdir);
  176. goto unlock;
  177. }
  178. /* Note that we're retaining an extra ref on the dentry */
  179. subdir->d_fsdata = (void *)1UL;
  180. ret = 0;
  181. unlock:
  182. inode_unlock(root->d_inode);
  183. return ret;
  184. }
  185. /*
  186. * Remove a manually added cell mount directory.
  187. * - The caller must hold net->proc_cells_lock
  188. */
  189. void afs_dynroot_rmdir(struct afs_net *net, struct afs_cell *cell)
  190. {
  191. struct super_block *sb = net->dynroot_sb;
  192. struct dentry *root, *subdir;
  193. if (!sb || atomic_read(&sb->s_active) == 0)
  194. return;
  195. root = sb->s_root;
  196. inode_lock(root->d_inode);
  197. /* Don't want to trigger a lookup call, which will re-add the cell */
  198. subdir = try_lookup_one_len(cell->name, root, cell->name_len);
  199. if (IS_ERR_OR_NULL(subdir)) {
  200. _debug("lookup %ld", PTR_ERR(subdir));
  201. goto no_dentry;
  202. }
  203. _debug("rmdir %pd %u", subdir, d_count(subdir));
  204. if (subdir->d_fsdata) {
  205. _debug("unpin %u", d_count(subdir));
  206. subdir->d_fsdata = NULL;
  207. dput(subdir);
  208. }
  209. dput(subdir);
  210. no_dentry:
  211. inode_unlock(root->d_inode);
  212. _leave("");
  213. }
  214. /*
  215. * Populate a newly created dynamic root with cell names.
  216. */
  217. int afs_dynroot_populate(struct super_block *sb)
  218. {
  219. struct afs_cell *cell;
  220. struct afs_net *net = afs_sb2net(sb);
  221. int ret;
  222. if (mutex_lock_interruptible(&net->proc_cells_lock) < 0)
  223. return -ERESTARTSYS;
  224. net->dynroot_sb = sb;
  225. hlist_for_each_entry(cell, &net->proc_cells, proc_link) {
  226. ret = afs_dynroot_mkdir(net, cell);
  227. if (ret < 0)
  228. goto error;
  229. }
  230. ret = 0;
  231. out:
  232. mutex_unlock(&net->proc_cells_lock);
  233. return ret;
  234. error:
  235. net->dynroot_sb = NULL;
  236. goto out;
  237. }
  238. /*
  239. * When a dynamic root that's in the process of being destroyed, depopulate it
  240. * of pinned directories.
  241. */
  242. void afs_dynroot_depopulate(struct super_block *sb)
  243. {
  244. struct afs_net *net = afs_sb2net(sb);
  245. struct dentry *root = sb->s_root, *subdir, *tmp;
  246. /* Prevent more subdirs from being created */
  247. mutex_lock(&net->proc_cells_lock);
  248. if (net->dynroot_sb == sb)
  249. net->dynroot_sb = NULL;
  250. mutex_unlock(&net->proc_cells_lock);
  251. inode_lock(root->d_inode);
  252. /* Remove all the pins for dirs created for manually added cells */
  253. list_for_each_entry_safe(subdir, tmp, &root->d_subdirs, d_child) {
  254. if (subdir->d_fsdata) {
  255. subdir->d_fsdata = NULL;
  256. dput(subdir);
  257. }
  258. }
  259. inode_unlock(root->d_inode);
  260. }