1 // SPDX-License-Identifier: GPL-2.0
3 * (C) 2001 Clemson University and The University of Chicago
4 * Copyright 2018 Omnibond Systems, L.L.C.
6 * See COPYING in top-level directory.
8 #include <linux/kernel.h>
10 #include "orangefs-kernel.h"
11 #include "orangefs-dev-proto.h"
12 #include "orangefs-bufmap.h"
14 __s32 fsid_of_op(struct orangefs_kernel_op_s *op)
16 __s32 fsid = ORANGEFS_FS_ID_NULL;
19 switch (op->upcall.type) {
20 case ORANGEFS_VFS_OP_FILE_IO:
21 fsid = op->upcall.req.io.refn.fs_id;
23 case ORANGEFS_VFS_OP_LOOKUP:
24 fsid = op->upcall.req.lookup.parent_refn.fs_id;
26 case ORANGEFS_VFS_OP_CREATE:
27 fsid = op->upcall.req.create.parent_refn.fs_id;
29 case ORANGEFS_VFS_OP_GETATTR:
30 fsid = op->upcall.req.getattr.refn.fs_id;
32 case ORANGEFS_VFS_OP_REMOVE:
33 fsid = op->upcall.req.remove.parent_refn.fs_id;
35 case ORANGEFS_VFS_OP_MKDIR:
36 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
38 case ORANGEFS_VFS_OP_READDIR:
39 fsid = op->upcall.req.readdir.refn.fs_id;
41 case ORANGEFS_VFS_OP_SETATTR:
42 fsid = op->upcall.req.setattr.refn.fs_id;
44 case ORANGEFS_VFS_OP_SYMLINK:
45 fsid = op->upcall.req.sym.parent_refn.fs_id;
47 case ORANGEFS_VFS_OP_RENAME:
48 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
50 case ORANGEFS_VFS_OP_STATFS:
51 fsid = op->upcall.req.statfs.fs_id;
53 case ORANGEFS_VFS_OP_TRUNCATE:
54 fsid = op->upcall.req.truncate.refn.fs_id;
56 case ORANGEFS_VFS_OP_RA_FLUSH:
57 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
59 case ORANGEFS_VFS_OP_FS_UMOUNT:
60 fsid = op->upcall.req.fs_umount.fs_id;
62 case ORANGEFS_VFS_OP_GETXATTR:
63 fsid = op->upcall.req.getxattr.refn.fs_id;
65 case ORANGEFS_VFS_OP_SETXATTR:
66 fsid = op->upcall.req.setxattr.refn.fs_id;
68 case ORANGEFS_VFS_OP_LISTXATTR:
69 fsid = op->upcall.req.listxattr.refn.fs_id;
71 case ORANGEFS_VFS_OP_REMOVEXATTR:
72 fsid = op->upcall.req.removexattr.refn.fs_id;
74 case ORANGEFS_VFS_OP_FSYNC:
75 fsid = op->upcall.req.fsync.refn.fs_id;
84 static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
87 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
90 flags &= ~S_IMMUTABLE;
91 if (attrs->flags & ORANGEFS_APPEND_FL)
95 if (attrs->flags & ORANGEFS_NOATIME_FL)
102 static int orangefs_inode_perms(struct ORANGEFS_sys_attr_s *attrs)
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;
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;
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;
127 if (attrs->perms & ORANGEFS_G_SGID)
128 perm_mode |= S_ISGID;
129 if (attrs->perms & ORANGEFS_U_SUID)
130 perm_mode |= S_ISUID;
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.
139 static inline void copy_attributes_from_inode(struct inode *inode,
140 struct ORANGEFS_sys_attr_s *attrs)
142 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
144 if (orangefs_inode->attr_valid & ATTR_UID) {
145 attrs->owner = from_kuid(&init_user_ns, inode->i_uid);
146 attrs->mask |= ORANGEFS_ATTR_SYS_UID;
147 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
149 if (orangefs_inode->attr_valid & ATTR_GID) {
150 attrs->group = from_kgid(&init_user_ns, inode->i_gid);
151 attrs->mask |= ORANGEFS_ATTR_SYS_GID;
152 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
155 if (orangefs_inode->attr_valid & ATTR_ATIME) {
156 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
157 if (orangefs_inode->attr_valid & ATTR_ATIME_SET) {
158 attrs->atime = (time64_t)inode->i_atime.tv_sec;
159 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
162 if (orangefs_inode->attr_valid & ATTR_MTIME) {
163 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
164 if (orangefs_inode->attr_valid & ATTR_MTIME_SET) {
165 attrs->mtime = (time64_t)inode->i_mtime.tv_sec;
166 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
169 if (orangefs_inode->attr_valid & ATTR_CTIME)
170 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
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
178 if (orangefs_inode->attr_valid & ATTR_MODE) {
179 attrs->perms = ORANGEFS_util_translate_mode(inode->i_mode);
180 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
184 static int orangefs_inode_type(enum orangefs_ds_type objtype)
186 if (objtype == ORANGEFS_TYPE_METAFILE)
188 else if (objtype == ORANGEFS_TYPE_DIRECTORY)
190 else if (objtype == ORANGEFS_TYPE_SYMLINK)
196 static void orangefs_make_bad_inode(struct inode *inode)
198 if (is_root_handle(inode)) {
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.
204 gossip_debug(GOSSIP_UTILS_DEBUG,
205 "*** NOT making bad root inode %pU\n",
206 get_khandle_from_ino(inode));
208 gossip_debug(GOSSIP_UTILS_DEBUG,
209 "*** making bad inode %pU\n",
210 get_khandle_from_ino(inode));
211 make_bad_inode(inode);
215 static int orangefs_inode_is_stale(struct inode *inode,
216 struct ORANGEFS_sys_attr_s *attrs, char *link_target)
218 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
219 int type = orangefs_inode_type(attrs->objtype);
221 * If the inode type or symlink target have changed then this
224 if (type == -1 || inode_wrong_type(inode, type)) {
225 orangefs_make_bad_inode(inode);
228 if (type == S_IFLNK && strncmp(orangefs_inode->link_target,
229 link_target, ORANGEFS_NAME_MAX)) {
230 orangefs_make_bad_inode(inode);
236 int orangefs_inode_getattr(struct inode *inode, int flags)
238 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
239 struct orangefs_kernel_op_s *new_op;
243 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU flags %d\n",
244 __func__, get_khandle_from_ino(inode), flags);
247 spin_lock(&inode->i_lock);
248 /* Must have all the attributes in the mask and be within cache time. */
249 if ((!flags && time_before(jiffies, orangefs_inode->getattr_time)) ||
250 orangefs_inode->attr_valid || inode->i_state & I_DIRTY_PAGES) {
251 if (orangefs_inode->attr_valid) {
252 spin_unlock(&inode->i_lock);
253 write_inode_now(inode, 1);
256 spin_unlock(&inode->i_lock);
259 spin_unlock(&inode->i_lock);
261 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
264 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
266 * Size is the hardest attribute to get. The incremental cost of any
267 * other attribute is essentially zero.
270 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
272 new_op->upcall.req.getattr.mask =
273 ORANGEFS_ATTR_SYS_ALL_NOHINT & ~ORANGEFS_ATTR_SYS_SIZE;
275 ret = service_operation(new_op, __func__,
276 get_interruptible_flag(inode));
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)) ||
284 orangefs_inode->attr_valid || inode->i_state & I_DIRTY_PAGES) {
285 if (orangefs_inode->attr_valid) {
286 spin_unlock(&inode->i_lock);
287 write_inode_now(inode, 1);
290 if (inode->i_state & I_DIRTY_PAGES) {
294 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: in cache or dirty\n",
300 if (!(flags & ORANGEFS_GETATTR_NEW)) {
301 ret = orangefs_inode_is_stale(inode,
302 &new_op->downcall.resp.getattr.attributes,
303 new_op->downcall.resp.getattr.link_target);
310 type = orangefs_inode_type(new_op->
311 downcall.resp.getattr.attributes.objtype);
314 inode->i_flags = orangefs_inode_flags(&new_op->
315 downcall.resp.getattr.attributes);
317 inode_size = (loff_t)new_op->
318 downcall.resp.getattr.attributes.size;
319 inode->i_size = inode_size;
320 inode->i_blkbits = ffs(new_op->downcall.resp.getattr.
322 inode->i_bytes = inode_size;
324 (inode_size + 512 - inode_size % 512)/512;
329 inode->i_size = PAGE_SIZE;
330 inode_set_bytes(inode, inode->i_size);
335 if (flags & ORANGEFS_GETATTR_NEW) {
336 inode->i_size = (loff_t)strlen(new_op->
337 downcall.resp.getattr.link_target);
338 ret = strscpy(orangefs_inode->link_target,
339 new_op->downcall.resp.getattr.link_target,
345 inode->i_link = orangefs_inode->link_target;
350 /* XXX: ESTALE? This is what is done if it is not new. */
351 orangefs_make_bad_inode(inode);
356 inode->i_uid = make_kuid(&init_user_ns, new_op->
357 downcall.resp.getattr.attributes.owner);
358 inode->i_gid = make_kgid(&init_user_ns, new_op->
359 downcall.resp.getattr.attributes.group);
360 inode->i_atime.tv_sec = (time64_t)new_op->
361 downcall.resp.getattr.attributes.atime;
362 inode->i_mtime.tv_sec = (time64_t)new_op->
363 downcall.resp.getattr.attributes.mtime;
364 inode_set_ctime(inode,
365 (time64_t)new_op->downcall.resp.getattr.attributes.ctime,
367 inode->i_atime.tv_nsec = 0;
368 inode->i_mtime.tv_nsec = 0;
370 /* special case: mark the root inode as sticky */
371 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
372 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
374 orangefs_inode->getattr_time = jiffies +
375 orangefs_getattr_timeout_msecs*HZ/1000;
378 spin_unlock(&inode->i_lock);
384 int orangefs_inode_check_changed(struct inode *inode)
386 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
387 struct orangefs_kernel_op_s *new_op;
390 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
391 get_khandle_from_ino(inode));
393 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
396 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
397 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE |
398 ORANGEFS_ATTR_SYS_LNK_TARGET;
400 ret = service_operation(new_op, __func__,
401 get_interruptible_flag(inode));
405 ret = orangefs_inode_is_stale(inode,
406 &new_op->downcall.resp.getattr.attributes,
407 new_op->downcall.resp.getattr.link_target);
414 * issues a orangefs setattr request to make sure the new attribute values
415 * take effect if successful. returns 0 on success; -errno otherwise
417 int orangefs_inode_setattr(struct inode *inode)
419 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
420 struct orangefs_kernel_op_s *new_op;
423 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
427 spin_lock(&inode->i_lock);
428 new_op->upcall.uid = from_kuid(&init_user_ns, orangefs_inode->attr_uid);
429 new_op->upcall.gid = from_kgid(&init_user_ns, orangefs_inode->attr_gid);
430 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
431 copy_attributes_from_inode(inode,
432 &new_op->upcall.req.setattr.attributes);
433 orangefs_inode->attr_valid = 0;
434 if (!new_op->upcall.req.setattr.attributes.mask) {
435 spin_unlock(&inode->i_lock);
439 spin_unlock(&inode->i_lock);
441 ret = service_operation(new_op, __func__,
442 get_interruptible_flag(inode) | ORANGEFS_OP_WRITEBACK);
443 gossip_debug(GOSSIP_UTILS_DEBUG,
444 "orangefs_inode_setattr: returning %d\n", ret);
446 orangefs_make_bad_inode(inode);
451 orangefs_inode->getattr_time = jiffies - 1;
456 * The following is a very dirty hack that is now a permanent part of the
457 * ORANGEFS protocol. See protocol.h for more error definitions.
460 /* The order matches include/orangefs-types.h in the OrangeFS source. */
461 static int PINT_errno_mapping[] = {
462 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
463 EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
464 EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
465 ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
466 EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
467 EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
468 ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
469 EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
470 ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
471 EACCES, ECONNRESET, ERANGE
474 int orangefs_normalize_to_errno(__s32 error_code)
479 if (error_code == 0) {
482 * This shouldn't ever happen. If it does it should be fixed on the
485 } else if (error_code > 0) {
486 gossip_err("orangefs: error status received.\n");
487 gossip_err("orangefs: assuming error code is inverted.\n");
488 error_code = -error_code;
492 * XXX: This is very bad since error codes from ORANGEFS may not be
493 * suitable for return into userspace.
497 * Convert ORANGEFS error values into errno values suitable for return
500 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
502 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
503 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
505 * cancellation error codes generally correspond to
506 * a timeout from the client's perspective
508 error_code = -ETIMEDOUT;
510 /* assume a default error code */
511 gossip_err("%s: bad error code :%d:.\n",
514 error_code = -EINVAL;
517 /* Convert ORANGEFS encoded errno values into regular errno values. */
518 } else if ((-error_code) & ORANGEFS_ERROR_BIT) {
519 i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS);
520 if (i < ARRAY_SIZE(PINT_errno_mapping))
521 error_code = -PINT_errno_mapping[i];
523 error_code = -EINVAL;
526 * Only ORANGEFS protocol error codes should ever come here. Otherwise
527 * there is a bug somewhere.
530 gossip_err("%s: unknown error code.\n", __func__);
531 error_code = -EINVAL;
537 __s32 ORANGEFS_util_translate_mode(int mode)
541 static int modes[NUM_MODES] = {
542 S_IXOTH, S_IWOTH, S_IROTH,
543 S_IXGRP, S_IWGRP, S_IRGRP,
544 S_IXUSR, S_IWUSR, S_IRUSR,
547 static int orangefs_modes[NUM_MODES] = {
548 ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ,
549 ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ,
550 ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ,
551 ORANGEFS_G_SGID, ORANGEFS_U_SUID
554 for (i = 0; i < NUM_MODES; i++)
556 ret |= orangefs_modes[i];