diff options
-rw-r--r-- | fs/ocfs2/cluster/heartbeat.c | 101 |
1 files changed, 78 insertions, 23 deletions
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index a8f10649674d..16e49765c853 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -62,8 +62,19 @@ static unsigned long o2hb_live_node_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)]; | |||
62 | static LIST_HEAD(o2hb_node_events); | 62 | static LIST_HEAD(o2hb_node_events); |
63 | static DECLARE_WAIT_QUEUE_HEAD(o2hb_steady_queue); | 63 | static DECLARE_WAIT_QUEUE_HEAD(o2hb_steady_queue); |
64 | 64 | ||
65 | #define O2HB_DB_TYPE_LIVENODES 0 | ||
66 | struct o2hb_debug_buf { | ||
67 | int db_type; | ||
68 | int db_size; | ||
69 | int db_len; | ||
70 | void *db_data; | ||
71 | }; | ||
72 | |||
73 | static struct o2hb_debug_buf *o2hb_db_livenodes; | ||
74 | |||
65 | #define O2HB_DEBUG_DIR "o2hb" | 75 | #define O2HB_DEBUG_DIR "o2hb" |
66 | #define O2HB_DEBUG_LIVENODES "livenodes" | 76 | #define O2HB_DEBUG_LIVENODES "livenodes" |
77 | |||
67 | static struct dentry *o2hb_debug_dir; | 78 | static struct dentry *o2hb_debug_dir; |
68 | static struct dentry *o2hb_debug_livenodes; | 79 | static struct dentry *o2hb_debug_livenodes; |
69 | 80 | ||
@@ -969,21 +980,35 @@ static int o2hb_thread(void *data) | |||
969 | #ifdef CONFIG_DEBUG_FS | 980 | #ifdef CONFIG_DEBUG_FS |
970 | static int o2hb_debug_open(struct inode *inode, struct file *file) | 981 | static int o2hb_debug_open(struct inode *inode, struct file *file) |
971 | { | 982 | { |
983 | struct o2hb_debug_buf *db = inode->i_private; | ||
972 | unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; | 984 | unsigned long map[BITS_TO_LONGS(O2NM_MAX_NODES)]; |
973 | char *buf = NULL; | 985 | char *buf = NULL; |
974 | int i = -1; | 986 | int i = -1; |
975 | int out = 0; | 987 | int out = 0; |
976 | 988 | ||
989 | /* max_nodes should be the largest bitmap we pass here */ | ||
990 | BUG_ON(sizeof(map) < db->db_size); | ||
991 | |||
977 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 992 | buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
978 | if (!buf) | 993 | if (!buf) |
979 | goto bail; | 994 | goto bail; |
980 | 995 | ||
981 | o2hb_fill_node_map(map, sizeof(map)); | 996 | switch (db->db_type) { |
997 | case O2HB_DB_TYPE_LIVENODES: | ||
998 | spin_lock(&o2hb_live_lock); | ||
999 | memcpy(map, db->db_data, db->db_size); | ||
1000 | spin_unlock(&o2hb_live_lock); | ||
1001 | break; | ||
1002 | |||
1003 | default: | ||
1004 | goto done; | ||
1005 | } | ||
982 | 1006 | ||
983 | while ((i = find_next_bit(map, O2NM_MAX_NODES, i + 1)) < O2NM_MAX_NODES) | 1007 | while ((i = find_next_bit(map, db->db_len, i + 1)) < db->db_len) |
984 | out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i); | 1008 | out += snprintf(buf + out, PAGE_SIZE - out, "%d ", i); |
985 | out += snprintf(buf + out, PAGE_SIZE - out, "\n"); | 1009 | out += snprintf(buf + out, PAGE_SIZE - out, "\n"); |
986 | 1010 | ||
1011 | done: | ||
987 | i_size_write(inode, out); | 1012 | i_size_write(inode, out); |
988 | 1013 | ||
989 | file->private_data = buf; | 1014 | file->private_data = buf; |
@@ -1030,10 +1055,56 @@ static const struct file_operations o2hb_debug_fops = { | |||
1030 | 1055 | ||
1031 | void o2hb_exit(void) | 1056 | void o2hb_exit(void) |
1032 | { | 1057 | { |
1033 | if (o2hb_debug_livenodes) | 1058 | kfree(o2hb_db_livenodes); |
1034 | debugfs_remove(o2hb_debug_livenodes); | 1059 | debugfs_remove(o2hb_debug_livenodes); |
1035 | if (o2hb_debug_dir) | 1060 | debugfs_remove(o2hb_debug_dir); |
1036 | debugfs_remove(o2hb_debug_dir); | 1061 | } |
1062 | |||
1063 | static struct dentry *o2hb_debug_create(const char *name, struct dentry *dir, | ||
1064 | struct o2hb_debug_buf **db, int db_len, | ||
1065 | int type, int size, int len, void *data) | ||
1066 | { | ||
1067 | *db = kmalloc(db_len, GFP_KERNEL); | ||
1068 | if (!*db) | ||
1069 | return NULL; | ||
1070 | |||
1071 | (*db)->db_type = type; | ||
1072 | (*db)->db_size = size; | ||
1073 | (*db)->db_len = len; | ||
1074 | (*db)->db_data = data; | ||
1075 | |||
1076 | return debugfs_create_file(name, S_IFREG|S_IRUSR, dir, *db, | ||
1077 | &o2hb_debug_fops); | ||
1078 | } | ||
1079 | |||
1080 | static int o2hb_debug_init(void) | ||
1081 | { | ||
1082 | int ret = -ENOMEM; | ||
1083 | |||
1084 | o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL); | ||
1085 | if (!o2hb_debug_dir) { | ||
1086 | mlog_errno(ret); | ||
1087 | goto bail; | ||
1088 | } | ||
1089 | |||
1090 | o2hb_debug_livenodes = o2hb_debug_create(O2HB_DEBUG_LIVENODES, | ||
1091 | o2hb_debug_dir, | ||
1092 | &o2hb_db_livenodes, | ||
1093 | sizeof(*o2hb_db_livenodes), | ||
1094 | O2HB_DB_TYPE_LIVENODES, | ||
1095 | sizeof(o2hb_live_node_bitmap), | ||
1096 | O2NM_MAX_NODES, | ||
1097 | o2hb_live_node_bitmap); | ||
1098 | if (!o2hb_debug_livenodes) { | ||
1099 | mlog_errno(ret); | ||
1100 | goto bail; | ||
1101 | } | ||
1102 | ret = 0; | ||
1103 | bail: | ||
1104 | if (ret) | ||
1105 | o2hb_exit(); | ||
1106 | |||
1107 | return ret; | ||
1037 | } | 1108 | } |
1038 | 1109 | ||
1039 | int o2hb_init(void) | 1110 | int o2hb_init(void) |
@@ -1050,23 +1121,7 @@ int o2hb_init(void) | |||
1050 | 1121 | ||
1051 | memset(o2hb_live_node_bitmap, 0, sizeof(o2hb_live_node_bitmap)); | 1122 | memset(o2hb_live_node_bitmap, 0, sizeof(o2hb_live_node_bitmap)); |
1052 | 1123 | ||
1053 | o2hb_debug_dir = debugfs_create_dir(O2HB_DEBUG_DIR, NULL); | 1124 | return o2hb_debug_init(); |
1054 | if (!o2hb_debug_dir) { | ||
1055 | mlog_errno(-ENOMEM); | ||
1056 | return -ENOMEM; | ||
1057 | } | ||
1058 | |||
1059 | o2hb_debug_livenodes = debugfs_create_file(O2HB_DEBUG_LIVENODES, | ||
1060 | S_IFREG|S_IRUSR, | ||
1061 | o2hb_debug_dir, NULL, | ||
1062 | &o2hb_debug_fops); | ||
1063 | if (!o2hb_debug_livenodes) { | ||
1064 | mlog_errno(-ENOMEM); | ||
1065 | debugfs_remove(o2hb_debug_dir); | ||
1066 | return -ENOMEM; | ||
1067 | } | ||
1068 | |||
1069 | return 0; | ||
1070 | } | 1125 | } |
1071 | 1126 | ||
1072 | /* if we're already in a callback then we're already serialized by the sem */ | 1127 | /* if we're already in a callback then we're already serialized by the sem */ |