blob: 804c8a261e4b2d5c5d211f6e8ba935ff336f1f34 [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
4 *
5 * See COPYING in top-level directory.
6 */
Jérémy Lefaure296200d2017-10-01 15:30:48 -04007#include <linux/kernel.h>
Mike Marshallf7be4ee2015-07-17 10:38:14 -04008#include "protocol.h"
Mike Marshall575e9462015-12-04 12:56:14 -05009#include "orangefs-kernel.h"
10#include "orangefs-dev-proto.h"
11#include "orangefs-bufmap.h"
Mike Marshallf7be4ee2015-07-17 10:38:14 -040012
Yi Liu8bb8aef2015-11-24 15:12:14 -050013__s32 fsid_of_op(struct orangefs_kernel_op_s *op)
Mike Marshallf7be4ee2015-07-17 10:38:14 -040014{
Yi Liu8bb8aef2015-11-24 15:12:14 -050015 __s32 fsid = ORANGEFS_FS_ID_NULL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040016
17 if (op) {
18 switch (op->upcall.type) {
Yi Liu8bb8aef2015-11-24 15:12:14 -050019 case ORANGEFS_VFS_OP_FILE_IO:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040020 fsid = op->upcall.req.io.refn.fs_id;
21 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050022 case ORANGEFS_VFS_OP_LOOKUP:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040023 fsid = op->upcall.req.lookup.parent_refn.fs_id;
24 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050025 case ORANGEFS_VFS_OP_CREATE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040026 fsid = op->upcall.req.create.parent_refn.fs_id;
27 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050028 case ORANGEFS_VFS_OP_GETATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040029 fsid = op->upcall.req.getattr.refn.fs_id;
30 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050031 case ORANGEFS_VFS_OP_REMOVE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040032 fsid = op->upcall.req.remove.parent_refn.fs_id;
33 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050034 case ORANGEFS_VFS_OP_MKDIR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040035 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
36 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050037 case ORANGEFS_VFS_OP_READDIR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040038 fsid = op->upcall.req.readdir.refn.fs_id;
39 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050040 case ORANGEFS_VFS_OP_SETATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040041 fsid = op->upcall.req.setattr.refn.fs_id;
42 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050043 case ORANGEFS_VFS_OP_SYMLINK:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040044 fsid = op->upcall.req.sym.parent_refn.fs_id;
45 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050046 case ORANGEFS_VFS_OP_RENAME:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040047 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
48 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050049 case ORANGEFS_VFS_OP_STATFS:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040050 fsid = op->upcall.req.statfs.fs_id;
51 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050052 case ORANGEFS_VFS_OP_TRUNCATE:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040053 fsid = op->upcall.req.truncate.refn.fs_id;
54 break;
Martin Brandenburg6eaff8c2016-08-02 14:31:05 -040055 case ORANGEFS_VFS_OP_RA_FLUSH:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040056 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
57 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050058 case ORANGEFS_VFS_OP_FS_UMOUNT:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040059 fsid = op->upcall.req.fs_umount.fs_id;
60 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050061 case ORANGEFS_VFS_OP_GETXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040062 fsid = op->upcall.req.getxattr.refn.fs_id;
63 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050064 case ORANGEFS_VFS_OP_SETXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040065 fsid = op->upcall.req.setxattr.refn.fs_id;
66 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050067 case ORANGEFS_VFS_OP_LISTXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040068 fsid = op->upcall.req.listxattr.refn.fs_id;
69 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050070 case ORANGEFS_VFS_OP_REMOVEXATTR:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040071 fsid = op->upcall.req.removexattr.refn.fs_id;
72 break;
Yi Liu8bb8aef2015-11-24 15:12:14 -050073 case ORANGEFS_VFS_OP_FSYNC:
Mike Marshallf7be4ee2015-07-17 10:38:14 -040074 fsid = op->upcall.req.fsync.refn.fs_id;
75 break;
76 default:
77 break;
78 }
79 }
80 return fsid;
81}
82
Martin Brandenburg394f6472016-01-25 15:33:39 -050083static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
Mike Marshallf7be4ee2015-07-17 10:38:14 -040084{
Martin Brandenburg394f6472016-01-25 15:33:39 -050085 int flags = 0;
Yi Liu8bb8aef2015-11-24 15:12:14 -050086 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050087 flags |= S_IMMUTABLE;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040088 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050089 flags &= ~S_IMMUTABLE;
Yi Liu8bb8aef2015-11-24 15:12:14 -050090 if (attrs->flags & ORANGEFS_APPEND_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050091 flags |= S_APPEND;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040092 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050093 flags &= ~S_APPEND;
Yi Liu8bb8aef2015-11-24 15:12:14 -050094 if (attrs->flags & ORANGEFS_NOATIME_FL)
Martin Brandenburg394f6472016-01-25 15:33:39 -050095 flags |= S_NOATIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -040096 else
Martin Brandenburg394f6472016-01-25 15:33:39 -050097 flags &= ~S_NOATIME;
98 return flags;
99}
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400100
Martin Brandenburg394f6472016-01-25 15:33:39 -0500101static int orangefs_inode_perms(struct ORANGEFS_sys_attr_s *attrs)
102{
103 int perm_mode = 0;
104
105 if (attrs->perms & ORANGEFS_O_EXECUTE)
106 perm_mode |= S_IXOTH;
107 if (attrs->perms & ORANGEFS_O_WRITE)
108 perm_mode |= S_IWOTH;
109 if (attrs->perms & ORANGEFS_O_READ)
110 perm_mode |= S_IROTH;
111
112 if (attrs->perms & ORANGEFS_G_EXECUTE)
113 perm_mode |= S_IXGRP;
114 if (attrs->perms & ORANGEFS_G_WRITE)
115 perm_mode |= S_IWGRP;
116 if (attrs->perms & ORANGEFS_G_READ)
117 perm_mode |= S_IRGRP;
118
119 if (attrs->perms & ORANGEFS_U_EXECUTE)
120 perm_mode |= S_IXUSR;
121 if (attrs->perms & ORANGEFS_U_WRITE)
122 perm_mode |= S_IWUSR;
123 if (attrs->perms & ORANGEFS_U_READ)
124 perm_mode |= S_IRUSR;
125
126 if (attrs->perms & ORANGEFS_G_SGID)
127 perm_mode |= S_ISGID;
128 if (attrs->perms & ORANGEFS_U_SUID)
129 perm_mode |= S_ISUID;
130
131 return perm_mode;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400132}
133
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400134/*
135 * NOTE: in kernel land, we never use the sys_attr->link_target for
136 * anything, so don't bother copying it into the sys_attr object here.
137 */
138static inline int copy_attributes_from_inode(struct inode *inode,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500139 struct ORANGEFS_sys_attr_s *attrs,
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400140 struct iattr *iattr)
141{
142 umode_t tmp_mode;
143
144 if (!iattr || !inode || !attrs) {
145 gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
146 "in copy_attributes_from_inode!\n",
147 iattr,
148 inode,
149 attrs);
150 return -EINVAL;
151 }
152 /*
153 * We need to be careful to only copy the attributes out of the
154 * iattr object that we know are valid.
155 */
156 attrs->mask = 0;
157 if (iattr->ia_valid & ATTR_UID) {
Jann Horn78fee0b2016-06-25 01:51:52 +0200158 attrs->owner = from_kuid(&init_user_ns, iattr->ia_uid);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500159 attrs->mask |= ORANGEFS_ATTR_SYS_UID;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400160 gossip_debug(GOSSIP_UTILS_DEBUG, "(UID) %d\n", attrs->owner);
161 }
162 if (iattr->ia_valid & ATTR_GID) {
Jann Horn78fee0b2016-06-25 01:51:52 +0200163 attrs->group = from_kgid(&init_user_ns, iattr->ia_gid);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500164 attrs->mask |= ORANGEFS_ATTR_SYS_GID;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400165 gossip_debug(GOSSIP_UTILS_DEBUG, "(GID) %d\n", attrs->group);
166 }
167
168 if (iattr->ia_valid & ATTR_ATIME) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500169 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400170 if (iattr->ia_valid & ATTR_ATIME_SET) {
Arnd Bergmannbe81ce42016-02-26 13:54:10 +0100171 attrs->atime = (time64_t)iattr->ia_atime.tv_sec;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500172 attrs->mask |= ORANGEFS_ATTR_SYS_ATIME_SET;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400173 }
174 }
175 if (iattr->ia_valid & ATTR_MTIME) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500176 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400177 if (iattr->ia_valid & ATTR_MTIME_SET) {
Arnd Bergmannbe81ce42016-02-26 13:54:10 +0100178 attrs->mtime = (time64_t)iattr->ia_mtime.tv_sec;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500179 attrs->mask |= ORANGEFS_ATTR_SYS_MTIME_SET;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400180 }
181 }
182 if (iattr->ia_valid & ATTR_CTIME)
Yi Liu8bb8aef2015-11-24 15:12:14 -0500183 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400184
185 /*
Mike Marshall95f5f882018-05-11 17:11:48 -0400186 * ORANGEFS cannot set size with a setattr operation. Probably not
187 * likely to be requested through the VFS, but just in case, don't
188 * worry about ATTR_SIZE
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400189 */
190
191 if (iattr->ia_valid & ATTR_MODE) {
192 tmp_mode = iattr->ia_mode;
193 if (tmp_mode & (S_ISVTX)) {
194 if (is_root_handle(inode)) {
195 /*
196 * allow sticky bit to be set on root (since
197 * it shows up that way by default anyhow),
198 * but don't show it to the server
199 */
200 tmp_mode -= S_ISVTX;
201 } else {
202 gossip_debug(GOSSIP_UTILS_DEBUG,
Mike Marshall95f5f882018-05-11 17:11:48 -0400203 "%s: setting sticky bit not supported.\n",
204 __func__);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400205 return -EINVAL;
206 }
207 }
208
209 if (tmp_mode & (S_ISUID)) {
210 gossip_debug(GOSSIP_UTILS_DEBUG,
Mike Marshall95f5f882018-05-11 17:11:48 -0400211 "%s: setting setuid bit not supported.\n",
212 __func__);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400213 return -EINVAL;
214 }
215
Yi Liu8bb8aef2015-11-24 15:12:14 -0500216 attrs->perms = ORANGEFS_util_translate_mode(tmp_mode);
217 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400218 }
219
220 return 0;
221}
222
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400223static int orangefs_inode_type(enum orangefs_ds_type objtype)
224{
225 if (objtype == ORANGEFS_TYPE_METAFILE)
226 return S_IFREG;
227 else if (objtype == ORANGEFS_TYPE_DIRECTORY)
228 return S_IFDIR;
229 else if (objtype == ORANGEFS_TYPE_SYMLINK)
230 return S_IFLNK;
231 else
232 return -1;
233}
234
Martin Brandenburg4d0cac72018-01-26 14:07:14 -0500235static void orangefs_make_bad_inode(struct inode *inode)
236{
237 if (is_root_handle(inode)) {
238 /*
239 * if this occurs, the pvfs2-client-core was killed but we
240 * can't afford to lose the inode operations and such
241 * associated with the root handle in any case.
242 */
243 gossip_debug(GOSSIP_UTILS_DEBUG,
244 "*** NOT making bad root inode %pU\n",
245 get_khandle_from_ino(inode));
246 } else {
247 gossip_debug(GOSSIP_UTILS_DEBUG,
248 "*** making bad inode %pU\n",
249 get_khandle_from_ino(inode));
250 make_bad_inode(inode);
251 }
252}
253
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000254static int orangefs_inode_is_stale(struct inode *inode,
Martin Brandenburg26662632016-03-17 16:01:52 -0400255 struct ORANGEFS_sys_attr_s *attrs, char *link_target)
256{
257 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
258 int type = orangefs_inode_type(attrs->objtype);
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000259 /*
260 * If the inode type or symlink target have changed then this
261 * inode is stale.
262 */
263 if (type == -1 || !(inode->i_mode & type)) {
264 orangefs_make_bad_inode(inode);
265 return 1;
266 }
267 if (type == S_IFLNK && strncmp(orangefs_inode->link_target,
268 link_target, ORANGEFS_NAME_MAX)) {
269 orangefs_make_bad_inode(inode);
270 return 1;
Martin Brandenburg26662632016-03-17 16:01:52 -0400271 }
272 return 0;
273}
274
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400275int orangefs_inode_getattr(struct inode *inode, int new, int bypass,
276 u32 request_mask)
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400277{
278 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
279 struct orangefs_kernel_op_s *new_op;
Martin Brandenburg9f8fd532018-05-31 16:36:59 +0000280 loff_t inode_size;
Martin Brandenburg26662632016-03-17 16:01:52 -0400281 int ret, type;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400282
283 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
284 get_khandle_from_ino(inode));
285
Martin Brandenburg71680c12016-06-09 16:32:38 -0400286 if (!new && !bypass) {
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400287 /*
288 * Must have all the attributes in the mask and be within cache
289 * time.
290 */
291 if ((request_mask & orangefs_inode->getattr_mask) ==
292 request_mask &&
293 time_before(jiffies, orangefs_inode->getattr_time))
Martin Brandenburg71680c12016-06-09 16:32:38 -0400294 return 0;
295 }
296
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400297 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
298 if (!new_op)
299 return -ENOMEM;
300 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400301 /*
302 * Size is the hardest attribute to get. The incremental cost of any
303 * other attribute is essentially zero.
304 */
305 if (request_mask & STATX_SIZE || new)
306 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_ALL_NOHINT;
307 else
308 new_op->upcall.req.getattr.mask =
309 ORANGEFS_ATTR_SYS_ALL_NOHINT & ~ORANGEFS_ATTR_SYS_SIZE;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400310
311 ret = service_operation(new_op, __func__,
312 get_interruptible_flag(inode));
313 if (ret != 0)
314 goto out;
315
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000316 if (!new) {
317 ret = orangefs_inode_is_stale(inode,
318 &new_op->downcall.resp.getattr.attributes,
319 new_op->downcall.resp.getattr.link_target);
320 if (ret) {
321 ret = -ESTALE;
322 goto out;
323 }
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400324 }
325
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000326 type = orangefs_inode_type(new_op->
327 downcall.resp.getattr.attributes.objtype);
Martin Brandenburg26662632016-03-17 16:01:52 -0400328 switch (type) {
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400329 case S_IFREG:
330 inode->i_flags = orangefs_inode_flags(&new_op->
331 downcall.resp.getattr.attributes);
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400332 if (request_mask & STATX_SIZE || new) {
333 inode_size = (loff_t)new_op->
334 downcall.resp.getattr.attributes.size;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400335 inode->i_size = inode_size;
Martin Brandenburg9f8fd532018-05-31 16:36:59 +0000336 inode->i_blkbits = ffs(new_op->downcall.resp.getattr.
337 attributes.blksize);
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400338 spin_lock(&inode->i_lock);
339 inode->i_bytes = inode_size;
340 inode->i_blocks =
Martin Brandenburg9f8fd532018-05-31 16:36:59 +0000341 (inode_size + 512 - inode_size % 512)/512;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400342 spin_unlock(&inode->i_lock);
343 }
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400344 break;
345 case S_IFDIR:
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400346 if (request_mask & STATX_SIZE || new) {
347 inode->i_size = PAGE_SIZE;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400348 spin_lock(&inode->i_lock);
349 inode_set_bytes(inode, inode->i_size);
350 spin_unlock(&inode->i_lock);
351 }
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400352 set_nlink(inode, 1);
353 break;
354 case S_IFLNK:
355 if (new) {
356 inode->i_size = (loff_t)strlen(new_op->
357 downcall.resp.getattr.link_target);
Martin Brandenburg2eacea72016-04-08 13:33:21 -0400358 ret = strscpy(orangefs_inode->link_target,
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400359 new_op->downcall.resp.getattr.link_target,
360 ORANGEFS_NAME_MAX);
Martin Brandenburg2eacea72016-04-08 13:33:21 -0400361 if (ret == -E2BIG) {
362 ret = -EIO;
363 goto out;
364 }
Martin Brandenburge8da2542016-03-18 14:20:15 -0400365 inode->i_link = orangefs_inode->link_target;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400366 }
367 break;
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000368 /* i.e. -1 */
369 default:
370 /* XXX: ESTALE? This is what is done if it is not new. */
371 orangefs_make_bad_inode(inode);
372 ret = -ESTALE;
373 goto out;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400374 }
375
376 inode->i_uid = make_kuid(&init_user_ns, new_op->
377 downcall.resp.getattr.attributes.owner);
378 inode->i_gid = make_kgid(&init_user_ns, new_op->
379 downcall.resp.getattr.attributes.group);
380 inode->i_atime.tv_sec = (time64_t)new_op->
381 downcall.resp.getattr.attributes.atime;
382 inode->i_mtime.tv_sec = (time64_t)new_op->
383 downcall.resp.getattr.attributes.mtime;
384 inode->i_ctime.tv_sec = (time64_t)new_op->
385 downcall.resp.getattr.attributes.ctime;
386 inode->i_atime.tv_nsec = 0;
387 inode->i_mtime.tv_nsec = 0;
388 inode->i_ctime.tv_nsec = 0;
389
390 /* special case: mark the root inode as sticky */
Martin Brandenburg26662632016-03-17 16:01:52 -0400391 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400392 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
393
Martin Brandenburg1d503612016-08-16 11:38:14 -0400394 orangefs_inode->getattr_time = jiffies +
395 orangefs_getattr_timeout_msecs*HZ/1000;
Martin Brandenburg68a24a62017-04-25 15:38:03 -0400396 if (request_mask & STATX_SIZE || new)
397 orangefs_inode->getattr_mask = STATX_BASIC_STATS;
398 else
399 orangefs_inode->getattr_mask = STATX_BASIC_STATS & ~STATX_SIZE;
Martin Brandenburg3c9cf982016-03-15 11:28:20 -0400400 ret = 0;
401out:
402 op_release(new_op);
403 return ret;
404}
405
Martin Brandenburg5859d772016-03-17 15:15:16 -0400406int orangefs_inode_check_changed(struct inode *inode)
407{
408 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
409 struct orangefs_kernel_op_s *new_op;
410 int ret;
411
412 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
413 get_khandle_from_ino(inode));
414
415 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
416 if (!new_op)
417 return -ENOMEM;
418 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
419 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE |
420 ORANGEFS_ATTR_SYS_LNK_TARGET;
421
422 ret = service_operation(new_op, __func__,
423 get_interruptible_flag(inode));
424 if (ret != 0)
425 goto out;
426
Martin Brandenburg480e5ae2018-02-06 14:01:25 +0000427 ret = orangefs_inode_is_stale(inode,
Martin Brandenburg26662632016-03-17 16:01:52 -0400428 &new_op->downcall.resp.getattr.attributes,
429 new_op->downcall.resp.getattr.link_target);
Martin Brandenburg5859d772016-03-17 15:15:16 -0400430out:
431 op_release(new_op);
432 return ret;
433}
434
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400435/*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500436 * issues a orangefs setattr request to make sure the new attribute values
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400437 * take effect if successful. returns 0 on success; -errno otherwise
438 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500439int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400440{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500441 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
442 struct orangefs_kernel_op_s *new_op;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400443 int ret;
444
Yi Liu8bb8aef2015-11-24 15:12:14 -0500445 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400446 if (!new_op)
447 return -ENOMEM;
448
Yi Liu8bb8aef2015-11-24 15:12:14 -0500449 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400450 ret = copy_attributes_from_inode(inode,
451 &new_op->upcall.req.setattr.attributes,
452 iattr);
Al Viroed42fe02016-01-22 19:47:47 -0500453 if (ret >= 0) {
454 ret = service_operation(new_op, __func__,
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400455 get_interruptible_flag(inode));
456
Al Viroed42fe02016-01-22 19:47:47 -0500457 gossip_debug(GOSSIP_UTILS_DEBUG,
458 "orangefs_inode_setattr: returning %d\n",
459 ret);
460 }
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400461
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400462 op_release(new_op);
463
Martin Brandenburga55f2d82017-11-07 15:01:40 -0500464 if (ret == 0)
Martin Brandenburg8bbb20a2016-07-28 14:46:36 -0400465 orangefs_inode->getattr_time = jiffies - 1;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400466
467 return ret;
468}
469
Mike Marshall54804942015-10-05 13:44:24 -0400470/*
471 * The following is a very dirty hack that is now a permanent part of the
Yi Liu8bb8aef2015-11-24 15:12:14 -0500472 * ORANGEFS protocol. See protocol.h for more error definitions.
Mike Marshall54804942015-10-05 13:44:24 -0400473 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400474
Yi Liu8bb8aef2015-11-24 15:12:14 -0500475/* The order matches include/orangefs-types.h in the OrangeFS source. */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400476static int PINT_errno_mapping[] = {
Mike Marshall54804942015-10-05 13:44:24 -0400477 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
478 EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
479 EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
480 ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
481 EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
482 EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
483 ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
484 EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
485 ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
486 EACCES, ECONNRESET, ERANGE
Martin Brandenburg894ac432015-10-02 12:11:19 -0400487};
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400488
Yi Liu8bb8aef2015-11-24 15:12:14 -0500489int orangefs_normalize_to_errno(__s32 error_code)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400490{
Mike Marshall54804942015-10-05 13:44:24 -0400491 __u32 i;
492
Martin Brandenburg894ac432015-10-02 12:11:19 -0400493 /* Success */
494 if (error_code == 0) {
495 return 0;
Mike Marshall54804942015-10-05 13:44:24 -0400496 /*
497 * This shouldn't ever happen. If it does it should be fixed on the
498 * server.
499 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400500 } else if (error_code > 0) {
Masanari Iidabc8282a2018-01-16 00:18:36 +0900501 gossip_err("orangefs: error status received.\n");
Yi Liu8bb8aef2015-11-24 15:12:14 -0500502 gossip_err("orangefs: assuming error code is inverted.\n");
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400503 error_code = -error_code;
504 }
505
Mike Marshall54804942015-10-05 13:44:24 -0400506 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500507 * XXX: This is very bad since error codes from ORANGEFS may not be
Mike Marshall54804942015-10-05 13:44:24 -0400508 * suitable for return into userspace.
509 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400510
Mike Marshall54804942015-10-05 13:44:24 -0400511 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500512 * Convert ORANGEFS error values into errno values suitable for return
Mike Marshall54804942015-10-05 13:44:24 -0400513 * from the kernel.
514 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500515 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
Martin Brandenburg894ac432015-10-02 12:11:19 -0400516 if (((-error_code) &
Yi Liu8bb8aef2015-11-24 15:12:14 -0500517 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
518 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400519 /*
520 * cancellation error codes generally correspond to
521 * a timeout from the client's perspective
522 */
523 error_code = -ETIMEDOUT;
524 } else {
525 /* assume a default error code */
Mike Marshall95f5f882018-05-11 17:11:48 -0400526 gossip_err("%s: bad error code :%d:.\n",
527 __func__,
528 error_code);
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400529 error_code = -EINVAL;
530 }
Martin Brandenburg894ac432015-10-02 12:11:19 -0400531
Yi Liu8bb8aef2015-11-24 15:12:14 -0500532 /* Convert ORANGEFS encoded errno values into regular errno values. */
533 } else if ((-error_code) & ORANGEFS_ERROR_BIT) {
534 i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS);
Jérémy Lefaure296200d2017-10-01 15:30:48 -0400535 if (i < ARRAY_SIZE(PINT_errno_mapping))
Martin Brandenburg894ac432015-10-02 12:11:19 -0400536 error_code = -PINT_errno_mapping[i];
537 else
538 error_code = -EINVAL;
539
Mike Marshall54804942015-10-05 13:44:24 -0400540 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500541 * Only ORANGEFS protocol error codes should ever come here. Otherwise
Mike Marshall54804942015-10-05 13:44:24 -0400542 * there is a bug somewhere.
543 */
Martin Brandenburg894ac432015-10-02 12:11:19 -0400544 } else {
Mike Marshall95f5f882018-05-11 17:11:48 -0400545 gossip_err("%s: unknown error code.\n", __func__);
Mike Marshallcf546ab2018-01-25 14:43:28 -0500546 error_code = -EINVAL;
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400547 }
548 return error_code;
549}
550
551#define NUM_MODES 11
Yi Liu8bb8aef2015-11-24 15:12:14 -0500552__s32 ORANGEFS_util_translate_mode(int mode)
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400553{
554 int ret = 0;
555 int i = 0;
556 static int modes[NUM_MODES] = {
557 S_IXOTH, S_IWOTH, S_IROTH,
558 S_IXGRP, S_IWGRP, S_IRGRP,
559 S_IXUSR, S_IWUSR, S_IRUSR,
560 S_ISGID, S_ISUID
561 };
Yi Liu8bb8aef2015-11-24 15:12:14 -0500562 static int orangefs_modes[NUM_MODES] = {
563 ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ,
564 ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ,
565 ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ,
566 ORANGEFS_G_SGID, ORANGEFS_U_SUID
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400567 };
568
569 for (i = 0; i < NUM_MODES; i++)
570 if (mode & modes[i])
Yi Liu8bb8aef2015-11-24 15:12:14 -0500571 ret |= orangefs_modes[i];
Mike Marshallf7be4ee2015-07-17 10:38:14 -0400572
573 return ret;
574}
575#undef NUM_MODES