namei.c 12 KB

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