namei.c 12 KB

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