namei.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  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 inode *dir,
  16. struct dentry *dentry,
  17. umode_t mode,
  18. bool exclusive)
  19. {
  20. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  21. struct orangefs_kernel_op_s *new_op;
  22. struct orangefs_object_kref ref;
  23. struct inode *inode;
  24. struct iattr iattr;
  25. int ret;
  26. gossip_debug(GOSSIP_NAME_DEBUG, "%s: %pd\n",
  27. __func__,
  28. dentry);
  29. new_op = op_alloc(ORANGEFS_VFS_OP_CREATE);
  30. if (!new_op)
  31. return -ENOMEM;
  32. new_op->upcall.req.create.parent_refn = parent->refn;
  33. fill_default_sys_attrs(new_op->upcall.req.create.attributes,
  34. ORANGEFS_TYPE_METAFILE, mode);
  35. strncpy(new_op->upcall.req.create.d_name,
  36. dentry->d_name.name, ORANGEFS_NAME_MAX - 1);
  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. strncpy(new_op->upcall.req.lookup.d_name, dentry->d_name.name,
  116. ORANGEFS_NAME_MAX - 1);
  117. gossip_debug(GOSSIP_NAME_DEBUG,
  118. "%s: doing lookup on %s under %pU,%d\n",
  119. __func__,
  120. new_op->upcall.req.lookup.d_name,
  121. &new_op->upcall.req.lookup.parent_refn.khandle,
  122. new_op->upcall.req.lookup.parent_refn.fs_id);
  123. ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
  124. gossip_debug(GOSSIP_NAME_DEBUG,
  125. "Lookup Got %pU, fsid %d (ret=%d)\n",
  126. &new_op->downcall.resp.lookup.refn.khandle,
  127. new_op->downcall.resp.lookup.refn.fs_id,
  128. ret);
  129. if (ret == 0) {
  130. orangefs_set_timeout(dentry);
  131. inode = orangefs_iget(dir->i_sb, &new_op->downcall.resp.lookup.refn);
  132. } else if (ret == -ENOENT) {
  133. inode = NULL;
  134. } else {
  135. /* must be a non-recoverable error */
  136. inode = ERR_PTR(ret);
  137. }
  138. op_release(new_op);
  139. return d_splice_alias(inode, dentry);
  140. }
  141. /* return 0 on success; non-zero otherwise */
  142. static int orangefs_unlink(struct inode *dir, struct dentry *dentry)
  143. {
  144. struct inode *inode = dentry->d_inode;
  145. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  146. struct orangefs_kernel_op_s *new_op;
  147. struct iattr iattr;
  148. int ret;
  149. gossip_debug(GOSSIP_NAME_DEBUG,
  150. "%s: called on %pd\n"
  151. " (inode %pU): Parent is %pU | fs_id %d\n",
  152. __func__,
  153. dentry,
  154. get_khandle_from_ino(inode),
  155. &parent->refn.khandle,
  156. parent->refn.fs_id);
  157. new_op = op_alloc(ORANGEFS_VFS_OP_REMOVE);
  158. if (!new_op)
  159. return -ENOMEM;
  160. new_op->upcall.req.remove.parent_refn = parent->refn;
  161. strncpy(new_op->upcall.req.remove.d_name, dentry->d_name.name,
  162. ORANGEFS_NAME_MAX - 1);
  163. ret = service_operation(new_op, "orangefs_unlink",
  164. get_interruptible_flag(inode));
  165. gossip_debug(GOSSIP_NAME_DEBUG,
  166. "%s: service_operation returned:%d:\n",
  167. __func__,
  168. ret);
  169. op_release(new_op);
  170. if (!ret) {
  171. drop_nlink(inode);
  172. memset(&iattr, 0, sizeof iattr);
  173. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  174. iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
  175. __orangefs_setattr(dir, &iattr);
  176. }
  177. return ret;
  178. }
  179. static int orangefs_symlink(struct inode *dir,
  180. struct dentry *dentry,
  181. const char *symname)
  182. {
  183. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  184. struct orangefs_kernel_op_s *new_op;
  185. struct orangefs_object_kref ref;
  186. struct inode *inode;
  187. struct iattr iattr;
  188. int mode = 0755;
  189. int ret;
  190. gossip_debug(GOSSIP_NAME_DEBUG, "%s: called\n", __func__);
  191. if (!symname)
  192. return -EINVAL;
  193. if (strlen(symname)+1 > ORANGEFS_NAME_MAX)
  194. return -ENAMETOOLONG;
  195. new_op = op_alloc(ORANGEFS_VFS_OP_SYMLINK);
  196. if (!new_op)
  197. return -ENOMEM;
  198. new_op->upcall.req.sym.parent_refn = parent->refn;
  199. fill_default_sys_attrs(new_op->upcall.req.sym.attributes,
  200. ORANGEFS_TYPE_SYMLINK,
  201. mode);
  202. strncpy(new_op->upcall.req.sym.entry_name,
  203. dentry->d_name.name,
  204. ORANGEFS_NAME_MAX - 1);
  205. strncpy(new_op->upcall.req.sym.target, symname, ORANGEFS_NAME_MAX - 1);
  206. ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
  207. gossip_debug(GOSSIP_NAME_DEBUG,
  208. "Symlink Got ORANGEFS handle %pU on fsid %d (ret=%d)\n",
  209. &new_op->downcall.resp.sym.refn.khandle,
  210. new_op->downcall.resp.sym.refn.fs_id, ret);
  211. if (ret < 0) {
  212. gossip_debug(GOSSIP_NAME_DEBUG,
  213. "%s: failed with error code %d\n",
  214. __func__, ret);
  215. goto out;
  216. }
  217. ref = new_op->downcall.resp.sym.refn;
  218. inode = orangefs_new_inode(dir->i_sb, dir, S_IFLNK | mode, 0, &ref);
  219. if (IS_ERR(inode)) {
  220. gossip_err
  221. ("*** Failed to allocate orangefs symlink inode\n");
  222. ret = PTR_ERR(inode);
  223. goto out;
  224. }
  225. /*
  226. * This is necessary because orangefs_inode_getattr will not
  227. * re-read symlink size as it is impossible for it to change.
  228. * Invalidating the cache does not help. orangefs_new_inode
  229. * does not set the correct size (it does not know symname).
  230. */
  231. inode->i_size = strlen(symname);
  232. gossip_debug(GOSSIP_NAME_DEBUG,
  233. "Assigned symlink inode new number of %pU\n",
  234. get_khandle_from_ino(inode));
  235. d_instantiate_new(dentry, inode);
  236. orangefs_set_timeout(dentry);
  237. gossip_debug(GOSSIP_NAME_DEBUG,
  238. "Inode (Symlink) %pU -> %pd\n",
  239. get_khandle_from_ino(inode),
  240. dentry);
  241. memset(&iattr, 0, sizeof iattr);
  242. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  243. iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
  244. __orangefs_setattr(dir, &iattr);
  245. ret = 0;
  246. out:
  247. op_release(new_op);
  248. return ret;
  249. }
  250. static int orangefs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
  251. {
  252. struct orangefs_inode_s *parent = ORANGEFS_I(dir);
  253. struct orangefs_kernel_op_s *new_op;
  254. struct orangefs_object_kref ref;
  255. struct inode *inode;
  256. struct iattr iattr;
  257. int ret;
  258. new_op = op_alloc(ORANGEFS_VFS_OP_MKDIR);
  259. if (!new_op)
  260. return -ENOMEM;
  261. new_op->upcall.req.mkdir.parent_refn = parent->refn;
  262. fill_default_sys_attrs(new_op->upcall.req.mkdir.attributes,
  263. ORANGEFS_TYPE_DIRECTORY, mode);
  264. strncpy(new_op->upcall.req.mkdir.d_name,
  265. dentry->d_name.name, ORANGEFS_NAME_MAX - 1);
  266. ret = service_operation(new_op, __func__, get_interruptible_flag(dir));
  267. gossip_debug(GOSSIP_NAME_DEBUG,
  268. "Mkdir Got ORANGEFS handle %pU on fsid %d\n",
  269. &new_op->downcall.resp.mkdir.refn.khandle,
  270. new_op->downcall.resp.mkdir.refn.fs_id);
  271. if (ret < 0) {
  272. gossip_debug(GOSSIP_NAME_DEBUG,
  273. "%s: failed with error code %d\n",
  274. __func__, ret);
  275. goto out;
  276. }
  277. ref = new_op->downcall.resp.mkdir.refn;
  278. inode = orangefs_new_inode(dir->i_sb, dir, S_IFDIR | mode, 0, &ref);
  279. if (IS_ERR(inode)) {
  280. gossip_err("*** Failed to allocate orangefs dir inode\n");
  281. ret = PTR_ERR(inode);
  282. goto out;
  283. }
  284. gossip_debug(GOSSIP_NAME_DEBUG,
  285. "Assigned dir inode new number of %pU\n",
  286. get_khandle_from_ino(inode));
  287. d_instantiate_new(dentry, inode);
  288. orangefs_set_timeout(dentry);
  289. gossip_debug(GOSSIP_NAME_DEBUG,
  290. "Inode (Directory) %pU -> %pd\n",
  291. get_khandle_from_ino(inode),
  292. dentry);
  293. /*
  294. * NOTE: we have no good way to keep nlink consistent for directories
  295. * across clients; keep constant at 1.
  296. */
  297. memset(&iattr, 0, sizeof iattr);
  298. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  299. iattr.ia_mtime = iattr.ia_ctime = current_time(dir);
  300. __orangefs_setattr(dir, &iattr);
  301. out:
  302. op_release(new_op);
  303. return ret;
  304. }
  305. static int orangefs_rename(struct inode *old_dir,
  306. struct dentry *old_dentry,
  307. struct inode *new_dir,
  308. struct dentry *new_dentry,
  309. unsigned int flags)
  310. {
  311. struct orangefs_kernel_op_s *new_op;
  312. struct iattr iattr;
  313. int ret;
  314. if (flags)
  315. return -EINVAL;
  316. gossip_debug(GOSSIP_NAME_DEBUG,
  317. "orangefs_rename: called (%pd2 => %pd2) ct=%d\n",
  318. old_dentry, new_dentry, d_count(new_dentry));
  319. memset(&iattr, 0, sizeof iattr);
  320. iattr.ia_valid |= ATTR_MTIME | ATTR_CTIME;
  321. iattr.ia_mtime = iattr.ia_ctime = current_time(new_dir);
  322. __orangefs_setattr(new_dir, &iattr);
  323. new_op = op_alloc(ORANGEFS_VFS_OP_RENAME);
  324. if (!new_op)
  325. return -EINVAL;
  326. new_op->upcall.req.rename.old_parent_refn = ORANGEFS_I(old_dir)->refn;
  327. new_op->upcall.req.rename.new_parent_refn = ORANGEFS_I(new_dir)->refn;
  328. strncpy(new_op->upcall.req.rename.d_old_name,
  329. old_dentry->d_name.name,
  330. ORANGEFS_NAME_MAX - 1);
  331. strncpy(new_op->upcall.req.rename.d_new_name,
  332. new_dentry->d_name.name,
  333. ORANGEFS_NAME_MAX - 1);
  334. ret = service_operation(new_op,
  335. "orangefs_rename",
  336. get_interruptible_flag(old_dentry->d_inode));
  337. gossip_debug(GOSSIP_NAME_DEBUG,
  338. "orangefs_rename: got downcall status %d\n",
  339. ret);
  340. if (new_dentry->d_inode)
  341. new_dentry->d_inode->i_ctime = current_time(new_dentry->d_inode);
  342. op_release(new_op);
  343. return ret;
  344. }
  345. /* ORANGEFS implementation of VFS inode operations for directories */
  346. const struct inode_operations orangefs_dir_inode_operations = {
  347. .lookup = orangefs_lookup,
  348. .get_acl = orangefs_get_acl,
  349. .set_acl = orangefs_set_acl,
  350. .create = orangefs_create,
  351. .unlink = orangefs_unlink,
  352. .symlink = orangefs_symlink,
  353. .mkdir = orangefs_mkdir,
  354. .rmdir = orangefs_unlink,
  355. .rename = orangefs_rename,
  356. .setattr = orangefs_setattr,
  357. .getattr = orangefs_getattr,
  358. .listxattr = orangefs_listxattr,
  359. .permission = orangefs_permission,
  360. .update_time = orangefs_update_time,
  361. };