]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/orangefs/orangefs-utils.c
orangefs: remove needless wrapper around GFP_KERNEL
[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;
8bb8aefd 53 case ORANGEFS_VFS_OP_MMAP_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) {
156 attrs->owner = from_kuid(current_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) {
161 attrs->group = from_kgid(current_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
3c9cf98d
MB
254int orangefs_inode_getattr(struct inode *inode, int new, int size)
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
264 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
265 if (!new_op)
266 return -ENOMEM;
267 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
268 new_op->upcall.req.getattr.mask = size ?
269 ORANGEFS_ATTR_SYS_ALL_NOHINT : ORANGEFS_ATTR_SYS_ALL_NOHINT_NOSIZE;
270
271 ret = service_operation(new_op, __func__,
272 get_interruptible_flag(inode));
273 if (ret != 0)
274 goto out;
275
26662633 276 type = orangefs_inode_type(new_op->
3c9cf98d 277 downcall.resp.getattr.attributes.objtype);
26662633
MB
278 ret = orangefs_inode_is_stale(inode, new,
279 &new_op->downcall.resp.getattr.attributes,
280 new_op->downcall.resp.getattr.link_target);
281 if (ret) {
282 ret = -ESTALE;
283 goto out;
3c9cf98d
MB
284 }
285
26662633 286 switch (type) {
3c9cf98d
MB
287 case S_IFREG:
288 inode->i_flags = orangefs_inode_flags(&new_op->
289 downcall.resp.getattr.attributes);
290 if (size) {
291 inode_size = (loff_t)new_op->
292 downcall.resp.getattr.attributes.size;
293 rounded_up_size =
294 (inode_size + (4096 - (inode_size % 4096)));
295 inode->i_size = inode_size;
296 orangefs_inode->blksize =
297 new_op->downcall.resp.getattr.attributes.blksize;
298 spin_lock(&inode->i_lock);
299 inode->i_bytes = inode_size;
300 inode->i_blocks =
301 (unsigned long)(rounded_up_size / 512);
302 spin_unlock(&inode->i_lock);
303 }
304 break;
305 case S_IFDIR:
306 inode->i_size = PAGE_CACHE_SIZE;
307 orangefs_inode->blksize = (1 << inode->i_blkbits);
308 spin_lock(&inode->i_lock);
309 inode_set_bytes(inode, inode->i_size);
310 spin_unlock(&inode->i_lock);
311 set_nlink(inode, 1);
312 break;
313 case S_IFLNK:
314 if (new) {
315 inode->i_size = (loff_t)strlen(new_op->
316 downcall.resp.getattr.link_target);
317 orangefs_inode->blksize = (1 << inode->i_blkbits);
318 strlcpy(orangefs_inode->link_target,
319 new_op->downcall.resp.getattr.link_target,
320 ORANGEFS_NAME_MAX);
321 }
322 break;
323 }
324
325 inode->i_uid = make_kuid(&init_user_ns, new_op->
326 downcall.resp.getattr.attributes.owner);
327 inode->i_gid = make_kgid(&init_user_ns, new_op->
328 downcall.resp.getattr.attributes.group);
329 inode->i_atime.tv_sec = (time64_t)new_op->
330 downcall.resp.getattr.attributes.atime;
331 inode->i_mtime.tv_sec = (time64_t)new_op->
332 downcall.resp.getattr.attributes.mtime;
333 inode->i_ctime.tv_sec = (time64_t)new_op->
334 downcall.resp.getattr.attributes.ctime;
335 inode->i_atime.tv_nsec = 0;
336 inode->i_mtime.tv_nsec = 0;
337 inode->i_ctime.tv_nsec = 0;
338
339 /* special case: mark the root inode as sticky */
26662633 340 inode->i_mode = type | (is_root_handle(inode) ? S_ISVTX : 0) |
3c9cf98d
MB
341 orangefs_inode_perms(&new_op->downcall.resp.getattr.attributes);
342
343 ret = 0;
344out:
345 op_release(new_op);
346 return ret;
347}
348
5859d77e
MB
349int orangefs_inode_check_changed(struct inode *inode)
350{
351 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
352 struct orangefs_kernel_op_s *new_op;
353 int ret;
354
355 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
356 get_khandle_from_ino(inode));
357
358 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
359 if (!new_op)
360 return -ENOMEM;
361 new_op->upcall.req.getattr.refn = orangefs_inode->refn;
362 new_op->upcall.req.getattr.mask = ORANGEFS_ATTR_SYS_TYPE |
363 ORANGEFS_ATTR_SYS_LNK_TARGET;
364
365 ret = service_operation(new_op, __func__,
366 get_interruptible_flag(inode));
367 if (ret != 0)
368 goto out;
369
26662633
MB
370 ret = orangefs_inode_is_stale(inode, 0,
371 &new_op->downcall.resp.getattr.attributes,
372 new_op->downcall.resp.getattr.link_target);
5859d77e
MB
373out:
374 op_release(new_op);
375 return ret;
376}
377
f7be4ee0 378/*
8bb8aefd 379 * issues a orangefs setattr request to make sure the new attribute values
f7be4ee0
MM
380 * take effect if successful. returns 0 on success; -errno otherwise
381 */
8bb8aefd 382int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
f7be4ee0 383{
8bb8aefd
YL
384 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
385 struct orangefs_kernel_op_s *new_op;
f7be4ee0
MM
386 int ret;
387
8bb8aefd 388 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
f7be4ee0
MM
389 if (!new_op)
390 return -ENOMEM;
391
8bb8aefd 392 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
f7be4ee0
MM
393 ret = copy_attributes_from_inode(inode,
394 &new_op->upcall.req.setattr.attributes,
395 iattr);
ed42fe05
AV
396 if (ret >= 0) {
397 ret = service_operation(new_op, __func__,
f7be4ee0
MM
398 get_interruptible_flag(inode));
399
ed42fe05
AV
400 gossip_debug(GOSSIP_UTILS_DEBUG,
401 "orangefs_inode_setattr: returning %d\n",
402 ret);
403 }
f7be4ee0 404
f7be4ee0
MM
405 op_release(new_op);
406
407 /*
408 * successful setattr should clear the atime, mtime and
409 * ctime flags.
410 */
411 if (ret == 0) {
8bb8aefd
YL
412 ClearAtimeFlag(orangefs_inode);
413 ClearMtimeFlag(orangefs_inode);
414 ClearCtimeFlag(orangefs_inode);
415 ClearModeFlag(orangefs_inode);
f7be4ee0
MM
416 }
417
418 return ret;
419}
420
8bb8aefd 421int orangefs_flush_inode(struct inode *inode)
f7be4ee0
MM
422{
423 /*
424 * If it is a dirty inode, this function gets called.
425 * Gather all the information that needs to be setattr'ed
426 * Right now, this will only be used for mode, atime, mtime
427 * and/or ctime.
428 */
429 struct iattr wbattr;
430 int ret;
431 int mtime_flag;
432 int ctime_flag;
433 int atime_flag;
434 int mode_flag;
8bb8aefd 435 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
f7be4ee0
MM
436
437 memset(&wbattr, 0, sizeof(wbattr));
438
439 /*
440 * check inode flags up front, and clear them if they are set. This
441 * will prevent multiple processes from all trying to flush the same
442 * inode if they call close() simultaneously
443 */
8bb8aefd
YL
444 mtime_flag = MtimeFlag(orangefs_inode);
445 ClearMtimeFlag(orangefs_inode);
446 ctime_flag = CtimeFlag(orangefs_inode);
447 ClearCtimeFlag(orangefs_inode);
448 atime_flag = AtimeFlag(orangefs_inode);
449 ClearAtimeFlag(orangefs_inode);
450 mode_flag = ModeFlag(orangefs_inode);
451 ClearModeFlag(orangefs_inode);
f7be4ee0
MM
452
453 /* -- Lazy atime,mtime and ctime update --
454 * Note: all times are dictated by server in the new scheme
455 * and not by the clients
456 *
457 * Also mode updates are being handled now..
458 */
459
460 if (mtime_flag)
461 wbattr.ia_valid |= ATTR_MTIME;
462 if (ctime_flag)
463 wbattr.ia_valid |= ATTR_CTIME;
464 if (atime_flag)
465 wbattr.ia_valid |= ATTR_ATIME;
466
467 if (mode_flag) {
468 wbattr.ia_mode = inode->i_mode;
469 wbattr.ia_valid |= ATTR_MODE;
470 }
471
472 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd 473 "*********** orangefs_flush_inode: %pU "
f7be4ee0
MM
474 "(ia_valid %d)\n",
475 get_khandle_from_ino(inode),
476 wbattr.ia_valid);
477 if (wbattr.ia_valid == 0) {
478 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd 479 "orangefs_flush_inode skipping setattr()\n");
f7be4ee0
MM
480 return 0;
481 }
482
483 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd 484 "orangefs_flush_inode (%pU) writing mode %o\n",
f7be4ee0
MM
485 get_khandle_from_ino(inode),
486 inode->i_mode);
487
8bb8aefd 488 ret = orangefs_inode_setattr(inode, &wbattr);
f7be4ee0
MM
489
490 return ret;
491}
492
8bb8aefd 493int orangefs_unmount_sb(struct super_block *sb)
f7be4ee0
MM
494{
495 int ret = -EINVAL;
8bb8aefd 496 struct orangefs_kernel_op_s *new_op = NULL;
f7be4ee0
MM
497
498 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd 499 "orangefs_unmount_sb called on sb %p\n",
f7be4ee0
MM
500 sb);
501
8bb8aefd 502 new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT);
f7be4ee0
MM
503 if (!new_op)
504 return -ENOMEM;
8bb8aefd
YL
505 new_op->upcall.req.fs_umount.id = ORANGEFS_SB(sb)->id;
506 new_op->upcall.req.fs_umount.fs_id = ORANGEFS_SB(sb)->fs_id;
507 strncpy(new_op->upcall.req.fs_umount.orangefs_config_server,
508 ORANGEFS_SB(sb)->devname,
509 ORANGEFS_MAX_SERVER_ADDR_LEN);
f7be4ee0
MM
510
511 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd
YL
512 "Attempting ORANGEFS Unmount via host %s\n",
513 new_op->upcall.req.fs_umount.orangefs_config_server);
f7be4ee0 514
8bb8aefd 515 ret = service_operation(new_op, "orangefs_fs_umount", 0);
f7be4ee0
MM
516
517 gossip_debug(GOSSIP_UTILS_DEBUG,
8bb8aefd 518 "orangefs_unmount: got return value of %d\n", ret);
f7be4ee0
MM
519 if (ret)
520 sb = ERR_PTR(ret);
521 else
8bb8aefd 522 ORANGEFS_SB(sb)->mount_pending = 1;
f7be4ee0
MM
523
524 op_release(new_op);
525 return ret;
526}
527
8bb8aefd 528void orangefs_make_bad_inode(struct inode *inode)
f7be4ee0
MM
529{
530 if (is_root_handle(inode)) {
531 /*
532 * if this occurs, the pvfs2-client-core was killed but we
533 * can't afford to lose the inode operations and such
534 * associated with the root handle in any case.
535 */
536 gossip_debug(GOSSIP_UTILS_DEBUG,
537 "*** NOT making bad root inode %pU\n",
538 get_khandle_from_ino(inode));
539 } else {
540 gossip_debug(GOSSIP_UTILS_DEBUG,
541 "*** making bad inode %pU\n",
542 get_khandle_from_ino(inode));
543 make_bad_inode(inode);
544 }
545}
546
54804949
MM
547/*
548 * The following is a very dirty hack that is now a permanent part of the
8bb8aefd 549 * ORANGEFS protocol. See protocol.h for more error definitions.
54804949 550 */
894ac432 551
8bb8aefd 552/* The order matches include/orangefs-types.h in the OrangeFS source. */
894ac432 553static int PINT_errno_mapping[] = {
54804949
MM
554 0, EPERM, ENOENT, EINTR, EIO, ENXIO, EBADF, EAGAIN, ENOMEM,
555 EFAULT, EBUSY, EEXIST, ENODEV, ENOTDIR, EISDIR, EINVAL, EMFILE,
556 EFBIG, ENOSPC, EROFS, EMLINK, EPIPE, EDEADLK, ENAMETOOLONG,
557 ENOLCK, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK, ENOMSG, EUNATCH,
558 EBADR, EDEADLOCK, ENODATA, ETIME, ENONET, EREMOTE, ECOMM,
559 EPROTO, EBADMSG, EOVERFLOW, ERESTART, EMSGSIZE, EPROTOTYPE,
560 ENOPROTOOPT, EPROTONOSUPPORT, EOPNOTSUPP, EADDRINUSE,
561 EADDRNOTAVAIL, ENETDOWN, ENETUNREACH, ENETRESET, ENOBUFS,
562 ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY,
563 EACCES, ECONNRESET, ERANGE
894ac432 564};
f7be4ee0 565
8bb8aefd 566int orangefs_normalize_to_errno(__s32 error_code)
f7be4ee0 567{
54804949
MM
568 __u32 i;
569
894ac432
MB
570 /* Success */
571 if (error_code == 0) {
572 return 0;
54804949
MM
573 /*
574 * This shouldn't ever happen. If it does it should be fixed on the
575 * server.
576 */
894ac432 577 } else if (error_code > 0) {
8bb8aefd
YL
578 gossip_err("orangefs: error status receieved.\n");
579 gossip_err("orangefs: assuming error code is inverted.\n");
f7be4ee0
MM
580 error_code = -error_code;
581 }
582
54804949 583 /*
8bb8aefd 584 * XXX: This is very bad since error codes from ORANGEFS may not be
54804949
MM
585 * suitable for return into userspace.
586 */
894ac432 587
54804949 588 /*
8bb8aefd 589 * Convert ORANGEFS error values into errno values suitable for return
54804949
MM
590 * from the kernel.
591 */
8bb8aefd 592 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
894ac432 593 if (((-error_code) &
8bb8aefd
YL
594 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
595 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
f7be4ee0
MM
596 /*
597 * cancellation error codes generally correspond to
598 * a timeout from the client's perspective
599 */
600 error_code = -ETIMEDOUT;
601 } else {
602 /* assume a default error code */
8bb8aefd 603 gossip_err("orangefs: warning: got error code without errno equivalent: %d.\n", error_code);
f7be4ee0
MM
604 error_code = -EINVAL;
605 }
894ac432 606
8bb8aefd
YL
607 /* Convert ORANGEFS encoded errno values into regular errno values. */
608 } else if ((-error_code) & ORANGEFS_ERROR_BIT) {
609 i = (-error_code) & ~(ORANGEFS_ERROR_BIT|ORANGEFS_ERROR_CLASS_BITS);
54804949 610 if (i < sizeof(PINT_errno_mapping)/sizeof(*PINT_errno_mapping))
894ac432
MB
611 error_code = -PINT_errno_mapping[i];
612 else
613 error_code = -EINVAL;
614
54804949 615 /*
8bb8aefd 616 * Only ORANGEFS protocol error codes should ever come here. Otherwise
54804949
MM
617 * there is a bug somewhere.
618 */
894ac432 619 } else {
8bb8aefd 620 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
f7be4ee0
MM
621 }
622 return error_code;
623}
624
625#define NUM_MODES 11
8bb8aefd 626__s32 ORANGEFS_util_translate_mode(int mode)
f7be4ee0
MM
627{
628 int ret = 0;
629 int i = 0;
630 static int modes[NUM_MODES] = {
631 S_IXOTH, S_IWOTH, S_IROTH,
632 S_IXGRP, S_IWGRP, S_IRGRP,
633 S_IXUSR, S_IWUSR, S_IRUSR,
634 S_ISGID, S_ISUID
635 };
8bb8aefd
YL
636 static int orangefs_modes[NUM_MODES] = {
637 ORANGEFS_O_EXECUTE, ORANGEFS_O_WRITE, ORANGEFS_O_READ,
638 ORANGEFS_G_EXECUTE, ORANGEFS_G_WRITE, ORANGEFS_G_READ,
639 ORANGEFS_U_EXECUTE, ORANGEFS_U_WRITE, ORANGEFS_U_READ,
640 ORANGEFS_G_SGID, ORANGEFS_U_SUID
f7be4ee0
MM
641 };
642
643 for (i = 0; i < NUM_MODES; i++)
644 if (mode & modes[i])
8bb8aefd 645 ret |= orangefs_modes[i];
f7be4ee0
MM
646
647 return ret;
648}
649#undef NUM_MODES
650
651/*
652 * After obtaining a string representation of the client's debug
653 * keywords and their associated masks, this function is called to build an
654 * array of these values.
655 */
656int orangefs_prepare_cdm_array(char *debug_array_string)
657{
658 int i;
659 int rc = -EINVAL;
660 char *cds_head = NULL;
661 char *cds_delimiter = NULL;
662 int keyword_len = 0;
663
664 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
665
666 /*
667 * figure out how many elements the cdm_array needs.
668 */
669 for (i = 0; i < strlen(debug_array_string); i++)
670 if (debug_array_string[i] == '\n')
671 cdm_element_count++;
672
673 if (!cdm_element_count) {
674 pr_info("No elements in client debug array string!\n");
675 goto out;
676 }
677
678 cdm_array =
679 kzalloc(cdm_element_count * sizeof(struct client_debug_mask),
680 GFP_KERNEL);
681 if (!cdm_array) {
682 pr_info("malloc failed for cdm_array!\n");
683 rc = -ENOMEM;
684 goto out;
685 }
686
687 cds_head = debug_array_string;
688
689 for (i = 0; i < cdm_element_count; i++) {
690 cds_delimiter = strchr(cds_head, '\n');
691 *cds_delimiter = '\0';
692
693 keyword_len = strcspn(cds_head, " ");
694
695 cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL);
696 if (!cdm_array[i].keyword) {
697 rc = -ENOMEM;
698 goto out;
699 }
700
701 sscanf(cds_head,
702 "%s %llx %llx",
703 cdm_array[i].keyword,
704 (unsigned long long *)&(cdm_array[i].mask1),
705 (unsigned long long *)&(cdm_array[i].mask2));
706
8bb8aefd 707 if (!strcmp(cdm_array[i].keyword, ORANGEFS_VERBOSE))
f7be4ee0
MM
708 client_verbose_index = i;
709
8bb8aefd 710 if (!strcmp(cdm_array[i].keyword, ORANGEFS_ALL))
f7be4ee0
MM
711 client_all_index = i;
712
713 cds_head = cds_delimiter + 1;
714 }
715
716 rc = cdm_element_count;
717
718 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc);
719
720out:
721
722 return rc;
723
724}
725
726/*
727 * /sys/kernel/debug/orangefs/debug-help can be catted to
728 * see all the available kernel and client debug keywords.
729 *
730 * When the kernel boots, we have no idea what keywords the
731 * client supports, nor their associated masks.
732 *
733 * We pass through this function once at boot and stamp a
734 * boilerplate "we don't know" message for the client in the
735 * debug-help file. We pass through here again when the client
736 * starts and then we can fill out the debug-help file fully.
737 *
738 * The client might be restarted any number of times between
739 * reboots, we only build the debug-help file the first time.
740 */
741int orangefs_prepare_debugfs_help_string(int at_boot)
742{
743 int rc = -EINVAL;
744 int i;
745 int byte_count = 0;
746 char *client_title = "Client Debug Keywords:\n";
747 char *kernel_title = "Kernel Debug Keywords:\n";
748
749 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
750
751 if (at_boot) {
752 byte_count += strlen(HELP_STRING_UNINITIALIZED);
753 client_title = HELP_STRING_UNINITIALIZED;
754 } else {
755 /*
756 * fill the client keyword/mask array and remember
757 * how many elements there were.
758 */
759 cdm_element_count =
760 orangefs_prepare_cdm_array(client_debug_array_string);
761 if (cdm_element_count <= 0)
762 goto out;
763
764 /* Count the bytes destined for debug_help_string. */
765 byte_count += strlen(client_title);
766
767 for (i = 0; i < cdm_element_count; i++) {
768 byte_count += strlen(cdm_array[i].keyword + 2);
769 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
770 pr_info("%s: overflow 1!\n", __func__);
771 goto out;
772 }
773 }
774
775 gossip_debug(GOSSIP_UTILS_DEBUG,
776 "%s: cdm_element_count:%d:\n",
777 __func__,
778 cdm_element_count);
779 }
780
781 byte_count += strlen(kernel_title);
782 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
783 byte_count +=
784 strlen(s_kmod_keyword_mask_map[i].keyword + 2);
785 if (byte_count >= DEBUG_HELP_STRING_SIZE) {
786 pr_info("%s: overflow 2!\n", __func__);
787 goto out;
788 }
789 }
790
791 /* build debug_help_string. */
792 debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
793 if (!debug_help_string) {
794 rc = -ENOMEM;
795 goto out;
796 }
797
798 strcat(debug_help_string, client_title);
799
800 if (!at_boot) {
801 for (i = 0; i < cdm_element_count; i++) {
802 strcat(debug_help_string, "\t");
803 strcat(debug_help_string, cdm_array[i].keyword);
804 strcat(debug_help_string, "\n");
805 }
806 }
807
808 strcat(debug_help_string, "\n");
809 strcat(debug_help_string, kernel_title);
810
811 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
812 strcat(debug_help_string, "\t");
813 strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword);
814 strcat(debug_help_string, "\n");
815 }
816
817 rc = 0;
818
819out:
820
821 return rc;
822
823}
824
825/*
826 * kernel = type 0
827 * client = type 1
828 */
829void debug_mask_to_string(void *mask, int type)
830{
831 int i;
832 int len = 0;
833 char *debug_string;
834 int element_count = 0;
835
836 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
837
838 if (type) {
839 debug_string = client_debug_string;
840 element_count = cdm_element_count;
841 } else {
842 debug_string = kernel_debug_string;
843 element_count = num_kmod_keyword_mask_map;
844 }
845
8bb8aefd 846 memset(debug_string, 0, ORANGEFS_MAX_DEBUG_STRING_LEN);
f7be4ee0
MM
847
848 /*
849 * Some keywords, like "all" or "verbose", are amalgams of
850 * numerous other keywords. Make a special check for those
851 * before grinding through the whole mask only to find out
852 * later...
853 */
854 if (check_amalgam_keyword(mask, type))
855 goto out;
856
857 /* Build the debug string. */
858 for (i = 0; i < element_count; i++)
859 if (type)
860 do_c_string(mask, i);
861 else
862 do_k_string(mask, i);
863
864 len = strlen(debug_string);
865
866 if ((len) && (type))
867 client_debug_string[len - 1] = '\0';
868 else if (len)
869 kernel_debug_string[len - 1] = '\0';
870 else if (type)
871 strcpy(client_debug_string, "none");
872 else
873 strcpy(kernel_debug_string, "none");
874
875out:
876gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string);
877
878 return;
879
880}
881
882void do_k_string(void *k_mask, int index)
883{
884 __u64 *mask = (__u64 *) k_mask;
885
886 if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword))
54804949 887 goto out;
f7be4ee0
MM
888
889 if (*mask & s_kmod_keyword_mask_map[index].mask_val) {
890 if ((strlen(kernel_debug_string) +
891 strlen(s_kmod_keyword_mask_map[index].keyword))
8bb8aefd 892 < ORANGEFS_MAX_DEBUG_STRING_LEN - 1) {
f7be4ee0
MM
893 strcat(kernel_debug_string,
894 s_kmod_keyword_mask_map[index].keyword);
895 strcat(kernel_debug_string, ",");
896 } else {
897 gossip_err("%s: overflow!\n", __func__);
8bb8aefd 898 strcpy(kernel_debug_string, ORANGEFS_ALL);
f7be4ee0
MM
899 goto out;
900 }
901 }
902
903out:
904
905 return;
906}
907
908void do_c_string(void *c_mask, int index)
909{
910 struct client_debug_mask *mask = (struct client_debug_mask *) c_mask;
911
912 if (keyword_is_amalgam(cdm_array[index].keyword))
913 goto out;
914
915 if ((mask->mask1 & cdm_array[index].mask1) ||
916 (mask->mask2 & cdm_array[index].mask2)) {
917 if ((strlen(client_debug_string) +
918 strlen(cdm_array[index].keyword) + 1)
8bb8aefd 919 < ORANGEFS_MAX_DEBUG_STRING_LEN - 2) {
f7be4ee0
MM
920 strcat(client_debug_string,
921 cdm_array[index].keyword);
922 strcat(client_debug_string, ",");
923 } else {
924 gossip_err("%s: overflow!\n", __func__);
8bb8aefd 925 strcpy(client_debug_string, ORANGEFS_ALL);
f7be4ee0
MM
926 goto out;
927 }
928 }
929out:
930 return;
931}
932
933int keyword_is_amalgam(char *keyword)
934{
935 int rc = 0;
936
8bb8aefd 937 if ((!strcmp(keyword, ORANGEFS_ALL)) || (!strcmp(keyword, ORANGEFS_VERBOSE)))
f7be4ee0
MM
938 rc = 1;
939
940 return rc;
941}
942
943/*
944 * kernel = type 0
945 * client = type 1
946 *
947 * return 1 if we found an amalgam.
948 */
949int check_amalgam_keyword(void *mask, int type)
950{
951 __u64 *k_mask;
952 struct client_debug_mask *c_mask;
953 int k_all_index = num_kmod_keyword_mask_map - 1;
954 int rc = 0;
955
956 if (type) {
957 c_mask = (struct client_debug_mask *) mask;
958
959 if ((c_mask->mask1 == cdm_array[client_all_index].mask1) &&
960 (c_mask->mask2 == cdm_array[client_all_index].mask2)) {
8bb8aefd 961 strcpy(client_debug_string, ORANGEFS_ALL);
f7be4ee0
MM
962 rc = 1;
963 goto out;
964 }
965
966 if ((c_mask->mask1 == cdm_array[client_verbose_index].mask1) &&
967 (c_mask->mask2 == cdm_array[client_verbose_index].mask2)) {
8bb8aefd 968 strcpy(client_debug_string, ORANGEFS_VERBOSE);
f7be4ee0
MM
969 rc = 1;
970 goto out;
971 }
972
973 } else {
974 k_mask = (__u64 *) mask;
975
976 if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) {
8bb8aefd 977 strcpy(kernel_debug_string, ORANGEFS_ALL);
f7be4ee0
MM
978 rc = 1;
979 goto out;
980 }
981 }
982
983out:
984
985 return rc;
986}
987
988/*
989 * kernel = type 0
990 * client = type 1
991 */
992void debug_string_to_mask(char *debug_string, void *mask, int type)
993{
994 char *unchecked_keyword;
995 int i;
996 char *strsep_fodder = kstrdup(debug_string, GFP_KERNEL);
eeaa3d44 997 char *original_pointer;
f7be4ee0
MM
998 int element_count = 0;
999 struct client_debug_mask *c_mask;
1000 __u64 *k_mask;
1001
1002 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
1003
1004 if (type) {
1005 c_mask = (struct client_debug_mask *)mask;
1006 element_count = cdm_element_count;
1007 } else {
1008 k_mask = (__u64 *)mask;
1009 *k_mask = 0;
1010 element_count = num_kmod_keyword_mask_map;
1011 }
1012
eeaa3d44 1013 original_pointer = strsep_fodder;
f7be4ee0
MM
1014 while ((unchecked_keyword = strsep(&strsep_fodder, ",")))
1015 if (strlen(unchecked_keyword)) {
1016 for (i = 0; i < element_count; i++)
1017 if (type)
1018 do_c_mask(i,
1019 unchecked_keyword,
1020 &c_mask);
1021 else
1022 do_k_mask(i,
1023 unchecked_keyword,
1024 &k_mask);
1025 }
1026
eeaa3d44 1027 kfree(original_pointer);
f7be4ee0
MM
1028}
1029
1030void do_c_mask(int i,
1031 char *unchecked_keyword,
1032 struct client_debug_mask **sane_mask)
1033{
1034
1035 if (!strcmp(cdm_array[i].keyword, unchecked_keyword)) {
1036 (**sane_mask).mask1 = (**sane_mask).mask1 | cdm_array[i].mask1;
1037 (**sane_mask).mask2 = (**sane_mask).mask2 | cdm_array[i].mask2;
1038 }
1039}
1040
1041void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask)
1042{
1043
1044 if (!strcmp(s_kmod_keyword_mask_map[i].keyword, unchecked_keyword))
1045 **sane_mask = (**sane_mask) |
1046 s_kmod_keyword_mask_map[i].mask_val;
1047}