]> Git Repo - linux.git/blame_incremental - fs/orangefs/orangefs-utils.c
orangefs: remove orangefs_readpages
[linux.git] / fs / orangefs / orangefs-utils.c
... / ...
CommitLineData
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * (C) 2001 Clemson University and The University of Chicago
4 * Copyright 2018 Omnibond Systems, L.L.C.
5 *
6 * See COPYING in top-level directory.
7 */
8#include <linux/kernel.h>
9#include "protocol.h"
10#include "orangefs-kernel.h"
11#include "orangefs-dev-proto.h"
12#include "orangefs-bufmap.h"
13
14__s32 fsid_of_op(struct orangefs_kernel_op_s *op)
15{
16 __s32 fsid = ORANGEFS_FS_ID_NULL;
17
18 if (op) {
19 switch (op->upcall.type) {
20 case ORANGEFS_VFS_OP_FILE_IO:
21 fsid = op->upcall.req.io.refn.fs_id;
22 break;
23 case ORANGEFS_VFS_OP_LOOKUP:
24 fsid = op->upcall.req.lookup.parent_refn.fs_id;
25 break;
26 case ORANGEFS_VFS_OP_CREATE:
27 fsid = op->upcall.req.create.parent_refn.fs_id;
28 break;
29 case ORANGEFS_VFS_OP_GETATTR:
30 fsid = op->upcall.req.getattr.refn.fs_id;
31 break;
32 case ORANGEFS_VFS_OP_REMOVE:
33 fsid = op->upcall.req.remove.parent_refn.fs_id;
34 break;
35 case ORANGEFS_VFS_OP_MKDIR:
36 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
37 break;
38 case ORANGEFS_VFS_OP_READDIR:
39 fsid = op->upcall.req.readdir.refn.fs_id;
40 break;
41 case ORANGEFS_VFS_OP_SETATTR:
42 fsid = op->upcall.req.setattr.refn.fs_id;
43 break;
44 case ORANGEFS_VFS_OP_SYMLINK:
45 fsid = op->upcall.req.sym.parent_refn.fs_id;
46 break;
47 case ORANGEFS_VFS_OP_RENAME:
48 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
49 break;
50 case ORANGEFS_VFS_OP_STATFS:
51 fsid = op->upcall.req.statfs.fs_id;
52 break;
53 case ORANGEFS_VFS_OP_TRUNCATE:
54 fsid = op->upcall.req.truncate.refn.fs_id;
55 break;
56 case ORANGEFS_VFS_OP_RA_FLUSH:
57 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
58 break;
59 case ORANGEFS_VFS_OP_FS_UMOUNT:
60 fsid = op->upcall.req.fs_umount.fs_id;
61 break;
62 case ORANGEFS_VFS_OP_GETXATTR:
63 fsid = op->upcall.req.getxattr.refn.fs_id;
64 break;
65 case ORANGEFS_VFS_OP_SETXATTR:
66 fsid = op->upcall.req.setxattr.refn.fs_id;
67 break;
68 case ORANGEFS_VFS_OP_LISTXATTR:
69 fsid = op->upcall.req.listxattr.refn.fs_id;
70 break;
71 case ORANGEFS_VFS_OP_REMOVEXATTR:
72 fsid = op->upcall.req.removexattr.refn.fs_id;
73 break;
74 case ORANGEFS_VFS_OP_FSYNC:
75 fsid = op->upcall.req.fsync.refn.fs_id;
76 break;
77 default:
78 break;
79 }
80 }
81 return fsid;
82}
83
84static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
85{
86 int flags = 0;
87 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
88 flags |= S_IMMUTABLE;
89 else
90 flags &= ~S_IMMUTABLE;
91 if (attrs->flags & ORANGEFS_APPEND_FL)
92 flags |= S_APPEND;
93 else
94 flags &= ~S_APPEND;
95 if (attrs->flags & ORANGEFS_NOATIME_FL)
96 flags |= S_NOATIME;
97 else
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;
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;
133}
134
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 */
139static inline void copy_attributes_from_inode(struct inode *inode,
140 struct ORANGEFS_sys_attr_s *attrs)
141{
142 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
143 attrs->mask = 0;
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);
148 }
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);
153 }
154
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;
160 }
161 }
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;
167 }
168 }
169 if (orangefs_inode->attr_valid & ATTR_CTIME)
170 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
171
172 /*
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
176 */
177
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;
181 }
182}
183
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
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
215static int orangefs_inode_is_stale(struct inode *inode,
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);
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;
232 }
233 return 0;
234}
235
236int orangefs_inode_getattr(struct inode *inode, int flags)
237{
238 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
239 struct orangefs_kernel_op_s *new_op;
240 loff_t inode_size;
241 int ret, type;
242
243 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU flags %d\n",
244 __func__, get_khandle_from_ino(inode), flags);
245
246again:
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) {
251 if (orangefs_inode->attr_valid) {
252 spin_unlock(&inode->i_lock);
253 write_inode_now(inode, 1);
254 goto again;
255 }
256 spin_unlock(&inode->i_lock);
257 return 0;
258 }
259 spin_unlock(&inode->i_lock);
260
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;
265 /*
266 * Size is the hardest attribute to get. The incremental cost of any
267 * other attribute is essentially zero.
268 */
269 if (flags)
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;
274
275 ret = service_operation(new_op, __func__,
276 get_interruptible_flag(inode));
277 if (ret != 0)
278 goto out;
279
280again2:
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) {
285 if (orangefs_inode->attr_valid) {
286 spin_unlock(&inode->i_lock);
287 write_inode_now(inode, 1);
288 goto again2;
289 }
290 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: in cache or dirty\n",
291 __func__);
292 ret = 0;
293 goto out_unlock;
294 }
295
296 if (!(flags & ORANGEFS_GETATTR_NEW)) {
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;
302 goto out_unlock;
303 }
304 }
305
306 type = orangefs_inode_type(new_op->
307 downcall.resp.getattr.attributes.objtype);
308 switch (type) {
309 case S_IFREG:
310 inode->i_flags = orangefs_inode_flags(&new_op->
311 downcall.resp.getattr.attributes);
312 if (flags) {
313 inode_size = (loff_t)new_op->
314 downcall.resp.getattr.attributes.size;
315 inode->i_size = inode_size;
316 inode->i_blkbits = ffs(new_op->downcall.resp.getattr.
317 attributes.blksize);
318 inode->i_bytes = inode_size;
319 inode->i_blocks =
320 (inode_size + 512 - inode_size % 512)/512;
321 }
322 break;
323 case S_IFDIR:
324 if (flags) {
325 inode->i_size = PAGE_SIZE;
326 inode_set_bytes(inode, inode->i_size);
327 }
328 set_nlink(inode, 1);
329 break;
330 case S_IFLNK:
331 if (flags & ORANGEFS_GETATTR_NEW) {
332 inode->i_size = (loff_t)strlen(new_op->
333 downcall.resp.getattr.link_target);
334 ret = strscpy(orangefs_inode->link_target,
335 new_op->downcall.resp.getattr.link_target,
336 ORANGEFS_NAME_MAX);
337 if (ret == -E2BIG) {
338 ret = -EIO;
339 goto out_unlock;
340 }
341 inode->i_link = orangefs_inode->link_target;
342 }
343 break;
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;
349 goto out_unlock;
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 */
367 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
368 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
369
370 orangefs_inode->getattr_time = jiffies +
371 orangefs_getattr_timeout_msecs*HZ/1000;
372 ret = 0;
373out_unlock:
374 spin_unlock(&inode->i_lock);
375out:
376 op_release(new_op);
377 return ret;
378}
379
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
401 ret = orangefs_inode_is_stale(inode,
402 &new_op->downcall.resp.getattr.attributes,
403 new_op->downcall.resp.getattr.link_target);
404out:
405 op_release(new_op);
406 return ret;
407}
408
409/*
410 * issues a orangefs setattr request to make sure the new attribute values
411 * take effect if successful. returns 0 on success; -errno otherwise
412 */
413int orangefs_inode_setattr(struct inode *inode)
414{
415 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
416 struct orangefs_kernel_op_s *new_op;
417 int ret;
418
419 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
420 if (!new_op)
421 return -ENOMEM;
422
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);
426 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
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);
431
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);
438
439 op_release(new_op);
440
441 if (ret == 0)
442 orangefs_inode->getattr_time = jiffies - 1;
443 return ret;
444}
445
446/*
447 * The following is a very dirty hack that is now a permanent part of the
448 * ORANGEFS protocol. See protocol.h for more error definitions.
449 */
450
451/* The order matches include/orangefs-types.h in the OrangeFS source. */
452static int PINT_errno_mapping[] = {
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
463};
464
465int orangefs_normalize_to_errno(__s32 error_code)
466{
467 __u32 i;
468
469 /* Success */
470 if (error_code == 0) {
471 return 0;
472 /*
473 * This shouldn't ever happen. If it does it should be fixed on the
474 * server.
475 */
476 } else if (error_code > 0) {
477 gossip_err("orangefs: error status received.\n");
478 gossip_err("orangefs: assuming error code is inverted.\n");
479 error_code = -error_code;
480 }
481
482 /*
483 * XXX: This is very bad since error codes from ORANGEFS may not be
484 * suitable for return into userspace.
485 */
486
487 /*
488 * Convert ORANGEFS error values into errno values suitable for return
489 * from the kernel.
490 */
491 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
492 if (((-error_code) &
493 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
494 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
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 */
502 gossip_err("%s: bad error code :%d:.\n",
503 __func__,
504 error_code);
505 error_code = -EINVAL;
506 }
507
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);
511 if (i < ARRAY_SIZE(PINT_errno_mapping))
512 error_code = -PINT_errno_mapping[i];
513 else
514 error_code = -EINVAL;
515
516 /*
517 * Only ORANGEFS protocol error codes should ever come here. Otherwise
518 * there is a bug somewhere.
519 */
520 } else {
521 gossip_err("%s: unknown error code.\n", __func__);
522 error_code = -EINVAL;
523 }
524 return error_code;
525}
526
527#define NUM_MODES 11
528__s32 ORANGEFS_util_translate_mode(int mode)
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 };
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
543 };
544
545 for (i = 0; i < NUM_MODES; i++)
546 if (mode & modes[i])
547 ret |= orangefs_modes[i];
548
549 return ret;
550}
551#undef NUM_MODES
This page took 0.028834 seconds and 4 git commands to generate.