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