]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/orangefs/orangefs-utils.c
orangefs: remove ORANGEFS_READDIR macros
[mirror_ubuntu-artful-kernel.git] / fs / orangefs / orangefs-utils.c
CommitLineData
f7be4ee0
MM
1/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * See COPYING in top-level directory.
5 */
6#include "protocol.h"
575e9461
MM
7#include "orangefs-kernel.h"
8#include "orangefs-dev-proto.h"
9#include "orangefs-bufmap.h"
f7be4ee0 10
8bb8aefd 11__s32 fsid_of_op(struct orangefs_kernel_op_s *op)
f7be4ee0 12{
8bb8aefd 13 __s32 fsid = ORANGEFS_FS_ID_NULL;
f7be4ee0
MM
14
15 if (op) {
16 switch (op->upcall.type) {
8bb8aefd 17 case ORANGEFS_VFS_OP_FILE_IO:
f7be4ee0
MM
18 fsid = op->upcall.req.io.refn.fs_id;
19 break;
8bb8aefd 20 case ORANGEFS_VFS_OP_LOOKUP:
f7be4ee0
MM
21 fsid = op->upcall.req.lookup.parent_refn.fs_id;
22 break;
8bb8aefd 23 case ORANGEFS_VFS_OP_CREATE:
f7be4ee0
MM
24 fsid = op->upcall.req.create.parent_refn.fs_id;
25 break;
8bb8aefd 26 case ORANGEFS_VFS_OP_GETATTR:
f7be4ee0
MM
27 fsid = op->upcall.req.getattr.refn.fs_id;
28 break;
8bb8aefd 29 case ORANGEFS_VFS_OP_REMOVE:
f7be4ee0
MM
30 fsid = op->upcall.req.remove.parent_refn.fs_id;
31 break;
8bb8aefd 32 case ORANGEFS_VFS_OP_MKDIR:
f7be4ee0
MM
33 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
34 break;
8bb8aefd 35 case ORANGEFS_VFS_OP_READDIR:
f7be4ee0
MM
36 fsid = op->upcall.req.readdir.refn.fs_id;
37 break;
8bb8aefd 38 case ORANGEFS_VFS_OP_SETATTR:
f7be4ee0
MM
39 fsid = op->upcall.req.setattr.refn.fs_id;
40 break;
8bb8aefd 41 case ORANGEFS_VFS_OP_SYMLINK:
f7be4ee0
MM
42 fsid = op->upcall.req.sym.parent_refn.fs_id;
43 break;
8bb8aefd 44 case ORANGEFS_VFS_OP_RENAME:
f7be4ee0
MM
45 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
46 break;
8bb8aefd 47 case ORANGEFS_VFS_OP_STATFS:
f7be4ee0
MM
48 fsid = op->upcall.req.statfs.fs_id;
49 break;
8bb8aefd 50 case ORANGEFS_VFS_OP_TRUNCATE:
f7be4ee0
MM
51 fsid = op->upcall.req.truncate.refn.fs_id;
52 break;
6eaff8c7 53 case ORANGEFS_VFS_OP_RA_FLUSH:
f7be4ee0
MM
54 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
55 break;
8bb8aefd 56 case ORANGEFS_VFS_OP_FS_UMOUNT:
f7be4ee0
MM
57 fsid = op->upcall.req.fs_umount.fs_id;
58 break;
8bb8aefd 59 case ORANGEFS_VFS_OP_GETXATTR:
f7be4ee0
MM
60 fsid = op->upcall.req.getxattr.refn.fs_id;
61 break;
8bb8aefd 62 case ORANGEFS_VFS_OP_SETXATTR:
f7be4ee0
MM
63 fsid = op->upcall.req.setxattr.refn.fs_id;
64 break;
8bb8aefd 65 case ORANGEFS_VFS_OP_LISTXATTR:
f7be4ee0
MM
66 fsid = op->upcall.req.listxattr.refn.fs_id;
67 break;
8bb8aefd 68 case ORANGEFS_VFS_OP_REMOVEXATTR:
f7be4ee0
MM
69 fsid = op->upcall.req.removexattr.refn.fs_id;
70 break;
8bb8aefd 71 case ORANGEFS_VFS_OP_FSYNC:
f7be4ee0
MM
72 fsid = op->upcall.req.fsync.refn.fs_id;
73 break;
74 default:
75 break;
76 }
77 }
78 return fsid;
79}
80
394f647e 81static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
f7be4ee0 82{
394f647e 83 int flags = 0;
8bb8aefd 84 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
394f647e 85 flags |= S_IMMUTABLE;
f7be4ee0 86 else
394f647e 87 flags &= ~S_IMMUTABLE;
8bb8aefd 88 if (attrs->flags & ORANGEFS_APPEND_FL)
394f647e 89 flags |= S_APPEND;
f7be4ee0 90 else
394f647e 91 flags &= ~S_APPEND;
8bb8aefd 92 if (attrs->flags & ORANGEFS_NOATIME_FL)
394f647e 93 flags |= S_NOATIME;
f7be4ee0 94 else
394f647e
MB
95 flags &= ~S_NOATIME;
96 return flags;
97}
98
99static 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;
f7be4ee0 116
394f647e
MB
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;
f7be4ee0
MM
130}
131
f7be4ee0
MM
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 */
136static inline int copy_attributes_from_inode(struct inode *inode,
8bb8aefd 137 struct ORANGEFS_sys_attr_s *attrs,
f7be4ee0
MM
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) {
78fee0b6 156 attrs->owner = from_kuid(&init_user_ns, iattr->ia_uid);
8bb8aefd 157 attrs->mask |= ORANGEFS_ATTR_SYS_UID;
f7be4ee0
MM
158 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
159 }
160 if (iattr->ia_valid & ATTR_GID) {
78fee0b6 161 attrs->group = from_kgid(&init_user_ns, iattr->ia_gid);
8bb8aefd 162 attrs->mask |= ORANGEFS_ATTR_SYS_GID;
f7be4ee0
MM
163 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
164 }
165
166 if (iattr->ia_valid & ATTR_ATIME) {
8bb8aefd 167 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
f7be4ee0 168 if (iattr->ia_valid & ATTR_ATIME_SET) {
be81ce48 169 attrs->atime = (time64_t)iattr->ia_atime.tv_sec;
8bb8aefd 170 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
f7be4ee0
MM
171 }
172 }
173 if (iattr->ia_valid & ATTR_MTIME) {
8bb8aefd 174 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
f7be4ee0 175 if (iattr->ia_valid & ATTR_MTIME_SET) {
be81ce48 176 attrs->mtime = (time64_t)iattr->ia_mtime.tv_sec;
8bb8aefd 177 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
f7be4ee0
MM
178 }
179 }
180 if (iattr->ia_valid & ATTR_CTIME)
8bb8aefd 181 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
f7be4ee0
MM
182
183 /*
8bb8aefd 184 * ORANGEFS cannot set size with a setattr operation. Probably not likely
f7be4ee0
MM
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
8bb8aefd
YL
212 attrs->perms = ORANGEFS_util_translate_mode(tmp_mode);
213 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
f7be4ee0
MM
214 }
215
216 return 0;
217}
218
3c9cf98d
MB
219static 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
26662633
MB
231static 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
71680c18 254int orangefs_inode_getattr(struct inode *inode, int new, int bypass)
3c9cf98d
MB
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;
26662633 259 int ret, type;
3c9cf98d
MB
260
261 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
262 get_khandle_from_ino(inode));
263
71680c18 264 if (!new && !bypass) {
8bbb20a8 265 if (time_before(jiffies, orangefs_inode->getattr_time))
71680c18
MB
266 return 0;
267 }
268
3c9cf98d
MB
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;
71680c18 273 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
3c9cf98d
MB
274
275 ret = service_operation(new_op, __func__,
276 get_interruptible_flag(inode));
277 if (ret != 0)
278 goto out;
279
26662633 280 type = orangefs_inode_type(new_op->
3c9cf98d 281 downcall.resp.getattr.attributes.objtype);
26662633
MB
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;
3c9cf98d
MB
288 }
289
26662633 290 switch (type) {
3c9cf98d
MB
291 case S_IFREG:
292 inode->i_flags = orangefs_inode_flags(&new_op->
293 downcall.resp.getattr.attributes);
71680c18
MB
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);
3c9cf98d
MB
306 break;
307 case S_IFDIR:
09cbfeaf 308 inode->i_size = PAGE_SIZE;
93407472 309 orangefs_inode->blksize = i_blocksize(inode);
3c9cf98d
MB
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);
93407472 319 orangefs_inode->blksize = i_blocksize(inode);
2eacea74 320 ret = strscpy(orangefs_inode->link_target,
3c9cf98d
MB
321 new_op->downcall.resp.getattr.link_target,
322 ORANGEFS_NAME_MAX);
2eacea74
MB
323 if (ret == -E2BIG) {
324 ret = -EIO;
325 goto out;
326 }
e8da254c 327 inode->i_link = orangefs_inode->link_target;
3c9cf98d
MB
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 */
26662633 347 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
3c9cf98d
MB
348 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
349
1d503617
MB
350 orangefs_inode->getattr_time = jiffies +
351 orangefs_getattr_timeout_msecs*HZ/1000;
3c9cf98d
MB
352 ret = 0;
353out:
354 op_release(new_op);
355 return ret;
356}
357
5859d77e
MB
358int 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
26662633
MB
379 ret = orangefs_inode_is_stale(inode, 0,
380 &new_op->downcall.resp.getattr.attributes,
381 new_op->downcall.resp.getattr.link_target);
5859d77e
MB
382out:
383 op_release(new_op);
384 return ret;
385}
386
f7be4ee0 387/*
8bb8aefd 388 * issues a orangefs setattr request to make sure the new attribute values
f7be4ee0
MM
389 * take effect if successful. returns 0 on success; -errno otherwise
390 */
8bb8aefd 391int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
f7be4ee0 392{
8bb8aefd
YL
393 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
394 struct orangefs_kernel_op_s *new_op;
f7be4ee0
MM
395 int ret;
396
8bb8aefd 397 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
f7be4ee0
MM
398 if (!new_op)
399 return -ENOMEM;
400
8bb8aefd 401 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
f7be4ee0
MM
402 ret = copy_attributes_from_inode(inode,
403 &new_op->upcall.req.setattr.attributes,
404 iattr);
ed42fe05
AV
405 if (ret >= 0) {
406 ret = service_operation(new_op, __func__,
f7be4ee0
MM
407 get_interruptible_flag(inode));
408
ed42fe05
AV
409 gossip_debug(GOSSIP_UTILS_DEBUG,
410 "orangefs_inode_setattr: returning %d\n",
411 ret);
412 }
f7be4ee0 413
f7be4ee0
MM
414 op_release(new_op);
415
416 /*
417 * successful setattr should clear the atime, mtime and
418 * ctime flags.
419 */
420 if (ret == 0) {
8bb8aefd
YL
421 ClearAtimeFlag(orangefs_inode);
422 ClearMtimeFlag(orangefs_inode);
423 ClearCtimeFlag(orangefs_inode);
424 ClearModeFlag(orangefs_inode);
8bbb20a8 425 orangefs_inode->getattr_time = jiffies - 1;
f7be4ee0
MM
426 }
427
428 return ret;
429}
430
8bb8aefd 431int orangefs_flush_inode(struct inode *inode)
f7be4ee0
MM
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;
8bb8aefd 445 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
f7be4ee0
MM
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 */
8bb8aefd
YL
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);
f7be4ee0
MM
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,
8bb8aefd 483 "*********** orangefs_flush_inode: %pU "
f7be4ee0
MM
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,
8bb8aefd 489 "orangefs_flush_inode skipping setattr()\n");
f7be4ee0
MM
490 return 0;
491 }
492
493 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd 494 "orangefs_flush_inode (%pU) writing mode %o\n",
f7be4ee0
MM
495 get_khandle_from_ino(inode),
496 inode->i_mode);
497
8bb8aefd 498 ret = orangefs_inode_setattr(inode, &wbattr);
f7be4ee0
MM
499
500 return ret;
501}
502
8bb8aefd 503int orangefs_unmount_sb(struct super_block *sb)
f7be4ee0
MM
504{
505 int ret = -EINVAL;
8bb8aefd 506 struct orangefs_kernel_op_s *new_op = NULL;
f7be4ee0
MM
507
508 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd 509 "orangefs_unmount_sb called on sb %p\n",
f7be4ee0
MM
510 sb);
511
8bb8aefd 512 new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT);
f7be4ee0
MM
513 if (!new_op)
514 return -ENOMEM;
8bb8aefd
YL
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);
f7be4ee0
MM
520
521 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd
YL
522 "Attempting ORANGEFS Unmount via host %s\n",
523 new_op->upcall.req.fs_umount.orangefs_config_server);
f7be4ee0 524
8bb8aefd 525 ret = service_operation(new_op, "orangefs_fs_umount", 0);
f7be4ee0
MM
526
527 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd 528 "orangefs_unmount: got return value of %d\n", ret);
f7be4ee0
MM
529 if (ret)
530 sb = ERR_PTR(ret);
531 else
8bb8aefd 532 ORANGEFS_SB(sb)->mount_pending = 1;
f7be4ee0
MM
533
534 op_release(new_op);
535 return ret;
536}
537
8bb8aefd 538void orangefs_make_bad_inode(struct inode *inode)
f7be4ee0
MM
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
54804949
MM
557/*
558 * The following is a very dirty hack that is now a permanent part of the
8bb8aefd 559 * ORANGEFS protocol. See protocol.h for more error definitions.
54804949 560 */
894ac432 561
8bb8aefd 562/* The order matches include/orangefs-types.h in the OrangeFS source. */
894ac432 563static int PINT_errno_mapping[] = {
54804949
MM
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
894ac432 574};
f7be4ee0 575
8bb8aefd 576int orangefs_normalize_to_errno(__s32 error_code)
f7be4ee0 577{
54804949
MM
578 __u32 i;
579
894ac432
MB
580 /* Success */
581 if (error_code == 0) {
582 return 0;
54804949
MM
583 /*
584 * This shouldn't ever happen. If it does it should be fixed on the
585 * server.
586 */
894ac432 587 } else if (error_code > 0) {
8bb8aefd
YL
588 gossip_err("orangefs: error status receieved.\n");
589 gossip_err("orangefs: assuming error code is inverted.\n");
f7be4ee0
MM
590 error_code = -error_code;
591 }
592
54804949 593 /*
8bb8aefd 594 * XXX: This is very bad since error codes from ORANGEFS may not be
54804949
MM
595 * suitable for return into userspace.
596 */
894ac432 597
54804949 598 /*
8bb8aefd 599 * Convert ORANGEFS error values into errno values suitable for return
54804949
MM
600 * from the kernel.
601 */
8bb8aefd 602 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
894ac432 603 if (((-error_code) &
8bb8aefd
YL
604 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
605 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
f7be4ee0
MM
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 */
8bb8aefd 613 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code);
f7be4ee0
MM
614 error_code = -EINVAL;
615 }
894ac432 616
8bb8aefd
YL
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);
54804949 620 if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping))
894ac432
MB
621 error_code = -PINT_errno_mapping[i];
622 else
623 error_code = -EINVAL;
624
54804949 625 /*
8bb8aefd 626 * Only ORANGEFS protocol error codes should ever come here. Otherwise
54804949
MM
627 * there is a bug somewhere.
628 */
894ac432 629 } else {
8bb8aefd 630 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
f7be4ee0
MM
631 }
632 return error_code;
633}
634
635#define NUM_MODES 11
8bb8aefd 636__s32 ORANGEFS_util_translate_mode(int mode)
f7be4ee0
MM
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 };
8bb8aefd
YL
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
f7be4ee0
MM
651 };
652
653 for (i = 0; i < NUM_MODES; i++)
654 if (mode & modes[i])
8bb8aefd 655 ret |= orangefs_modes[i];
f7be4ee0
MM
656
657 return ret;
658}
659#undef NUM_MODES