orangefs-utils.c 15 KB

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