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