namei.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * (C) 2001 Clemson University and The University of Chicago
  4. *
  5. * See COPYING in top-level directory.
  6. */
  7. /*
  8. * Linux VFS namei operations.
  9. */
  10. #include "protocol.h"
  11. #include "orangefs-kernel.h"
  12. /*
  13. * Get a newly allocated inode to go with a negative dentry.
  14. */
  15. static int orangefs_create(struct mnt_idmap *idmap,
  16. struct inode *dir,
  17. struct dentry *dentry,
  18. umode_t mode,
  19. bool exclusive)
  20. {
  21. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  22. struct orangefs_kernel_op_s *new_op;
  23. struct orangefs_object_kref ref;
  24. struct inode *inode;
  25. struct iattr iattr;
  26. int ret;
  27. gossip_debug(GOSSIP_NAME_DEBUG, "%s: %pd\n",
  28. __func__,
  29. dentry);
  30. new_op = op_alloc(ORANGEFS_VFS_OP_CREATE);
  31. if (!new_op)
  32. return -ENOMEM;
  33. new_op->upcall.req.create.parent_refn = parent->refn;
  34. fill_default_sys_attrs(new_op->upcall.req.create.attributes,
  35. ORANGEFS_TYPE_METAFILE, mode);
  36. strscpy(new_op->upcall.req.create.d_name, dentry->d_name.name);
  37. ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
  38. gossip_debug(GOSSIP_NAME_DEBUG,
  39. "%s: %pd: handle:%pU: fsid:%d: new_op:%p: ret:%d:\n",
  40. __func__,
  41. dentry,
  42. &new_op->downcall.resp.create.refn.khandle,
  43. new_op->downcall.resp.create.refn.fs_id,
  44. new_op,
  45. ret);
  46. if (ret < 0)
  47. goto out;
  48. ref = new_op->downcall.resp.create.refn;
  49. inode = orangefs_new_inode(dir->i_sb, dir, S_IFREG | mode, 0, &ref);
  50. if (IS_ERR(inode)) {
  51. gossip_err("%s: Failed to allocate inode for file :%pd:\n",
  52. __func__,
  53. dentry);
  54. ret = PTR_ERR(inode);
  55. goto out;
  56. }
  57. gossip_debug(GOSSIP_NAME_DEBUG,
  58. "%s: Assigned inode :%pU: for file :%pd:\n",
  59. __func__,
  60. get_khandle_from_ino(inode),
  61. dentry);
  62. d_instantiate_new(dentry, inode);
  63. orangefs_set_timeout(dentry);
  64. gossip_debug(GOSSIP_NAME_DEBUG,
  65. "%s: dentry instantiated for %pd\n",
  66. __func__,
  67. dentry);
  68. memset(&iattr, 0, sizeof iattr);
  69. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  70. iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
  71. __orangefs_setattr(dir, &iattr);
  72. ret = 0;
  73. out:
  74. op_release(new_op);
  75. gossip_debug(GOSSIP_NAME_DEBUG,
  76. "%s: %pd: returning %d\n",
  77. __func__,
  78. dentry,
  79. ret);
  80. return ret;
  81. }
  82. /*
  83. * Attempt to resolve an object name (dentry->d_name), parent handle, and
  84. * fsid into a handle for the object.
  85. */
  86. static struct dentry *orangefs_lookup(struct inode *dir, struct dentry *dentry,
  87. unsigned int flags)
  88. {
  89. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  90. struct orangefs_kernel_op_s *new_op;
  91. struct inode *inode;
  92. int ret = -EINVAL;
  93. /*
  94. * in theory we could skip a lookup here (if the intent is to
  95. * create) in order to avoid a potentially failed lookup, but
  96. * leaving it in can skip a valid lookup and try to create a file
  97. * that already exists (e.g. the vfs already handles checking for
  98. * -EEXIST on O_EXCL opens, which is broken if we skip this lookup
  99. * in the create path)
  100. */
  101. gossip_debug(GOSSIP_NAME_DEBUG, "%s called on %pd\n",
  102. __func__, dentry);
  103. if (dentry->d_name.len > (ORANGEFS_NAME_MAX - 1))
  104. return ERR_PTR(-ENAMETOOLONG);
  105. new_op = op_alloc(ORANGEFS_VFS_OP_LOOKUP);
  106. if (!new_op)
  107. return ERR_PTR(-ENOMEM);
  108. new_op->upcall.req.lookup.sym_follow = ORANGEFS_LOOKUP_LINK_NO_FOLLOW;
  109. gossip_debug(GOSSIP_NAME_DEBUG, "%s:%s:%d using parent %pU\n",
  110. __FILE__,
  111. __func__,
  112. __LINE__,
  113. &parent->refn.khandle);
  114. new_op->upcall.req.lookup.parent_refn = parent->refn;
  115. strscpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name);
  116. gossip_debug(GOSSIP_NAME_DEBUG,
  117. "%s: doing lookup on %s under %pU,%d\n",
  118. __func__,
  119. new_op->upcall.req.lookup.d_name,
  120. &new_op->upcall.req.lookup.parent_refn.khandle,
  121. new_op->upcall.req.lookup.parent_refn.fs_id);
  122. ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
  123. gossip_debug(GOSSIP_NAME_DEBUG,
  124. "Lookup Got %pU, fsid %d (ret=%d)\n",
  125. &new_op->downcall.resp.lookup.refn.khandle,
  126. new_op->downcall.resp.lookup.refn.fs_id,
  127. ret);
  128. if (ret == 0) {
  129. orangefs_set_timeout(dentry);
  130. inode = orangefs_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn);
  131. } else if (ret == -ENOENT) {
  132. inode = NULL;
  133. } else {
  134. /* must be a non-recoverable error */
  135. inode = ERR_PTR(ret);
  136. }
  137. op_release(new_op);
  138. return d_splice_alias(inode, dentry);
  139. }
  140. /* return 0 on success; non-zero otherwise */
  141. static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
  142. {
  143. struct inode *inode = dentry->d_inode;
  144. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  145. struct orangefs_kernel_op_s *new_op;
  146. struct iattr iattr;
  147. int ret;
  148. gossip_debug(GOSSIP_NAME_DEBUG,
  149. "%s: called on %pd\n"
  150. " (inode %pU): Parent is %pU | fs_id %d\n",
  151. __func__,
  152. dentry,
  153. get_khandle_from_ino(inode),
  154. &parent->refn.khandle,
  155. parent->refn.fs_id);
  156. new_op = op_alloc(ORANGEFS_VFS_OP_REMOVE);
  157. if (!new_op)
  158. return -ENOMEM;
  159. new_op->upcall.req.remove.parent_refn = parent->refn;
  160. strscpy(new_op->upcall.req.remove.d_name, dentry->d_name.name);
  161. ret = service_operation(new_op, "orangefs_unlink",
  162. get_interruptible_flag(inode));
  163. gossip_debug(GOSSIP_NAME_DEBUG,
  164. "%s: service_operation returned:%d:\n",
  165. __func__,
  166. ret);
  167. op_release(new_op);
  168. if (!ret) {
  169. drop_nlink(inode);
  170. memset(&iattr, 0, sizeof iattr);
  171. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  172. iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
  173. __orangefs_setattr(dir, &iattr);
  174. }
  175. return ret;
  176. }
  177. static int orangefs_symlink(struct mnt_idmap *idmap,
  178. struct inode *dir,
  179. struct dentry *dentry,
  180. const char *symname)
  181. {
  182. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  183. struct orangefs_kernel_op_s *new_op;
  184. struct orangefs_object_kref ref;
  185. struct inode *inode;
  186. struct iattr iattr;
  187. int mode = 0755;
  188. int ret;
  189. gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__);
  190. if (!symname)
  191. return -EINVAL;
  192. if (strlen(symname)+1 > ORANGEFS_NAME_MAX)
  193. return -ENAMETOOLONG;
  194. new_op = op_alloc(ORANGEFS_VFS_OP_SYMLINK);
  195. if (!new_op)
  196. return -ENOMEM;
  197. new_op->upcall.req.sym.parent_refn = parent->refn;
  198. fill_default_sys_attrs(new_op->upcall.req.sym.attributes,
  199. ORANGEFS_TYPE_SYMLINK,
  200. mode);
  201. strscpy(new_op->upcall.req.sym.entry_name, dentry->d_name.name);
  202. strscpy(new_op->upcall.req.sym.target, symname);
  203. ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
  204. gossip_debug(GOSSIP_NAME_DEBUG,
  205. "Symlink Got ORANGEFS handle %pU on fsid %d (ret=%d)\n",
  206. &new_op->downcall.resp.sym.refn.khandle,
  207. new_op->downcall.resp.sym.refn.fs_id, ret);
  208. if (ret < 0) {
  209. gossip_debug(GOSSIP_NAME_DEBUG,
  210. "%s: failed with error code %d\n",
  211. __func__, ret);
  212. goto out;
  213. }
  214. ref = new_op->downcall.resp.sym.refn;
  215. inode = orangefs_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, &ref);
  216. if (IS_ERR(inode)) {
  217. gossip_err
  218. ("*** Failed to allocate orangefs symlink inode\n");
  219. ret = PTR_ERR(inode);
  220. goto out;
  221. }
  222. /*
  223. * This is necessary because orangefs_inode_getattr will not
  224. * re-read symlink size as it is impossible for it to change.
  225. * Invalidating the cache does not help. orangefs_new_inode
  226. * does not set the correct size (it does not know symname).
  227. */
  228. inode->i_size = strlen(symname);
  229. gossip_debug(GOSSIP_NAME_DEBUG,
  230. "Assigned symlink inode new number of %pU\n",
  231. get_khandle_from_ino(inode));
  232. d_instantiate_new(dentry, inode);
  233. orangefs_set_timeout(dentry);
  234. gossip_debug(GOSSIP_NAME_DEBUG,
  235. "Inode (Symlink) %pU -> %pd\n",
  236. get_khandle_from_ino(inode),
  237. dentry);
  238. memset(&iattr, 0, sizeof iattr);
  239. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  240. iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
  241. __orangefs_setattr(dir, &iattr);
  242. ret = 0;
  243. out:
  244. op_release(new_op);
  245. return ret;
  246. }
  247. static int orangefs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
  248. struct dentry *dentry, umode_t mode)
  249. {
  250. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  251. struct orangefs_kernel_op_s *new_op;
  252. struct orangefs_object_kref ref;
  253. struct inode *inode;
  254. struct iattr iattr;
  255. int ret;
  256. new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR);
  257. if (!new_op)
  258. return -ENOMEM;
  259. new_op->upcall.req.mkdir.parent_refn = parent->refn;
  260. fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes,
  261. ORANGEFS_TYPE_DIRECTORY, mode);
  262. strscpy(new_op->upcall.req.mkdir.d_name, dentry->d_name.name);
  263. ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
  264. gossip_debug(GOSSIP_NAME_DEBUG,
  265. "Mkdir Got ORANGEFS handle %pU on fsid %d\n",
  266. &new_op->downcall.resp.mkdir.refn.khandle,
  267. new_op->downcall.resp.mkdir.refn.fs_id);
  268. if (ret < 0) {
  269. gossip_debug(GOSSIP_NAME_DEBUG,
  270. "%s: failed with error code %d\n",
  271. __func__, ret);
  272. goto out;
  273. }
  274. ref = new_op->downcall.resp.mkdir.refn;
  275. inode = orangefs_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, &ref);
  276. if (IS_ERR(inode)) {
  277. gossip_err("*** Failed to allocate orangefs dir inode\n");
  278. ret = PTR_ERR(inode);
  279. goto out;
  280. }
  281. gossip_debug(GOSSIP_NAME_DEBUG,
  282. "Assigned dir inode new number of %pU\n",
  283. get_khandle_from_ino(inode));
  284. d_instantiate_new(dentry, inode);
  285. orangefs_set_timeout(dentry);
  286. gossip_debug(GOSSIP_NAME_DEBUG,
  287. "Inode (Directory) %pU -> %pd\n",
  288. get_khandle_from_ino(inode),
  289. dentry);
  290. /*
  291. * NOTE: we have no good way to keep nlink consistent for directories
  292. * across clients; keep constant at 1.
  293. */
  294. memset(&iattr, 0, sizeof iattr);
  295. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  296. iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
  297. __orangefs_setattr(dir, &iattr);
  298. out:
  299. op_release(new_op);
  300. return ret;
  301. }
  302. static int orangefs_rename(struct mnt_idmap *idmap,
  303. struct inode *old_dir,
  304. struct dentry *old_dentry,
  305. struct inode *new_dir,
  306. struct dentry *new_dentry,
  307. unsigned int flags)
  308. {
  309. struct orangefs_kernel_op_s *new_op;
  310. struct iattr iattr;
  311. int ret;
  312. if (flags)
  313. return -EINVAL;
  314. gossip_debug(GOSSIP_NAME_DEBUG,
  315. "orangefs_rename: called (%pd2 => %pd2) ct=%d\n",
  316. old_dentry, new_dentry, d_count(new_dentry));
  317. memset(&iattr, 0, sizeof iattr);
  318. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  319. iattr.ia_mtime = iattr.ia_ctime = current_time(new_dir);
  320. __orangefs_setattr(new_dir, &iattr);
  321. new_op = op_alloc(ORANGEFS_VFS_OP_RENAME);
  322. if (!new_op)
  323. return -EINVAL;
  324. new_op->upcall.req.rename.old_parent_refn = ORANGEFS_I(old_dir)->refn;
  325. new_op->upcall.req.rename.new_parent_refn = ORANGEFS_I(new_dir)->refn;
  326. strscpy(new_op->upcall.req.rename.d_old_name, old_dentry->d_name.name);
  327. strscpy(new_op->upcall.req.rename.d_new_name, new_dentry->d_name.name);
  328. ret = service_operation(new_op,
  329. "orangefs_rename",
  330. get_interruptible_flag(old_dentry->d_inode));
  331. gossip_debug(GOSSIP_NAME_DEBUG,
  332. "orangefs_rename: got downcall status %d\n",
  333. ret);
  334. if (new_dentry->d_inode)
  335. inode_set_ctime_current(d_inode(new_dentry));
  336. op_release(new_op);
  337. return ret;
  338. }
  339. /* ORANGEFS implementation of VFS inode operations for directories */
  340. const struct inode_operations orangefs_dir_inode_operations = {
  341. .lookup = orangefs_lookup,
  342. .get_inode_acl = orangefs_get_acl,
  343. .set_acl = orangefs_set_acl,
  344. .create = orangefs_create,
  345. .unlink = orangefs_unlink,
  346. .symlink = orangefs_symlink,
  347. .mkdir = orangefs_mkdir,
  348. .rmdir = orangefs_unlink,
  349. .rename = orangefs_rename,
  350. .setattr = orangefs_setattr,
  351. .getattr = orangefs_getattr,
  352. .listxattr = orangefs_listxattr,
  353. .permission = orangefs_permission,
  354. .update_time = orangefs_update_time,
  355. };