aboutsummaryrefslogtreecommitdiffstats
path: root/fs/orangefs/orangefs-debugfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/orangefs/orangefs-debugfs.c')
-rw-r--r--fs/orangefs/orangefs-debugfs.c147
1 files changed, 64 insertions, 83 deletions
diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
index eb09aa026723..d484068ca716 100644
--- a/fs/orangefs/orangefs-debugfs.c
+++ b/fs/orangefs/orangefs-debugfs.c
@@ -141,6 +141,9 @@ static struct client_debug_mask client_debug_mask;
141 */ 141 */
142static DEFINE_MUTEX(orangefs_debug_lock); 142static DEFINE_MUTEX(orangefs_debug_lock);
143 143
144/* Used to protect data in ORANGEFS_KMOD_DEBUG_HELP_FILE */
145static DEFINE_MUTEX(orangefs_help_file_lock);
146
144/* 147/*
145 * initialize kmod debug operations, create orangefs debugfs dir and 148 * initialize kmod debug operations, create orangefs debugfs dir and
146 * ORANGEFS_KMOD_DEBUG_HELP_FILE. 149 * ORANGEFS_KMOD_DEBUG_HELP_FILE.
@@ -289,6 +292,8 @@ static void *help_start(struct seq_file *m, loff_t *pos)
289 292
290 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_start: start\n"); 293 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_start: start\n");
291 294
295 mutex_lock(&orangefs_help_file_lock);
296
292 if (*pos == 0) 297 if (*pos == 0)
293 payload = m->private; 298 payload = m->private;
294 299
@@ -305,6 +310,7 @@ static void *help_next(struct seq_file *m, void *v, loff_t *pos)
305static void help_stop(struct seq_file *m, void *p) 310static void help_stop(struct seq_file *m, void *p)
306{ 311{
307 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_stop: start\n"); 312 gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_stop: start\n");
313 mutex_unlock(&orangefs_help_file_lock);
308} 314}
309 315
310static int help_show(struct seq_file *m, void *v) 316static int help_show(struct seq_file *m, void *v)
@@ -610,32 +616,54 @@ out:
610 * /sys/kernel/debug/orangefs/debug-help can be catted to 616 * /sys/kernel/debug/orangefs/debug-help can be catted to
611 * see all the available kernel and client debug keywords. 617 * see all the available kernel and client debug keywords.
612 * 618 *
613 * When the kernel boots, we have no idea what keywords the 619 * When orangefs.ko initializes, we have no idea what keywords the
614 * client supports, nor their associated masks. 620 * client supports, nor their associated masks.
615 * 621 *
616 * We pass through this function once at boot and stamp a 622 * We pass through this function once at module-load and stamp a
617 * boilerplate "we don't know" message for the client in the 623 * boilerplate "we don't know" message for the client in the
618 * debug-help file. We pass through here again when the client 624 * debug-help file. We pass through here again when the client
619 * starts and then we can fill out the debug-help file fully. 625 * starts and then we can fill out the debug-help file fully.
620 * 626 *
621 * The client might be restarted any number of times between 627 * The client might be restarted any number of times between
622 * reboots, we only build the debug-help file the first time. 628 * module reloads, we only build the debug-help file the first time.
623 */ 629 */
624int orangefs_prepare_debugfs_help_string(int at_boot) 630int orangefs_prepare_debugfs_help_string(int at_boot)
625{ 631{
626 int rc = -EINVAL;
627 int i;
628 int byte_count = 0;
629 char *client_title = "Client Debug Keywords:\n"; 632 char *client_title = "Client Debug Keywords:\n";
630 char *kernel_title = "Kernel Debug Keywords:\n"; 633 char *kernel_title = "Kernel Debug Keywords:\n";
634 size_t string_size = DEBUG_HELP_STRING_SIZE;
635 size_t result_size;
636 size_t i;
637 char *new;
638 int rc = -EINVAL;
631 639
632 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__); 640 gossip_debug(GOSSIP_UTILS_DEBUG, "%s: start\n", __func__);
633 641
634 if (at_boot) { 642 if (at_boot)
635 byte_count += strlen(HELP_STRING_UNINITIALIZED);
636 client_title = HELP_STRING_UNINITIALIZED; 643 client_title = HELP_STRING_UNINITIALIZED;
637 } else { 644
638 /* 645 /* build a new debug_help_string. */
646 new = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL);
647 if (!new) {
648 rc = -ENOMEM;
649 goto out;
650 }
651
652 /*
653 * strlcat(dst, src, size) will append at most
654 * "size - strlen(dst) - 1" bytes of src onto dst,
655 * null terminating the result, and return the total
656 * length of the string it tried to create.
657 *
658 * We'll just plow through here building our new debug
659 * help string and let strlcat take care of assuring that
660 * dst doesn't overflow.
661 */
662 strlcat(new, client_title, string_size);
663
664 if (!at_boot) {
665
666 /*
639 * fill the client keyword/mask array and remember 667 * fill the client keyword/mask array and remember
640 * how many elements there were. 668 * how many elements there were.
641 */ 669 */
@@ -644,64 +672,40 @@ int orangefs_prepare_debugfs_help_string(int at_boot)
644 if (cdm_element_count <= 0) 672 if (cdm_element_count <= 0)
645 goto out; 673 goto out;
646 674
647 /* Count the bytes destined for debug_help_string. */
648 byte_count += strlen(client_title);
649
650 for (i = 0; i < cdm_element_count; i++) { 675 for (i = 0; i < cdm_element_count; i++) {
651 byte_count += strlen(cdm_array[i].keyword + 2); 676 strlcat(new, "\t", string_size);
652 if (byte_count >= DEBUG_HELP_STRING_SIZE) { 677 strlcat(new, cdm_array[i].keyword, string_size);
653 pr_info("%s: overflow 1!\n", __func__); 678 strlcat(new, "\n", string_size);
654 goto out;
655 }
656 } 679 }
657
658 gossip_debug(GOSSIP_UTILS_DEBUG,
659 "%s: cdm_element_count:%d:\n",
660 __func__,
661 cdm_element_count);
662 } 680 }
663 681
664 byte_count += strlen(kernel_title); 682 strlcat(new, "\n", string_size);
683 strlcat(new, kernel_title, string_size);
684
665 for (i = 0; i < num_kmod_keyword_mask_map; i++) { 685 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
666 byte_count += 686 strlcat(new, "\t", string_size);
667 strlen(s_kmod_keyword_mask_map[i].keyword + 2); 687 strlcat(new, s_kmod_keyword_mask_map[i].keyword, string_size);
668 if (byte_count >= DEBUG_HELP_STRING_SIZE) { 688 result_size = strlcat(new, "\n", string_size);
669 pr_info("%s: overflow 2!\n", __func__);
670 goto out;
671 }
672 } 689 }
673 690
674 /* build debug_help_string. */ 691 /* See if we tried to put too many bytes into "new"... */
675 debug_help_string = kzalloc(DEBUG_HELP_STRING_SIZE, GFP_KERNEL); 692 if (result_size >= string_size) {
676 if (!debug_help_string) { 693 kfree(new);
677 rc = -ENOMEM;
678 goto out; 694 goto out;
679 } 695 }
680 696
681 strcat(debug_help_string, client_title); 697 if (at_boot) {
682 698 debug_help_string = new;
683 if (!at_boot) { 699 } else {
684 for (i = 0; i < cdm_element_count; i++) { 700 mutex_lock(&orangefs_help_file_lock);
685 strcat(debug_help_string, "\t"); 701 memset(debug_help_string, 0, DEBUG_HELP_STRING_SIZE);
686 strcat(debug_help_string, cdm_array[i].keyword); 702 strlcat(debug_help_string, new, string_size);
687 strcat(debug_help_string, "\n"); 703 mutex_unlock(&orangefs_help_file_lock);
688 }
689 }
690
691 strcat(debug_help_string, "\n");
692 strcat(debug_help_string, kernel_title);
693
694 for (i = 0; i < num_kmod_keyword_mask_map; i++) {
695 strcat(debug_help_string, "\t");
696 strcat(debug_help_string, s_kmod_keyword_mask_map[i].keyword);
697 strcat(debug_help_string, "\n");
698 } 704 }
699 705
700 rc = 0; 706 rc = 0;
701 707
702out: 708out: return rc;
703
704 return rc;
705 709
706} 710}
707 711
@@ -959,8 +963,12 @@ int orangefs_debugfs_new_client_string(void __user *arg)
959 ret = copy_from_user(&client_debug_array_string, 963 ret = copy_from_user(&client_debug_array_string,
960 (void __user *)arg, 964 (void __user *)arg,
961 ORANGEFS_MAX_DEBUG_STRING_LEN); 965 ORANGEFS_MAX_DEBUG_STRING_LEN);
962 if (ret != 0) 966
967 if (ret != 0) {
968 pr_info("%s: CLIENT_STRING: copy_from_user failed\n",
969 __func__);
963 return -EIO; 970 return -EIO;
971 }
964 972
965 /* 973 /*
966 * The real client-core makes an effort to ensure 974 * The real client-core makes an effort to ensure
@@ -975,45 +983,18 @@ int orangefs_debugfs_new_client_string(void __user *arg)
975 client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN - 1] = 983 client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN - 1] =
976 '\0'; 984 '\0';
977 985
978 if (ret != 0) {
979 pr_info("%s: CLIENT_STRING: copy_from_user failed\n",
980 __func__);
981 return -EIO;
982 }
983
984 pr_info("%s: client debug array string has been received.\n", 986 pr_info("%s: client debug array string has been received.\n",
985 __func__); 987 __func__);
986 988
987 if (!help_string_initialized) { 989 if (!help_string_initialized) {
988 990
989 /* Free the "we don't know yet" default string... */ 991 /* Build a proper debug help string. */
990 kfree(debug_help_string);
991
992 /* build a proper debug help string */
993 if (orangefs_prepare_debugfs_help_string(0)) { 992 if (orangefs_prepare_debugfs_help_string(0)) {
994 gossip_err("%s: no debug help string \n", 993 gossip_err("%s: no debug help string \n",
995 __func__); 994 __func__);
996 return -EIO; 995 return -EIO;
997 } 996 }
998 997
999 /* Replace the boilerplate boot-time debug-help file. */
1000 debugfs_remove(help_file_dentry);
1001
1002 help_file_dentry =
1003 debugfs_create_file(
1004 ORANGEFS_KMOD_DEBUG_HELP_FILE,
1005 0444,
1006 debug_dir,
1007 debug_help_string,
1008 &debug_help_fops);
1009
1010 if (!help_file_dentry) {
1011 gossip_err("%s: debugfs_create_file failed for"
1012 " :%s:!\n",
1013 __func__,
1014 ORANGEFS_KMOD_DEBUG_HELP_FILE);
1015 return -EIO;
1016 }
1017 } 998 }
1018 999
1019 debug_mask_to_string(&client_debug_mask, 1); 1000 debug_mask_to_string(&client_debug_mask, 1);