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