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