orangefs-utils.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. /*
  2. * (C) 2001 Clemson University and The University of Chicago
  3. *
  4. * See COPYING in top-level directory.
  5. */
  6. #include "protocol.h"
  7. #include "orangefs-kernel.h"
  8. #include "orangefs-dev-proto.h"
  9. #include "orangefs-bufmap.h"
  10. __s32 fsid_of_op(struct orangefs_kernel_op_s *op)
  11. {
  12. __s32 fsid = ORANGEFS_FS_ID_NULL;
  13. if (op) {
  14. switch (op->upcall.type) {
  15. case ORANGEFS_VFS_OP_FILE_IO:
  16. fsid = op->upcall.req.io.refn.fs_id;
  17. break;
  18. case ORANGEFS_VFS_OP_LOOKUP:
  19. fsid = op->upcall.req.lookup.parent_refn.fs_id;
  20. break;
  21. case ORANGEFS_VFS_OP_CREATE:
  22. fsid = op->upcall.req.create.parent_refn.fs_id;
  23. break;
  24. case ORANGEFS_VFS_OP_GETATTR:
  25. fsid = op->upcall.req.getattr.refn.fs_id;
  26. break;
  27. case ORANGEFS_VFS_OP_REMOVE:
  28. fsid = op->upcall.req.remove.parent_refn.fs_id;
  29. break;
  30. case ORANGEFS_VFS_OP_MKDIR:
  31. fsid = op->upcall.req.mkdir.parent_refn.fs_id;
  32. break;
  33. case ORANGEFS_VFS_OP_READDIR:
  34. fsid = op->upcall.req.readdir.refn.fs_id;
  35. break;
  36. case ORANGEFS_VFS_OP_SETATTR:
  37. fsid = op->upcall.req.setattr.refn.fs_id;
  38. break;
  39. case ORANGEFS_VFS_OP_SYMLINK:
  40. fsid = op->upcall.req.sym.parent_refn.fs_id;
  41. break;
  42. case ORANGEFS_VFS_OP_RENAME:
  43. fsid = op->upcall.req.rename.old_parent_refn.fs_id;
  44. break;
  45. case ORANGEFS_VFS_OP_STATFS:
  46. fsid = op->upcall.req.statfs.fs_id;
  47. break;
  48. case ORANGEFS_VFS_OP_TRUNCATE:
  49. fsid = op->upcall.req.truncate.refn.fs_id;
  50. break;
  51. case ORANGEFS_VFS_OP_RA_FLUSH:
  52. fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
  53. break;
  54. case ORANGEFS_VFS_OP_FS_UMOUNT:
  55. fsid = op->upcall.req.fs_umount.fs_id;
  56. break;
  57. case ORANGEFS_VFS_OP_GETXATTR:
  58. fsid = op->upcall.req.getxattr.refn.fs_id;
  59. break;
  60. case ORANGEFS_VFS_OP_SETXATTR:
  61. fsid = op->upcall.req.setxattr.refn.fs_id;
  62. break;
  63. case ORANGEFS_VFS_OP_LISTXATTR:
  64. fsid = op->upcall.req.listxattr.refn.fs_id;
  65. break;
  66. case ORANGEFS_VFS_OP_REMOVEXATTR:
  67. fsid = op->upcall.req.removexattr.refn.fs_id;
  68. break;
  69. case ORANGEFS_VFS_OP_FSYNC:
  70. fsid = op->upcall.req.fsync.refn.fs_id;
  71. break;
  72. default:
  73. break;
  74. }
  75. }
  76. return fsid;
  77. }
  78. static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
  79. {
  80. int flags = 0;
  81. if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
  82. flags |= S_IMMUTABLE;
  83. else
  84. flags &= ~S_IMMUTABLE;
  85. if (attrs->flags & ORANGEFS_APPEND_FL)
  86. flags |= S_APPEND;
  87. else
  88. flags &= ~S_APPEND;
  89. if (attrs->flags & ORANGEFS_NOATIME_FL)
  90. flags |= S_NOATIME;
  91. else
  92. flags &= ~S_NOATIME;
  93. return flags;
  94. }
  95. static int orangefs_inode_perms(struct ORANGEFS_sys_attr_s *attrs)
  96. {
  97. int perm_mode = 0;
  98. if (attrs->perms & ORANGEFS_O_EXECUTE)
  99. perm_mode |= S_IXOTH;
  100. if (attrs->perms & ORANGEFS_O_WRITE)
  101. perm_mode |= S_IWOTH;
  102. if (attrs->perms & ORANGEFS_O_READ)
  103. perm_mode |= S_IROTH;
  104. if (attrs->perms & ORANGEFS_G_EXECUTE)
  105. perm_mode |= S_IXGRP;
  106. if (attrs->perms & ORANGEFS_G_WRITE)
  107. perm_mode |= S_IWGRP;
  108. if (attrs->perms & ORANGEFS_G_READ)
  109. perm_mode |= S_IRGRP;
  110. if (attrs->perms & ORANGEFS_U_EXECUTE)
  111. perm_mode |= S_IXUSR;
  112. if (attrs->perms & ORANGEFS_U_WRITE)
  113. perm_mode |= S_IWUSR;
  114. if (attrs->perms & ORANGEFS_U_READ)
  115. perm_mode |= S_IRUSR;
  116. if (attrs->perms & ORANGEFS_G_SGID)
  117. perm_mode |= S_ISGID;
  118. if (attrs->perms & ORANGEFS_U_SUID)
  119. perm_mode |= S_ISUID;
  120. return perm_mode;
  121. }
  122. /*
  123. * NOTE: in kernel land, we never use the sys_attr->link_target for
  124. * anything, so don't bother copying it into the sys_attr object here.
  125. */
  126. static inline int copy_attributes_from_inode(struct inode *inode,
  127. struct ORANGEFS_sys_attr_s *attrs,
  128. struct iattr *iattr)
  129. {
  130. umode_t tmp_mode;
  131. if (!iattr || !inode || !attrs) {
  132. gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
  133. "in copy_attributes_from_inode!\n",
  134. iattr,
  135. inode,
  136. attrs);
  137. return -EINVAL;
  138. }
  139. /*
  140. * We need to be careful to only copy the attributes out of the
  141. * iattr object that we know are valid.
  142. */
  143. attrs->mask = 0;
  144. if (iattr->ia_valid & ATTR_UID) {
  145. attrs->owner = from_kuid(&init_user_ns, iattr->ia_uid);
  146. attrs->mask |= ORANGEFS_ATTR_SYS_UID;
  147. gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
  148. }
  149. if (iattr->ia_valid & ATTR_GID) {
  150. attrs->group = from_kgid(&init_user_ns, iattr->ia_gid);
  151. attrs->mask |= ORANGEFS_ATTR_SYS_GID;
  152. gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
  153. }
  154. if (iattr->ia_valid & ATTR_ATIME) {
  155. attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
  156. if (iattr->ia_valid & ATTR_ATIME_SET) {
  157. attrs->atime = (time64_t)iattr->ia_atime.tv_sec;
  158. attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
  159. }
  160. }
  161. if (iattr->ia_valid & ATTR_MTIME) {
  162. attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
  163. if (iattr->ia_valid & ATTR_MTIME_SET) {
  164. attrs->mtime = (time64_t)iattr->ia_mtime.tv_sec;
  165. attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
  166. }
  167. }
  168. if (iattr->ia_valid & ATTR_CTIME)
  169. attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
  170. /*
  171. * ORANGEFS cannot set size with a setattr operation. Probably not likely
  172. * to be requested through the VFS, but just in case, don't worry about
  173. * ATTR_SIZE
  174. */
  175. if (iattr->ia_valid & ATTR_MODE) {
  176. tmp_mode = iattr->ia_mode;
  177. if (tmp_mode & (S_ISVTX)) {
  178. if (is_root_handle(inode)) {
  179. /*
  180. * allow sticky bit to be set on root (since
  181. * it shows up that way by default anyhow),
  182. * but don't show it to the server
  183. */
  184. tmp_mode -= S_ISVTX;
  185. } else {
  186. gossip_debug(GOSSIP_UTILS_DEBUG,
  187. "User attempted to set sticky bit on non-root directory; returning EINVAL.\n");
  188. return -EINVAL;
  189. }
  190. }
  191. if (tmp_mode & (S_ISUID)) {
  192. gossip_debug(GOSSIP_UTILS_DEBUG,
  193. "Attempting to set setuid bit (not supported); returning EINVAL.\n");
  194. return -EINVAL;
  195. }
  196. attrs->perms = ORANGEFS_util_translate_mode(tmp_mode);
  197. attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
  198. }
  199. return 0;
  200. }
  201. static int orangefs_inode_type(enum orangefs_ds_type objtype)
  202. {
  203. if (objtype == ORANGEFS_TYPE_METAFILE)
  204. return S_IFREG;
  205. else if (objtype == ORANGEFS_TYPE_DIRECTORY)
  206. return S_IFDIR;
  207. else if (objtype == ORANGEFS_TYPE_SYMLINK)
  208. return S_IFLNK;
  209. else
  210. return -1;
  211. }
  212. static int orangefs_inode_is_stale(struct inode *inode, int new,
  213. struct ORANGEFS_sys_attr_s *attrs, char *link_target)
  214. {
  215. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  216. int type = orangefs_inode_type(attrs->objtype);
  217. if (!new) {
  218. /*
  219. * If the inode type or symlink target have changed then this
  220. * inode is stale.
  221. */
  222. if (type == -1 || !(inode->i_mode & type)) {
  223. orangefs_make_bad_inode(inode);
  224. return 1;
  225. }
  226. if (type == S_IFLNK && strncmp(orangefs_inode->link_target,
  227. link_target, ORANGEFS_NAME_MAX)) {
  228. orangefs_make_bad_inode(inode);
  229. return 1;
  230. }
  231. }
  232. return 0;
  233. }
  234. int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
  235. u32 request_mask)
  236. {
  237. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  238. struct orangefs_kernel_op_s *new_op;
  239. loff_t inode_size, rounded_up_size;
  240. int ret, type;
  241. gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
  242. get_khandle_from_ino(inode));
  243. if (!new && !bypass) {
  244. /*
  245. * Must have all the attributes in the mask and be within cache
  246. * time.
  247. */
  248. if ((request_mask & orangefs_inode->getattr_mask) ==
  249. request_mask &&
  250. time_before(jiffies, orangefs_inode->getattr_time))
  251. return 0;
  252. }
  253. new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
  254. if (!new_op)
  255. return -ENOMEM;
  256. new_op->upcall.req.getattr.refn = orangefs_inode->refn;
  257. /*
  258. * Size is the hardest attribute to get. The incremental cost of any
  259. * other attribute is essentially zero.
  260. */
  261. if (request_mask & STATX_SIZE || new)
  262. new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
  263. else
  264. new_op->upcall.req.getattr.mask =
  265. ORANGEFS_ATTR_SYS_ALL_NOHINT & ~ORANGEFS_ATTR_SYS_SIZE;
  266. ret = service_operation(new_op, __func__,
  267. get_interruptible_flag(inode));
  268. if (ret != 0)
  269. goto out;
  270. type = orangefs_inode_type(new_op->
  271. downcall.resp.getattr.attributes.objtype);
  272. ret = orangefs_inode_is_stale(inode, new,
  273. &new_op->downcall.resp.getattr.attributes,
  274. new_op->downcall.resp.getattr.link_target);
  275. if (ret) {
  276. ret = -ESTALE;
  277. goto out;
  278. }
  279. switch (type) {
  280. case S_IFREG:
  281. inode->i_flags = orangefs_inode_flags(&new_op->
  282. downcall.resp.getattr.attributes);
  283. if (request_mask & STATX_SIZE || new) {
  284. inode_size = (loff_t)new_op->
  285. downcall.resp.getattr.attributes.size;
  286. rounded_up_size =
  287. (inode_size + (4096 - (inode_size % 4096)));
  288. inode->i_size = inode_size;
  289. orangefs_inode->blksize =
  290. new_op->downcall.resp.getattr.attributes.blksize;
  291. spin_lock(&inode->i_lock);
  292. inode->i_bytes = inode_size;
  293. inode->i_blocks =
  294. (unsigned long)(rounded_up_size / 512);
  295. spin_unlock(&inode->i_lock);
  296. }
  297. break;
  298. case S_IFDIR:
  299. if (request_mask & STATX_SIZE || new) {
  300. inode->i_size = PAGE_SIZE;
  301. orangefs_inode->blksize = i_blocksize(inode);
  302. spin_lock(&inode->i_lock);
  303. inode_set_bytes(inode, inode->i_size);
  304. spin_unlock(&inode->i_lock);
  305. }
  306. set_nlink(inode, 1);
  307. break;
  308. case S_IFLNK:
  309. if (new) {
  310. inode->i_size = (loff_t)strlen(new_op->
  311. downcall.resp.getattr.link_target);
  312. orangefs_inode->blksize = i_blocksize(inode);
  313. ret = strscpy(orangefs_inode->link_target,
  314. new_op->downcall.resp.getattr.link_target,
  315. ORANGEFS_NAME_MAX);
  316. if (ret == -E2BIG) {
  317. ret = -EIO;
  318. goto out;
  319. }
  320. inode->i_link = orangefs_inode->link_target;
  321. }
  322. break;
  323. }
  324. inode->i_uid = make_kuid(&init_user_ns, new_op->
  325. downcall.resp.getattr.attributes.owner);
  326. inode->i_gid = make_kgid(&init_user_ns, new_op->
  327. downcall.resp.getattr.attributes.group);
  328. inode->i_atime.tv_sec = (time64_t)new_op->
  329. downcall.resp.getattr.attributes.atime;
  330. inode->i_mtime.tv_sec = (time64_t)new_op->
  331. downcall.resp.getattr.attributes.mtime;
  332. inode->i_ctime.tv_sec = (time64_t)new_op->
  333. downcall.resp.getattr.attributes.ctime;
  334. inode->i_atime.tv_nsec = 0;
  335. inode->i_mtime.tv_nsec = 0;
  336. inode->i_ctime.tv_nsec = 0;
  337. /* special case: mark the root inode as sticky */
  338. inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
  339. orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
  340. orangefs_inode->getattr_time = jiffies +
  341. orangefs_getattr_timeout_msecs*HZ/1000;
  342. if (request_mask & STATX_SIZE || new)
  343. orangefs_inode->getattr_mask = STATX_BASIC_STATS;
  344. else
  345. orangefs_inode->getattr_mask = STATX_BASIC_STATS & ~STATX_SIZE;
  346. ret = 0;
  347. out:
  348. op_release(new_op);
  349. return ret;
  350. }
  351. int orangefs_inode_check_changed(struct inode *inode)
  352. {
  353. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  354. struct orangefs_kernel_op_s *new_op;
  355. int ret;
  356. gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
  357. get_khandle_from_ino(inode));
  358. new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
  359. if (!new_op)
  360. return -ENOMEM;
  361. new_op->upcall.req.getattr.refn = orangefs_inode->refn;
  362. new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE |
  363. ORANGEFS_ATTR_SYS_LNK_TARGET;
  364. ret = service_operation(new_op, __func__,
  365. get_interruptible_flag(inode));
  366. if (ret != 0)
  367. goto out;
  368. ret = orangefs_inode_is_stale(inode, 0,
  369. &new_op->downcall.resp.getattr.attributes,
  370. new_op->downcall.resp.getattr.link_target);
  371. out:
  372. op_release(new_op);
  373. return ret;
  374. }
  375. /*
  376. * issues a orangefs setattr request to make sure the new attribute values
  377. * take effect if successful. returns 0 on success; -errno otherwise
  378. */
  379. int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
  380. {
  381. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  382. struct orangefs_kernel_op_s *new_op;
  383. int ret;
  384. new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
  385. if (!new_op)
  386. return -ENOMEM;
  387. new_op->upcall.req.setattr.refn = orangefs_inode->refn;
  388. ret = copy_attributes_from_inode(inode,
  389. &new_op->upcall.req.setattr.attributes,
  390. iattr);
  391. if (ret >= 0) {
  392. ret = service_operation(new_op, __func__,
  393. get_interruptible_flag(inode));
  394. gossip_debug(GOSSIP_UTILS_DEBUG,
  395. "orangefs_inode_setattr: returning %d\n",
  396. ret);
  397. }
  398. op_release(new_op);
  399. /*
  400. * successful setattr should clear the atime, mtime and
  401. * ctime flags.
  402. */
  403. if (ret == 0) {
  404. ClearAtimeFlag(orangefs_inode);
  405. ClearMtimeFlag(orangefs_inode);
  406. ClearCtimeFlag(orangefs_inode);
  407. ClearModeFlag(orangefs_inode);
  408. orangefs_inode->getattr_time = jiffies - 1;
  409. }
  410. return ret;
  411. }
  412. int orangefs_flush_inode(struct inode *inode)
  413. {
  414. /*
  415. * If it is a dirty inode, this function gets called.
  416. * Gather all the information that needs to be setattr'ed
  417. * Right now, this will only be used for mode, atime, mtime
  418. * and/or ctime.
  419. */
  420. struct iattr wbattr;
  421. int ret;
  422. int mtime_flag;
  423. int ctime_flag;
  424. int atime_flag;
  425. int mode_flag;
  426. struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
  427. memset(&wbattr, 0, sizeof(wbattr));
  428. /*
  429. * check inode flags up front, and clear them if they are set. This
  430. * will prevent multiple processes from all trying to flush the same
  431. * inode if they call close() simultaneously
  432. */
  433. mtime_flag = MtimeFlag(orangefs_inode);
  434. ClearMtimeFlag(orangefs_inode);
  435. ctime_flag = CtimeFlag(orangefs_inode);
  436. ClearCtimeFlag(orangefs_inode);
  437. atime_flag = AtimeFlag(orangefs_inode);
  438. ClearAtimeFlag(orangefs_inode);
  439. mode_flag = ModeFlag(orangefs_inode);
  440. ClearModeFlag(orangefs_inode);
  441. /* -- Lazy atime,mtime and ctime update --
  442. * Note: all times are dictated by server in the new scheme
  443. * and not by the clients
  444. *
  445. * Also mode updates are being handled now..
  446. */
  447. if (mtime_flag)
  448. wbattr.ia_valid |= ATTR_MTIME;
  449. if (ctime_flag)
  450. wbattr.ia_valid |= ATTR_CTIME;
  451. if (atime_flag)
  452. wbattr.ia_valid |= ATTR_ATIME;
  453. if (mode_flag) {
  454. wbattr.ia_mode = inode->i_mode;
  455. wbattr.ia_valid |= ATTR_MODE;
  456. }
  457. gossip_debug(GOSSIP_UTILS_DEBUG,
  458. "*********** orangefs_flush_inode: %pU "
  459. "(ia_valid %d)\n",
  460. get_khandle_from_ino(inode),
  461. wbattr.ia_valid);
  462. if (wbattr.ia_valid == 0) {
  463. gossip_debug(GOSSIP_UTILS_DEBUG,
  464. "orangefs_flush_inode skipping setattr()\n");
  465. return 0;
  466. }
  467. gossip_debug(GOSSIP_UTILS_DEBUG,
  468. "orangefs_flush_inode (%pU) writing mode %o\n",
  469. get_khandle_from_ino(inode),
  470. inode->i_mode);
  471. ret = orangefs_inode_setattr(inode, &wbattr);
  472. return ret;
  473. }
  474. void orangefs_make_bad_inode(struct inode *inode)
  475. {
  476. if (is_root_handle(inode)) {
  477. /*
  478. * if this occurs, the pvfs2-client-core was killed but we
  479. * can't afford to lose the inode operations and such
  480. * associated with the root handle in any case.
  481. */
  482. gossip_debug(GOSSIP_UTILS_DEBUG,
  483. "*** NOT making bad root inode %pU\n",
  484. get_khandle_from_ino(inode));
  485. } else {
  486. gossip_debug(GOSSIP_UTILS_DEBUG,
  487. "*** making bad inode %pU\n",
  488. get_khandle_from_ino(inode));
  489. make_bad_inode(inode);
  490. }
  491. }
  492. /*
  493. * The following is a very dirty hack that is now a permanent part of the
  494. * ORANGEFS protocol. See protocol.h for more error definitions.
  495. */
  496. /* The order matches include/orangefs-types.h in the OrangeFS source. */
  497. static int PINT_errno_mapping[] = {
  498. 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
  499. EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
  500. EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
  501. ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
  502. EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
  503. EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
  504. ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
  505. EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
  506. ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
  507. EACCES, ECONNRESET, ERANGE
  508. };
  509. int orangefs_normalize_to_errno(__s32 error_code)
  510. {
  511. __u32 i;
  512. /* Success */
  513. if (error_code == 0) {
  514. return 0;
  515. /*
  516. * This shouldn't ever happen. If it does it should be fixed on the
  517. * server.
  518. */
  519. } else if (error_code > 0) {
  520. gossip_err("orangefs: error status receieved.\n");
  521. gossip_err("orangefs: assuming error code is inverted.\n");
  522. error_code = -error_code;
  523. }
  524. /*
  525. * XXX: This is very bad since error codes from ORANGEFS may not be
  526. * suitable for return into userspace.
  527. */
  528. /*
  529. * Convert ORANGEFS error values into errno values suitable for return
  530. * from the kernel.
  531. */
  532. if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
  533. if (((-error_code) &
  534. (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
  535. ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
  536. /*
  537. * cancellation error codes generally correspond to
  538. * a timeout from the client's perspective
  539. */
  540. error_code = -ETIMEDOUT;
  541. } else {
  542. /* assume a default error code */
  543. gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code);
  544. error_code = -EINVAL;
  545. }
  546. /* Convert ORANGEFS encoded errno values into regular errno values. */
  547. } else if ((-error_code) & ORANGEFS_ERROR_BIT) {
  548. i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS);
  549. if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping))
  550. error_code = -PINT_errno_mapping[i];
  551. else
  552. error_code = -EINVAL;
  553. /*
  554. * Only ORANGEFS protocol error codes should ever come here. Otherwise
  555. * there is a bug somewhere.
  556. */
  557. } else {
  558. gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
  559. }
  560. return error_code;
  561. }
  562. #define NUM_MODES 11
  563. __s32 ORANGEFS_util_translate_mode(int mode)
  564. {
  565. int ret = 0;
  566. int i = 0;
  567. static int modes[NUM_MODES] = {
  568. S_IXOTH, S_IWOTH, S_IROTH,
  569. S_IXGRP, S_IWGRP, S_IRGRP,
  570. S_IXUSR, S_IWUSR, S_IRUSR,
  571. S_ISGID, S_ISUID
  572. };
  573. static int orangefs_modes[NUM_MODES] = {
  574. ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ,
  575. ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ,
  576. ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ,
  577. ORANGEFS_G_SGID, ORANGEFS_U_SUID
  578. };
  579. for (i = 0; i < NUM_MODES; i++)
  580. if (mode & modes[i])
  581. ret |= orangefs_modes[i];
  582. return ret;
  583. }
  584. #undef NUM_MODES