dynroot.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* AFS dynamic root handling
  3. *
  4. * Copyright (C) 2018 Red Hat, Inc. All Rights Reserved.
  5. * Written by David Howells (dhowells@redhat.com)
  6. */
  7. #include <linux/fs.h>
  8. #include <linux/namei.h>
  9. #include <linux/dns_resolver.h>
  10. #include "internal.h"
  11. static atomic_t afs_autocell_ino;
  12. /*
  13. * iget5() comparator for inode created by autocell operations
  14. *
  15. * These pseudo inodes don't match anything.
  16. */
  17. static int afs_iget5_pseudo_test(struct inode *inode, void *opaque)
  18. {
  19. return 0;
  20. }
  21. /*
  22. * iget5() inode initialiser
  23. */
  24. static int afs_iget5_pseudo_set(struct inode *inode, void *opaque)
  25. {
  26. struct afs_super_info *as = AFS_FS_S(inode->i_sb);
  27. struct afs_vnode *vnode = AFS_FS_I(inode);
  28. struct afs_fid *fid = opaque;
  29. vnode->volume = as->volume;
  30. vnode->fid = *fid;
  31. inode->i_ino = fid->vnode;
  32. inode->i_generation = fid->unique;
  33. return 0;
  34. }
  35. /*
  36. * Create an inode for a dynamic root directory or an autocell dynamic
  37. * automount dir.
  38. */
  39. struct inode *afs_iget_pseudo_dir(struct super_block *sb, bool root)
  40. {
  41. struct afs_super_info *as = AFS_FS_S(sb);
  42. struct afs_vnode *vnode;
  43. struct inode *inode;
  44. struct afs_fid fid = {};
  45. _enter("");
  46. if (as->volume)
  47. fid.vid = as->volume->vid;
  48. if (root) {
  49. fid.vnode = 1;
  50. fid.unique = 1;
  51. } else {
  52. fid.vnode = atomic_inc_return(&afs_autocell_ino);
  53. fid.unique = 0;
  54. }
  55. inode = iget5_locked(sb, fid.vnode,
  56. afs_iget5_pseudo_test, afs_iget5_pseudo_set, &fid);
  57. if (!inode) {
  58. _leave(" = -ENOMEM");
  59. return ERR_PTR(-ENOMEM);
  60. }
  61. _debug("GOT INODE %p { ino=%lu, vl=%llx, vn=%llx, u=%x }",
  62. inode, inode->i_ino, fid.vid, fid.vnode, fid.unique);
  63. vnode = AFS_FS_I(inode);
  64. /* there shouldn't be an existing inode */
  65. BUG_ON(!(inode->i_state & I_NEW));
  66. netfs_inode_init(&vnode->netfs, NULL, false);
  67. inode->i_size = 0;
  68. inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
  69. if (root) {
  70. inode->i_op = &afs_dynroot_inode_operations;
  71. inode->i_fop = &simple_dir_operations;
  72. } else {
  73. inode->i_op = &afs_autocell_inode_operations;
  74. }
  75. set_nlink(inode, 2);
  76. inode->i_uid = GLOBAL_ROOT_UID;
  77. inode->i_gid = GLOBAL_ROOT_GID;
  78. simple_inode_init_ts(inode);
  79. inode->i_blocks = 0;
  80. inode->i_generation = 0;
  81. set_bit(AFS_VNODE_PSEUDODIR, &vnode->flags);
  82. if (!root) {
  83. set_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags);
  84. inode->i_flags |= S_AUTOMOUNT;
  85. }
  86. inode->i_flags |= S_NOATIME;
  87. unlock_new_inode(inode);
  88. _leave(" = %p", inode);
  89. return inode;
  90. }
  91. /*
  92. * Probe to see if a cell may exist. This prevents positive dentries from
  93. * being created unnecessarily.
  94. */
  95. static int afs_probe_cell_name(struct dentry *dentry)
  96. {
  97. struct afs_cell *cell;
  98. struct afs_net *net = afs_d2net(dentry);
  99. const char *name = dentry->d_name.name;
  100. size_t len = dentry->d_name.len;
  101. char *result = NULL;
  102. int ret;
  103. /* Names prefixed with a dot are R/W mounts. */
  104. if (name[0] == '.') {
  105. if (len == 1)
  106. return -EINVAL;
  107. name++;
  108. len--;
  109. }
  110. cell = afs_find_cell(net, name, len, afs_cell_trace_use_probe);
  111. if (!IS_ERR(cell)) {
  112. afs_unuse_cell(net, cell, afs_cell_trace_unuse_probe);
  113. return 0;
  114. }
  115. ret = dns_query(net->net, "afsdb", name, len, "srv=1",
  116. &result, NULL, false);
  117. if (ret == -ENODATA || ret == -ENOKEY || ret == 0)
  118. ret = -ENOENT;
  119. if (ret > 0 && ret >= sizeof(struct dns_server_list_v1_header)) {
  120. struct dns_server_list_v1_header *v1 = (void *)result;
  121. if (v1->hdr.zero == 0 &&
  122. v1->hdr.content == DNS_PAYLOAD_IS_SERVER_LIST &&
  123. v1->hdr.version == 1 &&
  124. (v1->status != DNS_LOOKUP_GOOD &&
  125. v1->status != DNS_LOOKUP_GOOD_WITH_BAD))
  126. return -ENOENT;
  127. }
  128. kfree(result);
  129. return ret;
  130. }
  131. /*
  132. * Try to auto mount the mountpoint with pseudo directory, if the autocell
  133. * operation is setted.
  134. */
  135. struct inode *afs_try_auto_mntpt(struct dentry *dentry, struct inode *dir)
  136. {
  137. struct afs_vnode *vnode = AFS_FS_I(dir);
  138. struct inode *inode;
  139. int ret = -ENOENT;
  140. _enter("%p{%pd}, {%llx:%llu}",
  141. dentry, dentry, vnode->fid.vid, vnode->fid.vnode);
  142. if (!test_bit(AFS_VNODE_AUTOCELL, &vnode->flags))
  143. goto out;
  144. ret = afs_probe_cell_name(dentry);
  145. if (ret < 0)
  146. goto out;
  147. inode = afs_iget_pseudo_dir(dir->i_sb, false);
  148. if (IS_ERR(inode)) {
  149. ret = PTR_ERR(inode);
  150. goto out;
  151. }
  152. _leave("= %p", inode);
  153. return inode;
  154. out:
  155. _leave("= %d", ret);
  156. return ret == -ENOENT ? NULL : ERR_PTR(ret);
  157. }
  158. /*
  159. * Look up @cell in a dynroot directory. This is a substitution for the
  160. * local cell name for the net namespace.
  161. */
  162. static struct dentry *afs_lookup_atcell(struct dentry *dentry)
  163. {
  164. struct afs_cell *cell;
  165. struct afs_net *net = afs_d2net(dentry);
  166. struct dentry *ret;
  167. char *name;
  168. int len;
  169. if (!net->ws_cell)
  170. return ERR_PTR(-ENOENT);
  171. ret = ERR_PTR(-ENOMEM);
  172. name = kmalloc(AFS_MAXCELLNAME + 1, GFP_KERNEL);
  173. if (!name)
  174. goto out_p;
  175. down_read(&net->cells_lock);
  176. cell = net->ws_cell;
  177. if (cell) {
  178. len = cell->name_len;
  179. memcpy(name, cell->name, len + 1);
  180. }
  181. up_read(&net->cells_lock);
  182. ret = ERR_PTR(-ENOENT);
  183. if (!cell)
  184. goto out_n;
  185. ret = lookup_one_len(name, dentry->d_parent, len);
  186. /* We don't want to d_add() the @cell dentry here as we don't want to
  187. * the cached dentry to hide changes to the local cell name.
  188. */
  189. out_n:
  190. kfree(name);
  191. out_p:
  192. return ret;
  193. }
  194. /*
  195. * Look up an entry in a dynroot directory.
  196. */
  197. static struct dentry *afs_dynroot_lookup(struct inode *dir, struct dentry *dentry,
  198. unsigned int flags)
  199. {
  200. _enter("%pd", dentry);
  201. ASSERTCMP(d_inode(dentry), ==, NULL);
  202. if (flags & LOOKUP_CREATE)
  203. return ERR_PTR(-EOPNOTSUPP);
  204. if (dentry->d_name.len >= AFSNAMEMAX) {
  205. _leave(" = -ENAMETOOLONG");
  206. return ERR_PTR(-ENAMETOOLONG);
  207. }
  208. if (dentry->d_name.len == 5 &&
  209. memcmp(dentry->d_name.name, "@cell", 5) == 0)
  210. return afs_lookup_atcell(dentry);
  211. return d_splice_alias(afs_try_auto_mntpt(dentry, dir), dentry);
  212. }
  213. const struct inode_operations afs_dynroot_inode_operations = {
  214. .lookup = afs_dynroot_lookup,
  215. };
  216. const struct dentry_operations afs_dynroot_dentry_operations = {
  217. .d_delete = always_delete_dentry,
  218. .d_release = afs_d_release,
  219. .d_automount = afs_d_automount,
  220. };
  221. /*
  222. * Create a manually added cell mount directory.
  223. * - The caller must hold net->proc_cells_lock
  224. */
  225. int afs_dynroot_mkdir(struct afs_net *net, struct afs_cell *cell)
  226. {
  227. struct super_block *sb = net->dynroot_sb;
  228. struct dentry *root, *subdir;
  229. int ret;
  230. if (!sb || atomic_read(&sb->s_active) == 0)
  231. return 0;
  232. /* Let the ->lookup op do the creation */
  233. root = sb->s_root;
  234. inode_lock(root->d_inode);
  235. subdir = lookup_one_len(cell->name, root, cell->name_len);
  236. if (IS_ERR(subdir)) {
  237. ret = PTR_ERR(subdir);
  238. goto unlock;
  239. }
  240. /* Note that we're retaining an extra ref on the dentry */
  241. subdir->d_fsdata = (void *)1UL;
  242. ret = 0;
  243. unlock:
  244. inode_unlock(root->d_inode);
  245. return ret;
  246. }
  247. /*
  248. * Remove a manually added cell mount directory.
  249. * - The caller must hold net->proc_cells_lock
  250. */
  251. void afs_dynroot_rmdir(struct afs_net *net, struct afs_cell *cell)
  252. {
  253. struct super_block *sb = net->dynroot_sb;
  254. struct dentry *root, *subdir;
  255. if (!sb || atomic_read(&sb->s_active) == 0)
  256. return;
  257. root = sb->s_root;
  258. inode_lock(root->d_inode);
  259. /* Don't want to trigger a lookup call, which will re-add the cell */
  260. subdir = try_lookup_one_len(cell->name, root, cell->name_len);
  261. if (IS_ERR_OR_NULL(subdir)) {
  262. _debug("lookup %ld", PTR_ERR(subdir));
  263. goto no_dentry;
  264. }
  265. _debug("rmdir %pd %u", subdir, d_count(subdir));
  266. if (subdir->d_fsdata) {
  267. _debug("unpin %u", d_count(subdir));
  268. subdir->d_fsdata = NULL;
  269. dput(subdir);
  270. }
  271. dput(subdir);
  272. no_dentry:
  273. inode_unlock(root->d_inode);
  274. _leave("");
  275. }
  276. /*
  277. * Populate a newly created dynamic root with cell names.
  278. */
  279. int afs_dynroot_populate(struct super_block *sb)
  280. {
  281. struct afs_cell *cell;
  282. struct afs_net *net = afs_sb2net(sb);
  283. int ret;
  284. mutex_lock(&net->proc_cells_lock);
  285. net->dynroot_sb = sb;
  286. hlist_for_each_entry(cell, &net->proc_cells, proc_link) {
  287. ret = afs_dynroot_mkdir(net, cell);
  288. if (ret < 0)
  289. goto error;
  290. }
  291. ret = 0;
  292. out:
  293. mutex_unlock(&net->proc_cells_lock);
  294. return ret;
  295. error:
  296. net->dynroot_sb = NULL;
  297. goto out;
  298. }
  299. /*
  300. * When a dynamic root that's in the process of being destroyed, depopulate it
  301. * of pinned directories.
  302. */
  303. void afs_dynroot_depopulate(struct super_block *sb)
  304. {
  305. struct afs_net *net = afs_sb2net(sb);
  306. struct dentry *root = sb->s_root, *subdir;
  307. /* Prevent more subdirs from being created */
  308. mutex_lock(&net->proc_cells_lock);
  309. if (net->dynroot_sb == sb)
  310. net->dynroot_sb = NULL;
  311. mutex_unlock(&net->proc_cells_lock);
  312. if (root) {
  313. struct hlist_node *n;
  314. inode_lock(root->d_inode);
  315. /* Remove all the pins for dirs created for manually added cells */
  316. hlist_for_each_entry_safe(subdir, n, &root->d_children, d_sib) {
  317. if (subdir->d_fsdata) {
  318. subdir->d_fsdata = NULL;
  319. dput(subdir);
  320. }
  321. }
  322. inode_unlock(root->d_inode);
  323. }
  324. }