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 = i_blocksize(inode); 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 = i_blocksize(inode); 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 + 351 orangefs_getattr_timeout_msecs*HZ/1000; 352 ret = 0; 353 out: 354 op_release(new_op); 355 return ret; 356 } 357 358 int orangefs_inode_check_changed(struct inode *inode) 359 { 360 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 361 struct orangefs_kernel_op_s *new_op; 362 int ret; 363 364 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__, 365 get_khandle_from_ino(inode)); 366 367 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR); 368 if (!new_op) 369 return -ENOMEM; 370 new_op->upcall.req.getattr.refn = orangefs_inode->refn; 371 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE | 372 ORANGEFS_ATTR_SYS_LNK_TARGET; 373 374 ret = service_operation(new_op, __func__, 375 get_interruptible_flag(inode)); 376 if (ret != 0) 377 goto out; 378 379 ret = orangefs_inode_is_stale(inode, 0, 380 &new_op->downcall.resp.getattr.attributes, 381 new_op->downcall.resp.getattr.link_target); 382 out: 383 op_release(new_op); 384 return ret; 385 } 386 387 /* 388 * issues a orangefs setattr request to make sure the new attribute values 389 * take effect if successful. returns 0 on success; -errno otherwise 390 */ 391 int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr) 392 { 393 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 394 struct orangefs_kernel_op_s *new_op; 395 int ret; 396 397 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR); 398 if (!new_op) 399 return -ENOMEM; 400 401 new_op->upcall.req.setattr.refn = orangefs_inode->refn; 402 ret = copy_attributes_from_inode(inode, 403 &new_op->upcall.req.setattr.attributes, 404 iattr); 405 if (ret >= 0) { 406 ret = service_operation(new_op, __func__, 407 get_interruptible_flag(inode)); 408 409 gossip_debug(GOSSIP_UTILS_DEBUG, 410 "orangefs_inode_setattr: returning %d\n", 411 ret); 412 } 413 414 op_release(new_op); 415 416 /* 417 * successful setattr should clear the atime, mtime and 418 * ctime flags. 419 */ 420 if (ret == 0) { 421 ClearAtimeFlag(orangefs_inode); 422 ClearMtimeFlag(orangefs_inode); 423 ClearCtimeFlag(orangefs_inode); 424 ClearModeFlag(orangefs_inode); 425 orangefs_inode->getattr_time = jiffies - 1; 426 } 427 428 return ret; 429 } 430 431 int orangefs_flush_inode(struct inode *inode) 432 { 433 /* 434 * If it is a dirty inode, this function gets called. 435 * Gather all the information that needs to be setattr'ed 436 * Right now, this will only be used for mode, atime, mtime 437 * and/or ctime. 438 */ 439 struct iattr wbattr; 440 int ret; 441 int mtime_flag; 442 int ctime_flag; 443 int atime_flag; 444 int mode_flag; 445 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode); 446 447 memset(&wbattr, 0, sizeof(wbattr)); 448 449 /* 450 * check inode flags up front, and clear them if they are set. This 451 * will prevent multiple processes from all trying to flush the same 452 * inode if they call close() simultaneously 453 */ 454 mtime_flag = MtimeFlag(orangefs_inode); 455 ClearMtimeFlag(orangefs_inode); 456 ctime_flag = CtimeFlag(orangefs_inode); 457 ClearCtimeFlag(orangefs_inode); 458 atime_flag = AtimeFlag(orangefs_inode); 459 ClearAtimeFlag(orangefs_inode); 460 mode_flag = ModeFlag(orangefs_inode); 461 ClearModeFlag(orangefs_inode); 462 463 /* -- Lazy atime,mtime and ctime update -- 464 * Note: all times are dictated by server in the new scheme 465 * and not by the clients 466 * 467 * Also mode updates are being handled now.. 468 */ 469 470 if (mtime_flag) 471 wbattr.ia_valid |= ATTR_MTIME; 472 if (ctime_flag) 473 wbattr.ia_valid |= ATTR_CTIME; 474 if (atime_flag) 475 wbattr.ia_valid |= ATTR_ATIME; 476 477 if (mode_flag) { 478 wbattr.ia_mode = inode->i_mode; 479 wbattr.ia_valid |= ATTR_MODE; 480 } 481 482 gossip_debug(GOSSIP_UTILS_DEBUG, 483 "*********** orangefs_flush_inode: %pU " 484 "(ia_valid %d)\n", 485 get_khandle_from_ino(inode), 486 wbattr.ia_valid); 487 if (wbattr.ia_valid == 0) { 488 gossip_debug(GOSSIP_UTILS_DEBUG, 489 "orangefs_flush_inode skipping setattr()\n"); 490 return 0; 491 } 492 493 gossip_debug(GOSSIP_UTILS_DEBUG, 494 "orangefs_flush_inode (%pU) writing mode %o\n", 495 get_khandle_from_ino(inode), 496 inode->i_mode); 497 498 ret = orangefs_inode_setattr(inode, &wbattr); 499 500 return ret; 501 } 502 503 int orangefs_unmount_sb(struct super_block *sb) 504 { 505 int ret = -EINVAL; 506 struct orangefs_kernel_op_s *new_op = NULL; 507 508 gossip_debug(GOSSIP_UTILS_DEBUG, 509 "orangefs_unmount_sb called on sb %p\n", 510 sb); 511 512 new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT); 513 if (!new_op) 514 return -ENOMEM; 515 new_op->upcall.req.fs_umount.id = ORANGEFS_SB(sb)->id; 516 new_op->upcall.req.fs_umount.fs_id = ORANGEFS_SB(sb)->fs_id; 517 strncpy(new_op->upcall.req.fs_umount.orangefs_config_server, 518 ORANGEFS_SB(sb)->devname, 519 ORANGEFS_MAX_SERVER_ADDR_LEN); 520 521 gossip_debug(GOSSIP_UTILS_DEBUG, 522 "Attempting ORANGEFS Unmount via host %s\n", 523 new_op->upcall.req.fs_umount.orangefs_config_server); 524 525 ret = service_operation(new_op, "orangefs_fs_umount", 0); 526 527 gossip_debug(GOSSIP_UTILS_DEBUG, 528 "orangefs_unmount: got return value of %d\n", ret); 529 if (ret) 530 sb = ERR_PTR(ret); 531 else 532 ORANGEFS_SB(sb)->mount_pending = 1; 533 534 op_release(new_op); 535 return ret; 536 } 537 538 void orangefs_make_bad_inode(struct inode *inode) 539 { 540 if (is_root_handle(inode)) { 541 /* 542 * if this occurs, the pvfs2-client-core was killed but we 543 * can't afford to lose the inode operations and such 544 * associated with the root handle in any case. 545 */ 546 gossip_debug(GOSSIP_UTILS_DEBUG, 547 "*** NOT making bad root inode %pU\n", 548 get_khandle_from_ino(inode)); 549 } else { 550 gossip_debug(GOSSIP_UTILS_DEBUG, 551 "*** making bad inode %pU\n", 552 get_khandle_from_ino(inode)); 553 make_bad_inode(inode); 554 } 555 } 556 557 /* 558 * The following is a very dirty hack that is now a permanent part of the 559 * ORANGEFS protocol. See protocol.h for more error definitions. 560 */ 561 562 /* The order matches include/orangefs-types.h in the OrangeFS source. */ 563 static int PINT_errno_mapping[] = { 564 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM, 565 EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE, 566 EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG, 567 ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH, 568 EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM, 569 EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE, 570 ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE, 571 EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS, 572 ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY, 573 EACCES, ECONNRESET, ERANGE 574 }; 575 576 int orangefs_normalize_to_errno(__s32 error_code) 577 { 578 __u32 i; 579 580 /* Success */ 581 if (error_code == 0) { 582 return 0; 583 /* 584 * This shouldn't ever happen. If it does it should be fixed on the 585 * server. 586 */ 587 } else if (error_code > 0) { 588 gossip_err("orangefs: error status receieved.\n"); 589 gossip_err("orangefs: assuming error code is inverted.\n"); 590 error_code = -error_code; 591 } 592 593 /* 594 * XXX: This is very bad since error codes from ORANGEFS may not be 595 * suitable for return into userspace. 596 */ 597 598 /* 599 * Convert ORANGEFS error values into errno values suitable for return 600 * from the kernel. 601 */ 602 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) { 603 if (((-error_code) & 604 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT| 605 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) { 606 /* 607 * cancellation error codes generally correspond to 608 * a timeout from the client's perspective 609 */ 610 error_code = -ETIMEDOUT; 611 } else { 612 /* assume a default error code */ 613 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code); 614 error_code = -EINVAL; 615 } 616 617 /* Convert ORANGEFS encoded errno values into regular errno values. */ 618 } else if ((-error_code) & ORANGEFS_ERROR_BIT) { 619 i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS); 620 if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping)) 621 error_code = -PINT_errno_mapping[i]; 622 else 623 error_code = -EINVAL; 624 625 /* 626 * Only ORANGEFS protocol error codes should ever come here. Otherwise 627 * there is a bug somewhere. 628 */ 629 } else { 630 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n"); 631 } 632 return error_code; 633 } 634 635 #define NUM_MODES 11 636 __s32 ORANGEFS_util_translate_mode(int mode) 637 { 638 int ret = 0; 639 int i = 0; 640 static int modes[NUM_MODES] = { 641 S_IXOTH, S_IWOTH, S_IROTH, 642 S_IXGRP, S_IWGRP, S_IRGRP, 643 S_IXUSR, S_IWUSR, S_IRUSR, 644 S_ISGID, S_ISUID 645 }; 646 static int orangefs_modes[NUM_MODES] = { 647 ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ, 648 ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ, 649 ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ, 650 ORANGEFS_G_SGID, ORANGEFS_U_SUID 651 }; 652 653 for (i = 0; i < NUM_MODES; i++) 654 if (mode & modes[i]) 655 ret |= orangefs_modes[i]; 656 657 return ret; 658 } 659 #undef NUM_MODES 660