blob: 46b7dcff18acedaa3b9ca07ac8ad812b3a90748c [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Mike Marshallf7be4ee2015-07-17 10:38:14 -04002/*
3 * (C) 2001 Clemson University and The University of Chicago
Martin Brandenburg8b607852018-02-07 18:44:50 +00004 * Copyright 2018 Omnibond Systems, L.L.C.
Mike Marshallf7be4ee2015-07-17 10:38:14 -04005 *
6 * See COPYING in top-level directory.
7 */
Jérémy Lefaure296200d2017-10-01 15:30:48 -04008#include <linux/kernel.h>
Mike Marshallf7be4ee2015-07-17 10:38:14 -04009#include "protocol.h"
Mike Marshall575e9462015-12-04 12:56:14 -050010#include "orangefs-kernel.h"
11#include "orangefs-dev-proto.h"
12#include "orangefs-bufmap.h"
Mike Marshallf7be4ee2015-07-17 10:38:14 -040013
Yi Liu8bb8aef2015-11-24 15:12:14 -050014__s32 fsid_of_op(struct orangefs_kernel_op_s *op)
Mike Marshallf7be4ee2015-07-17 10:38:14 -040015{
Yi Liu8bb8aef2015-11-24 15:12:14 -050016 __s32 fsid = ORANGEFS_FS_ID_NULL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040017
18 if (op) {
19 switch (op->upcall.type) {
Yi Liu8bb8aef2015-11-24 15:12:14 -050020 case ORANGEFS_VFS_OP_FILE_IO:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040021 fsid = op->upcall.req.io.refn.fs_id;
22 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050023 case ORANGEFS_VFS_OP_LOOKUP:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040024 fsid = op->upcall.req.lookup.parent_refn.fs_id;
25 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050026 case ORANGEFS_VFS_OP_CREATE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040027 fsid = op->upcall.req.create.parent_refn.fs_id;
28 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050029 case ORANGEFS_VFS_OP_GETATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040030 fsid = op->upcall.req.getattr.refn.fs_id;
31 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050032 case ORANGEFS_VFS_OP_REMOVE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040033 fsid = op->upcall.req.remove.parent_refn.fs_id;
34 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050035 case ORANGEFS_VFS_OP_MKDIR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040036 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
37 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050038 case ORANGEFS_VFS_OP_READDIR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040039 fsid = op->upcall.req.readdir.refn.fs_id;
40 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050041 case ORANGEFS_VFS_OP_SETATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040042 fsid = op->upcall.req.setattr.refn.fs_id;
43 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050044 case ORANGEFS_VFS_OP_SYMLINK:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040045 fsid = op->upcall.req.sym.parent_refn.fs_id;
46 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050047 case ORANGEFS_VFS_OP_RENAME:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040048 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
49 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050050 case ORANGEFS_VFS_OP_STATFS:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040051 fsid = op->upcall.req.statfs.fs_id;
52 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050053 case ORANGEFS_VFS_OP_TRUNCATE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040054 fsid = op->upcall.req.truncate.refn.fs_id;
55 break;
Martin Brandenburg6eaff8c2016-08-02 14:31:05 -040056 case ORANGEFS_VFS_OP_RA_FLUSH:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040057 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
58 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050059 case ORANGEFS_VFS_OP_FS_UMOUNT:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040060 fsid = op->upcall.req.fs_umount.fs_id;
61 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050062 case ORANGEFS_VFS_OP_GETXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040063 fsid = op->upcall.req.getxattr.refn.fs_id;
64 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050065 case ORANGEFS_VFS_OP_SETXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040066 fsid = op->upcall.req.setxattr.refn.fs_id;
67 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050068 case ORANGEFS_VFS_OP_LISTXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040069 fsid = op->upcall.req.listxattr.refn.fs_id;
70 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050071 case ORANGEFS_VFS_OP_REMOVEXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040072 fsid = op->upcall.req.removexattr.refn.fs_id;
73 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050074 case ORANGEFS_VFS_OP_FSYNC:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040075 fsid = op->upcall.req.fsync.refn.fs_id;
76 break;
77 default:
78 break;
79 }
80 }
81 return fsid;
82}
83
Martin Brandenburg394f6472016-01-25 15:33:39 -050084static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
Mike Marshallf7be4ee2015-07-17 10:38:14 -040085{
Martin Brandenburg394f6472016-01-25 15:33:39 -050086 int flags = 0;
Yi Liu8bb8aef2015-11-24 15:12:14 -050087 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050088 flags |= S_IMMUTABLE;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040089 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050090 flags &= ~S_IMMUTABLE;
Yi Liu8bb8aef2015-11-24 15:12:14 -050091 if (attrs->flags & ORANGEFS_APPEND_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050092 flags |= S_APPEND;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040093 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050094 flags &= ~S_APPEND;
Yi Liu8bb8aef2015-11-24 15:12:14 -050095 if (attrs->flags & ORANGEFS_NOATIME_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050096 flags |= S_NOATIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040097 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050098 flags &= ~S_NOATIME;
99 return flags;
100}
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400101
Martin Brandenburg394f6472016-01-25 15:33:39 -0500102static 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;
119
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;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400133}
134
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400135/*
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 */
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000139static inline void copy_attributes_from_inode(struct inode *inode,
140 struct ORANGEFS_sys_attr_s *attrs)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400141{
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000142 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400143 attrs->mask = 0;
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000144 if (orangefs_inode->attr_valid & ATTR_UID) {
145 attrs->owner = from_kuid(&init_user_ns, inode->i_uid);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500146 attrs->mask |= ORANGEFS_ATTR_SYS_UID;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400147 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
148 }
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000149 if (orangefs_inode->attr_valid & ATTR_GID) {
150 attrs->group = from_kgid(&init_user_ns, inode->i_gid);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500151 attrs->mask |= ORANGEFS_ATTR_SYS_GID;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400152 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
153 }
154
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000155 if (orangefs_inode->attr_valid & ATTR_ATIME) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500156 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000157 if (orangefs_inode->attr_valid & ATTR_ATIME_SET) {
158 attrs->atime = (time64_t)inode->i_atime.tv_sec;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500159 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400160 }
161 }
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000162 if (orangefs_inode->attr_valid & ATTR_MTIME) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500163 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000164 if (orangefs_inode->attr_valid & ATTR_MTIME_SET) {
165 attrs->mtime = (time64_t)inode->i_mtime.tv_sec;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500166 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400167 }
168 }
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000169 if (orangefs_inode->attr_valid & ATTR_CTIME)
Yi Liu8bb8aef2015-11-24 15:12:14 -0500170 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400171
172 /*
Mike Marshall95f5f882018-05-11 17:11:48 -0400173 * 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
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400176 */
177
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000178 if (orangefs_inode->attr_valid & ATTR_MODE) {
179 attrs->perms = ORANGEFS_util_translate_mode(inode->i_mode);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500180 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400181 }
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400182}
183
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400184static 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
Martin Brandenburg4d0cac72018-01-26 14:07:14 -0500196static 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
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000215static int orangefs_inode_is_stale(struct inode *inode,
Martin Brandenburg26662632016-03-17 16:01:52 -0400216 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);
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000220 /*
221 * If the inode type or symlink target have changed then this
222 * inode is stale.
223 */
Al Viroe89f00d2021-02-13 23:03:20 -0500224 if (type == -1 || inode_wrong_type(inode, type)) {
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000225 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;
Martin Brandenburg26662632016-03-17 16:01:52 -0400232 }
233 return 0;
234}
235
Martin Brandenburg8b607852018-02-07 18:44:50 +0000236int orangefs_inode_getattr(struct inode *inode, int flags)
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400237{
238 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
239 struct orangefs_kernel_op_s *new_op;
Martin Brandenburg9f8fd532018-05-31 16:36:59 +0000240 loff_t inode_size;
Martin Brandenburg26662632016-03-17 16:01:52 -0400241 int ret, type;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400242
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000243 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU flags %d\n",
244 __func__, get_khandle_from_ino(inode), flags);
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400245
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000246again:
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000247 spin_lock(&inode->i_lock);
Martin Brandenburg8b607852018-02-07 18:44:50 +0000248 /* Must have all the attributes in the mask and be within cache time. */
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000249 if ((!flags && time_before(jiffies, orangefs_inode->getattr_time)) ||
Martin Brandenburg85ac7992018-02-22 18:10:43 +0000250 orangefs_inode->attr_valid || inode->i_state & I_DIRTY_PAGES) {
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000251 if (orangefs_inode->attr_valid) {
252 spin_unlock(&inode->i_lock);
253 write_inode_now(inode, 1);
254 goto again;
255 }
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000256 spin_unlock(&inode->i_lock);
Martin Brandenburg8b607852018-02-07 18:44:50 +0000257 return 0;
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000258 }
259 spin_unlock(&inode->i_lock);
Martin Brandenburg71680c12016-06-09 16:32:38 -0400260
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400261 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;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400265 /*
266 * Size is the hardest attribute to get. The incremental cost of any
267 * other attribute is essentially zero.
268 */
Martin Brandenburg8b607852018-02-07 18:44:50 +0000269 if (flags)
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400270 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;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400274
275 ret = service_operation(new_op, __func__,
276 get_interruptible_flag(inode));
277 if (ret != 0)
278 goto out;
279
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000280again2:
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000281 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)) ||
Martin Brandenburg85ac7992018-02-22 18:10:43 +0000284 orangefs_inode->attr_valid || inode->i_state & I_DIRTY_PAGES) {
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000285 if (orangefs_inode->attr_valid) {
286 spin_unlock(&inode->i_lock);
287 write_inode_now(inode, 1);
288 goto again2;
289 }
Martin Brandenburg85ac7992018-02-22 18:10:43 +0000290 if (inode->i_state & I_DIRTY_PAGES) {
291 ret = 0;
292 goto out_unlock;
293 }
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000294 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: in cache or dirty\n",
295 __func__);
296 ret = 0;
297 goto out_unlock;
298 }
299
Martin Brandenburg8b607852018-02-07 18:44:50 +0000300 if (!(flags & ORANGEFS_GETATTR_NEW)) {
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000301 ret = orangefs_inode_is_stale(inode,
302 &new_op->downcall.resp.getattr.attributes,
303 new_op->downcall.resp.getattr.link_target);
304 if (ret) {
305 ret = -ESTALE;
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000306 goto out_unlock;
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000307 }
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400308 }
309
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000310 type = orangefs_inode_type(new_op->
311 downcall.resp.getattr.attributes.objtype);
Martin Brandenburg26662632016-03-17 16:01:52 -0400312 switch (type) {
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400313 case S_IFREG:
314 inode->i_flags = orangefs_inode_flags(&new_op->
315 downcall.resp.getattr.attributes);
Martin Brandenburg8b607852018-02-07 18:44:50 +0000316 if (flags) {
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400317 inode_size = (loff_t)new_op->
318 downcall.resp.getattr.attributes.size;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400319 inode->i_size = inode_size;
Martin Brandenburg9f8fd532018-05-31 16:36:59 +0000320 inode->i_blkbits = ffs(new_op->downcall.resp.getattr.
321 attributes.blksize);
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400322 inode->i_bytes = inode_size;
323 inode->i_blocks =
Martin Brandenburg9f8fd532018-05-31 16:36:59 +0000324 (inode_size + 512 - inode_size % 512)/512;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400325 }
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400326 break;
327 case S_IFDIR:
Martin Brandenburg8b607852018-02-07 18:44:50 +0000328 if (flags) {
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400329 inode->i_size = PAGE_SIZE;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400330 inode_set_bytes(inode, inode->i_size);
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400331 }
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400332 set_nlink(inode, 1);
333 break;
334 case S_IFLNK:
Martin Brandenburg8b607852018-02-07 18:44:50 +0000335 if (flags & ORANGEFS_GETATTR_NEW) {
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400336 inode->i_size = (loff_t)strlen(new_op->
337 downcall.resp.getattr.link_target);
Martin Brandenburg2eacea72016-04-08 13:33:21 -0400338 ret = strscpy(orangefs_inode->link_target,
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400339 new_op->downcall.resp.getattr.link_target,
340 ORANGEFS_NAME_MAX);
Martin Brandenburg2eacea72016-04-08 13:33:21 -0400341 if (ret == -E2BIG) {
342 ret = -EIO;
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000343 goto out_unlock;
Martin Brandenburg2eacea72016-04-08 13:33:21 -0400344 }
Martin Brandenburge8da2542016-03-18 14:20:15 -0400345 inode->i_link = orangefs_inode->link_target;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400346 }
347 break;
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000348 /* i.e. -1 */
349 default:
350 /* XXX: ESTALE? This is what is done if it is not new. */
351 orangefs_make_bad_inode(inode);
352 ret = -ESTALE;
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000353 goto out_unlock;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400354 }
355
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->i_ctime.tv_sec = (time64_t)new_op->
365 downcall.resp.getattr.attributes.ctime;
366 inode->i_atime.tv_nsec = 0;
367 inode->i_mtime.tv_nsec = 0;
368 inode->i_ctime.tv_nsec = 0;
369
370 /* special case: mark the root inode as sticky */
Martin Brandenburg26662632016-03-17 16:01:52 -0400371 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400372 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
373
Martin Brandenburg1d503612016-08-16 11:38:14 -0400374 orangefs_inode->getattr_time = jiffies +
375 orangefs_getattr_timeout_msecs*HZ/1000;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400376 ret = 0;
Martin Brandenburg5e4f6062018-02-12 17:04:57 +0000377out_unlock:
378 spin_unlock(&inode->i_lock);
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400379out:
380 op_release(new_op);
381 return ret;
382}
383
Martin Brandenburg5859d772016-03-17 15:15:16 -0400384int orangefs_inode_check_changed(struct inode *inode)
385{
386 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
387 struct orangefs_kernel_op_s *new_op;
388 int ret;
389
390 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
391 get_khandle_from_ino(inode));
392
393 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
394 if (!new_op)
395 return -ENOMEM;
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;
399
400 ret = service_operation(new_op, __func__,
401 get_interruptible_flag(inode));
402 if (ret != 0)
403 goto out;
404
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000405 ret = orangefs_inode_is_stale(inode,
Martin Brandenburg26662632016-03-17 16:01:52 -0400406 &new_op->downcall.resp.getattr.attributes,
407 new_op->downcall.resp.getattr.link_target);
Martin Brandenburg5859d772016-03-17 15:15:16 -0400408out:
409 op_release(new_op);
410 return ret;
411}
412
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400413/*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500414 * issues a orangefs setattr request to make sure the new attribute values
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400415 * take effect if successful. returns 0 on success; -errno otherwise
416 */
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000417int orangefs_inode_setattr(struct inode *inode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400418{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500419 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
420 struct orangefs_kernel_op_s *new_op;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400421 int ret;
422
Yi Liu8bb8aef2015-11-24 15:12:14 -0500423 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400424 if (!new_op)
425 return -ENOMEM;
426
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000427 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);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500430 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000431 copy_attributes_from_inode(inode,
432 &new_op->upcall.req.setattr.attributes);
433 orangefs_inode->attr_valid = 0;
Martin Brandenburg8a88bbc2018-02-22 18:15:56 +0000434 if (!new_op->upcall.req.setattr.attributes.mask) {
435 spin_unlock(&inode->i_lock);
436 op_release(new_op);
437 return 0;
438 }
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000439 spin_unlock(&inode->i_lock);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400440
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000441 ret = service_operation(new_op, __func__,
Martin Brandenburg0dcac0f2018-02-15 19:38:01 +0000442 get_interruptible_flag(inode) | ORANGEFS_OP_WRITEBACK);
Martin Brandenburgafd9fb22018-02-13 20:13:46 +0000443 gossip_debug(GOSSIP_UTILS_DEBUG,
444 "orangefs_inode_setattr: returning %d\n", ret);
445 if (ret)
446 orangefs_make_bad_inode(inode);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400447
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400448 op_release(new_op);
449
Martin Brandenburga55f2d82017-11-07 15:01:40 -0500450 if (ret == 0)
Martin Brandenburg8bbb20a2016-07-28 14:46:36 -0400451 orangefs_inode->getattr_time = jiffies - 1;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400452 return ret;
453}
454
Mike Marshall54804942015-10-05 13:44:24 -0400455/*
456 * The following is a very dirty hack that is now a permanent part of the
Yi Liu8bb8aef2015-11-24 15:12:14 -0500457 * ORANGEFS protocol. See protocol.h for more error definitions.
Mike Marshall54804942015-10-05 13:44:24 -0400458 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400459
Yi Liu8bb8aef2015-11-24 15:12:14 -0500460/* The order matches include/orangefs-types.h in the OrangeFS source. */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400461static int PINT_errno_mapping[] = {
Mike Marshall54804942015-10-05 13:44:24 -0400462 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
Martin Brandenburg894ac432015-10-02 12:11:19 -0400472};
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400473
Yi Liu8bb8aef2015-11-24 15:12:14 -0500474int orangefs_normalize_to_errno(__s32 error_code)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400475{
Mike Marshall54804942015-10-05 13:44:24 -0400476 __u32 i;
477
Martin Brandenburg894ac432015-10-02 12:11:19 -0400478 /* Success */
479 if (error_code == 0) {
480 return 0;
Mike Marshall54804942015-10-05 13:44:24 -0400481 /*
482 * This shouldn't ever happen. If it does it should be fixed on the
483 * server.
484 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400485 } else if (error_code > 0) {
Masanari Iidabc8282a2018-01-16 00:18:36 +0900486 gossip_err("orangefs: error status received.\n");
Yi Liu8bb8aef2015-11-24 15:12:14 -0500487 gossip_err("orangefs: assuming error code is inverted.\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400488 error_code = -error_code;
489 }
490
Mike Marshall54804942015-10-05 13:44:24 -0400491 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500492 * XXX: This is very bad since error codes from ORANGEFS may not be
Mike Marshall54804942015-10-05 13:44:24 -0400493 * suitable for return into userspace.
494 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400495
Mike Marshall54804942015-10-05 13:44:24 -0400496 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500497 * Convert ORANGEFS error values into errno values suitable for return
Mike Marshall54804942015-10-05 13:44:24 -0400498 * from the kernel.
499 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500500 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
Martin Brandenburg894ac432015-10-02 12:11:19 -0400501 if (((-error_code) &
Yi Liu8bb8aef2015-11-24 15:12:14 -0500502 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
503 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400504 /*
505 * cancellation error codes generally correspond to
506 * a timeout from the client's perspective
507 */
508 error_code = -ETIMEDOUT;
509 } else {
510 /* assume a default error code */
Mike Marshall95f5f882018-05-11 17:11:48 -0400511 gossip_err("%s: bad error code :%d:.\n",
512 __func__,
513 error_code);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400514 error_code = -EINVAL;
515 }
Martin Brandenburg894ac432015-10-02 12:11:19 -0400516
Yi Liu8bb8aef2015-11-24 15:12:14 -0500517 /* 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);
Jérémy Lefaure296200d2017-10-01 15:30:48 -0400520 if (i < ARRAY_SIZE(PINT_errno_mapping))
Martin Brandenburg894ac432015-10-02 12:11:19 -0400521 error_code = -PINT_errno_mapping[i];
522 else
523 error_code = -EINVAL;
524
Mike Marshall54804942015-10-05 13:44:24 -0400525 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500526 * Only ORANGEFS protocol error codes should ever come here. Otherwise
Mike Marshall54804942015-10-05 13:44:24 -0400527 * there is a bug somewhere.
528 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400529 } else {
Mike Marshall95f5f882018-05-11 17:11:48 -0400530 gossip_err("%s: unknown error code.\n", __func__);
Mike Marshallcf546ab2018-01-25 14:43:28 -0500531 error_code = -EINVAL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400532 }
533 return error_code;
534}
535
536#define NUM_MODES 11
Yi Liu8bb8aef2015-11-24 15:12:14 -0500537__s32 ORANGEFS_util_translate_mode(int mode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400538{
539 int ret = 0;
540 int i = 0;
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,
545 S_ISGID, S_ISUID
546 };
Yi Liu8bb8aef2015-11-24 15:12:14 -0500547 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
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400552 };
553
554 for (i = 0; i < NUM_MODES; i++)
555 if (mode & modes[i])
Yi Liu8bb8aef2015-11-24 15:12:14 -0500556 ret |= orangefs_modes[i];
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400557
558 return ret;
559}
560#undef NUM_MODES