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