2 * (C) 2001 Clemson University and The University of Chicago
4 * See COPYING in top-level directory.
7 #include "orangefs-kernel.h"
8 #include "orangefs-dev-proto.h"
9 #include "orangefs-bufmap.h"
11 __s32 fsid_of_op(struct orangefs_kernel_op_s *op)
13 __s32 fsid = ORANGEFS_FS_ID_NULL;
16 switch (op->upcall.type) {
17 case ORANGEFS_VFS_OP_FILE_IO:
18 fsid = op->upcall.req.io.refn.fs_id;
20 case ORANGEFS_VFS_OP_LOOKUP:
21 fsid = op->upcall.req.lookup.parent_refn.fs_id;
23 case ORANGEFS_VFS_OP_CREATE:
24 fsid = op->upcall.req.create.parent_refn.fs_id;
26 case ORANGEFS_VFS_OP_GETATTR:
27 fsid = op->upcall.req.getattr.refn.fs_id;
29 case ORANGEFS_VFS_OP_REMOVE:
30 fsid = op->upcall.req.remove.parent_refn.fs_id;
32 case ORANGEFS_VFS_OP_MKDIR:
33 fsid = op->upcall.req.mkdir.parent_refn.fs_id;
35 case ORANGEFS_VFS_OP_READDIR:
36 fsid = op->upcall.req.readdir.refn.fs_id;
38 case ORANGEFS_VFS_OP_SETATTR:
39 fsid = op->upcall.req.setattr.refn.fs_id;
41 case ORANGEFS_VFS_OP_SYMLINK:
42 fsid = op->upcall.req.sym.parent_refn.fs_id;
44 case ORANGEFS_VFS_OP_RENAME:
45 fsid = op->upcall.req.rename.old_parent_refn.fs_id;
47 case ORANGEFS_VFS_OP_STATFS:
48 fsid = op->upcall.req.statfs.fs_id;
50 case ORANGEFS_VFS_OP_TRUNCATE:
51 fsid = op->upcall.req.truncate.refn.fs_id;
53 case ORANGEFS_VFS_OP_MMAP_RA_FLUSH:
54 fsid = op->upcall.req.ra_cache_flush.refn.fs_id;
56 case ORANGEFS_VFS_OP_FS_UMOUNT:
57 fsid = op->upcall.req.fs_umount.fs_id;
59 case ORANGEFS_VFS_OP_GETXATTR:
60 fsid = op->upcall.req.getxattr.refn.fs_id;
62 case ORANGEFS_VFS_OP_SETXATTR:
63 fsid = op->upcall.req.setxattr.refn.fs_id;
65 case ORANGEFS_VFS_OP_LISTXATTR:
66 fsid = op->upcall.req.listxattr.refn.fs_id;
68 case ORANGEFS_VFS_OP_REMOVEXATTR:
69 fsid = op->upcall.req.removexattr.refn.fs_id;
71 case ORANGEFS_VFS_OP_FSYNC:
72 fsid = op->upcall.req.fsync.refn.fs_id;
81 static int orangefs_inode_flags(struct ORANGEFS_sys_attr_s *attrs)
84 if (attrs->flags & ORANGEFS_IMMUTABLE_FL)
87 flags &= ~S_IMMUTABLE;
88 if (attrs->flags & ORANGEFS_APPEND_FL)
92 if (attrs->flags & ORANGEFS_NOATIME_FL)
99 static int orangefs_inode_perms(struct ORANGEFS_sys_attr_s *attrs)
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;
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;
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;
124 if (attrs->perms & ORANGEFS_G_SGID)
125 perm_mode |= S_ISGID;
126 if (attrs->perms & ORANGEFS_U_SUID)
127 perm_mode |= S_ISUID;
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.
136 static inline int copy_attributes_from_inode(struct inode *inode,
137 struct ORANGEFS_sys_attr_s *attrs,
142 if (!iattr || !inode || !attrs) {
143 gossip_err("NULL iattr (%p), inode (%p), attrs (%p) "
144 "in copy_attributes_from_inode!\n",
151 * We need to be careful to only copy the attributes out of the
152 * iattr object that we know are valid.
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);
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);
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;
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;
180 if (iattr->ia_valid & ATTR_CTIME)
181 attrs->mask |= ORANGEFS_ATTR_SYS_CTIME;
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
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)) {
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
200 gossip_debug(GOSSIP_UTILS_DEBUG,
201 "User attempted to set sticky bit on non-root directory; returning EINVAL.\n");
206 if (tmp_mode & (S_ISUID)) {
207 gossip_debug(GOSSIP_UTILS_DEBUG,
208 "Attempting to set setuid bit (not supported); returning EINVAL.\n");
212 attrs->perms = ORANGEFS_util_translate_mode(tmp_mode);
213 attrs->mask |= ORANGEFS_ATTR_SYS_PERM;
219 static int orangefs_inode_type(enum orangefs_ds_type objtype)
221 if (objtype == ORANGEFS_TYPE_METAFILE)
223 else if (objtype == ORANGEFS_TYPE_DIRECTORY)
225 else if (objtype == ORANGEFS_TYPE_SYMLINK)
231 static int orangefs_inode_is_stale(struct inode *inode, int new,
232 struct ORANGEFS_sys_attr_s *attrs, char *link_target)
234 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
235 int type = orangefs_inode_type(attrs->objtype);
238 * If the inode type or symlink target have changed then this
241 if (type == -1 || !(inode->i_mode & type)) {
242 orangefs_make_bad_inode(inode);
245 if (type == S_IFLNK && strncmp(orangefs_inode->link_target,
246 link_target, ORANGEFS_NAME_MAX)) {
247 orangefs_make_bad_inode(inode);
254 int orangefs_inode_getattr(struct inode *inode, int new, int size)
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;
261 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
262 get_khandle_from_ino(inode));
264 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
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;
271 ret = service_operation(new_op, __func__,
272 get_interruptible_flag(inode));
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);
288 inode->i_flags = orangefs_inode_flags(&new_op->
289 downcall.resp.getattr.attributes);
291 inode_size = (loff_t)new_op->
292 downcall.resp.getattr.attributes.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;
301 (unsigned long)(rounded_up_size / 512);
302 spin_unlock(&inode->i_lock);
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);
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,
325 inode->i_link = orangefs_inode->link_target;
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;
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);
354 int orangefs_inode_check_changed(struct inode *inode)
356 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
357 struct orangefs_kernel_op_s *new_op;
360 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: called on inode %pU\n", __func__,
361 get_khandle_from_ino(inode));
363 new_op = op_alloc(ORANGEFS_VFS_OP_GETATTR);
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;
370 ret = service_operation(new_op, __func__,
371 get_interruptible_flag(inode));
375 ret = orangefs_inode_is_stale(inode, 0,
376 &new_op->downcall.resp.getattr.attributes,
377 new_op->downcall.resp.getattr.link_target);
384 * issues a orangefs setattr request to make sure the new attribute values
385 * take effect if successful. returns 0 on success; -errno otherwise
387 int orangefs_inode_setattr(struct inode *inode, struct iattr *iattr)
389 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
390 struct orangefs_kernel_op_s *new_op;
393 new_op = op_alloc(ORANGEFS_VFS_OP_SETATTR);
397 new_op->upcall.req.setattr.refn = orangefs_inode->refn;
398 ret = copy_attributes_from_inode(inode,
399 &new_op->upcall.req.setattr.attributes,
402 ret = service_operation(new_op, __func__,
403 get_interruptible_flag(inode));
405 gossip_debug(GOSSIP_UTILS_DEBUG,
406 "orangefs_inode_setattr: returning %d\n",
413 * successful setattr should clear the atime, mtime and
417 ClearAtimeFlag(orangefs_inode);
418 ClearMtimeFlag(orangefs_inode);
419 ClearCtimeFlag(orangefs_inode);
420 ClearModeFlag(orangefs_inode);
426 int orangefs_flush_inode(struct inode *inode)
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
440 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(inode);
442 memset(&wbattr, 0, sizeof(wbattr));
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
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);
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
462 * Also mode updates are being handled now..
466 wbattr.ia_valid |= ATTR_MTIME;
468 wbattr.ia_valid |= ATTR_CTIME;
470 wbattr.ia_valid |= ATTR_ATIME;
473 wbattr.ia_mode = inode->i_mode;
474 wbattr.ia_valid |= ATTR_MODE;
477 gossip_debug(GOSSIP_UTILS_DEBUG,
478 "*********** orangefs_flush_inode: %pU "
480 get_khandle_from_ino(inode),
482 if (wbattr.ia_valid == 0) {
483 gossip_debug(GOSSIP_UTILS_DEBUG,
484 "orangefs_flush_inode skipping setattr()\n");
488 gossip_debug(GOSSIP_UTILS_DEBUG,
489 "orangefs_flush_inode (%pU) writing mode %o\n",
490 get_khandle_from_ino(inode),
493 ret = orangefs_inode_setattr(inode, &wbattr);
498 int orangefs_unmount_sb(struct super_block *sb)
501 struct orangefs_kernel_op_s *new_op = NULL;
503 gossip_debug(GOSSIP_UTILS_DEBUG,
504 "orangefs_unmount_sb called on sb %p\n",
507 new_op = op_alloc(ORANGEFS_VFS_OP_FS_UMOUNT);
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);
516 gossip_debug(GOSSIP_UTILS_DEBUG,
517 "Attempting ORANGEFS Unmount via host %s\n",
518 new_op->upcall.req.fs_umount.orangefs_config_server);
520 ret = service_operation(new_op, "orangefs_fs_umount", 0);
522 gossip_debug(GOSSIP_UTILS_DEBUG,
523 "orangefs_unmount: got return value of %d\n", ret);
527 ORANGEFS_SB(sb)->mount_pending = 1;
533 void orangefs_make_bad_inode(struct inode *inode)
535 if (is_root_handle(inode)) {
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.
541 gossip_debug(GOSSIP_UTILS_DEBUG,
542 "*** NOT making bad root inode %pU\n",
543 get_khandle_from_ino(inode));
545 gossip_debug(GOSSIP_UTILS_DEBUG,
546 "*** making bad inode %pU\n",
547 get_khandle_from_ino(inode));
548 make_bad_inode(inode);
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.
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
571 int orangefs_normalize_to_errno(__s32 error_code)
576 if (error_code == 0) {
579 * This shouldn't ever happen. If it does it should be fixed on the
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;
589 * XXX: This is very bad since error codes from ORANGEFS may not be
590 * suitable for return into userspace.
594 * Convert ORANGEFS error values into errno values suitable for return
597 if ((-error_code) & ORANGEFS_NON_ERRNO_ERROR_BIT) {
599 (ORANGEFS_ERROR_NUMBER_BITS|ORANGEFS_NON_ERRNO_ERROR_BIT|
600 ORANGEFS_ERROR_BIT)) == ORANGEFS_ECANCEL) {
602 * cancellation error codes generally correspond to
603 * a timeout from the client's perspective
605 error_code = -ETIMEDOUT;
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;
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];
618 error_code = -EINVAL;
621 * Only ORANGEFS protocol error codes should ever come here. Otherwise
622 * there is a bug somewhere.
625 gossip_err("orangefs: orangefs_normalize_to_errno: got error code which is not from ORANGEFS.\n");
631 __s32 ORANGEFS_util_translate_mode(int mode)
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,
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
648 for (i = 0; i < NUM_MODES; i++)
650 ret |= orangefs_modes[i];
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.
661 int orangefs_prepare_cdm_array(char *debug_array_string)
665 char *cds_head = NULL;
666 char *cds_delimiter = NULL;
669 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
672 * figure out how many elements the cdm_array needs.
674 for (i = 0; i < strlen(debug_array_string); i++)
675 if (debug_array_string[i] == '\n')
678 if (!cdm_element_count) {
679 pr_info("No elements in client debug array string!\n");
684 kzalloc(cdm_element_count * sizeof(struct client_debug_mask),
687 pr_info("malloc failed for cdm_array!\n");
692 cds_head = debug_array_string;
694 for (i = 0; i < cdm_element_count; i++) {
695 cds_delimiter = strchr(cds_head, '\n');
696 *cds_delimiter = '\0';
698 keyword_len = strcspn(cds_head, " ");
700 cdm_array[i].keyword = kzalloc(keyword_len + 1, GFP_KERNEL);
701 if (!cdm_array[i].keyword) {
708 cdm_array[i].keyword,
709 (unsigned long long *)&(cdm_array[i].mask1),
710 (unsigned long long *)&(cdm_array[i].mask2));
712 if (!strcmp(cdm_array[i].keyword, ORANGEFS_VERBOSE))
713 client_verbose_index = i;
715 if (!strcmp(cdm_array[i].keyword, ORANGEFS_ALL))
716 client_all_index = i;
718 cds_head = cds_delimiter + 1;
721 rc = cdm_element_count;
723 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: rc:%d:\n", __func__, rc);
732 * /sys/kernel/debug/orangefs/debug-help can be catted to
733 * see all the available kernel and client debug keywords.
735 * When the kernel boots, we have no idea what keywords the
736 * client supports, nor their associated masks.
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.
743 * The client might be restarted any number of times between
744 * reboots, we only build the debug-help file the first time.
746 int orangefs_prepare_debugfs_help_string(int at_boot)
751 char *client_title = "Client Debug Keywords:\n";
752 char *kernel_title = "Kernel Debug Keywords:\n";
754 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
757 byte_count += strlen(HELP_STRING_UNINITIALIZED);
758 client_title = HELP_STRING_UNINITIALIZED;
761 * fill the client keyword/mask array and remember
762 * how many elements there were.
765 orangefs_prepare_cdm_array(client_debug_array_string);
766 if (cdm_element_count <= 0)
769 /* Count the bytes destined for debug_help_string. */
770 byte_count += strlen(client_title);
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__);
780 gossip_debug(GOSSIP_UTILS_DEBUG,
781 "%s: cdm_element_count:%d:\n",
786 byte_count += strlen(kernel_title);
787 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
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__);
796 /* build debug_help_string. */
797 debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
798 if (!debug_help_string) {
803 strcat(debug_help_string, client_title);
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");
813 strcat(debug_help_string, "\n");
814 strcat(debug_help_string, kernel_title);
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");
834 void debug_mask_to_string(void *mask, int type)
839 int element_count = 0;
841 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
844 debug_string = client_debug_string;
845 element_count = cdm_element_count;
847 debug_string = kernel_debug_string;
848 element_count = num_kmod_keyword_mask_map;
851 memset(debug_string, 0, ORANGEFS_MAX_DEBUG_STRING_LEN);
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
859 if (check_amalgam_keyword(mask, type))
862 /* Build the debug string. */
863 for (i = 0; i < element_count; i++)
865 do_c_string(mask, i);
867 do_k_string(mask, i);
869 len = strlen(debug_string);
872 client_debug_string[len - 1] = '\0';
874 kernel_debug_string[len - 1] = '\0';
876 strcpy(client_debug_string, "none");
878 strcpy(kernel_debug_string, "none");
881 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: string:%s:\n", __func__, debug_string);
887 void do_k_string(void *k_mask, int index)
889 __u64 *mask = (__u64 *) k_mask;
891 if (keyword_is_amalgam((char *) s_kmod_keyword_mask_map[index].keyword))
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, ",");
902 gossip_err("%s: overflow!\n", __func__);
903 strcpy(kernel_debug_string, ORANGEFS_ALL);
913 void do_c_string(void *c_mask, int index)
915 struct client_debug_mask *mask = (struct client_debug_mask *) c_mask;
917 if (keyword_is_amalgam(cdm_array[index].keyword))
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, ",");
929 gossip_err("%s: overflow!\n", __func__);
930 strcpy(client_debug_string, ORANGEFS_ALL);
938 int keyword_is_amalgam(char *keyword)
942 if ((!strcmp(keyword, ORANGEFS_ALL)) || (!strcmp(keyword, ORANGEFS_VERBOSE)))
952 * return 1 if we found an amalgam.
954 int check_amalgam_keyword(void *mask, int type)
957 struct client_debug_mask *c_mask;
958 int k_all_index = num_kmod_keyword_mask_map - 1;
962 c_mask = (struct client_debug_mask *) mask;
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);
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);
979 k_mask = (__u64 *) mask;
981 if (*k_mask >= s_kmod_keyword_mask_map[k_all_index].mask_val) {
982 strcpy(kernel_debug_string, ORANGEFS_ALL);
997 void debug_string_to_mask(char *debug_string, void *mask, int type)
999 char *unchecked_keyword;
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;
1007 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
1010 c_mask = (struct client_debug_mask *)mask;
1011 element_count = cdm_element_count;
1013 k_mask = (__u64 *)mask;
1015 element_count = num_kmod_keyword_mask_map;
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++)
1032 kfree(original_pointer);
1035 void do_c_mask(int i,
1036 char *unchecked_keyword,
1037 struct client_debug_mask **sane_mask)
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;
1046 void do_k_mask(int i, char *unchecked_keyword, __u64 **sane_mask)
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;