Loading fs/ocfs2/stack_user.c +89 −5 Original line number Diff line number Diff line Loading @@ -35,9 +35,21 @@ * of output is a supported protocol tag. All protocol tags are a single * character followed by a two hex digit version number. Currently the * only things supported is T01, for "Text-base version 0x01". Next, the * client writes the version they would like to use. If the version tag * written is unknown, -EINVAL is returned. Once the negotiation is * complete, the client can start sending messages. * client writes the version they would like to use, including the newline. * Thus, the protocol tag is 'T01\n'. If the version tag written is * unknown, -EINVAL is returned. Once the negotiation is complete, the * client can start sending messages. * * The T01 protocol only has one message, "DOWN". It has the following * syntax: * * DOWN<space><32-char-cap-hex-uuid><space><8-char-hex-nodenum><newline> * * eg: * * DOWN 632A924FDD844190BDA93C0DF6B94899 00000001\n * * This is 47 characters. */ /* Loading @@ -49,6 +61,11 @@ #define OCFS2_CONTROL_HANDSHAKE_INVALID (0) #define OCFS2_CONTROL_HANDSHAKE_READ (1) #define OCFS2_CONTROL_HANDSHAKE_VALID (2) #define OCFS2_CONTROL_MESSAGE_DOWN "DOWN" #define OCFS2_CONTROL_MESSAGE_DOWN_LEN 4 #define OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN 47 #define OCFS2_TEXT_UUID_LEN 32 #define OCFS2_CONTROL_MESSAGE_NODENUM_LEN 8 /* * ocfs2_live_connection is refcounted because the filesystem and Loading Loading @@ -149,7 +166,7 @@ static void ocfs2_live_connection_drop(struct ocfs2_live_connection *c) kfree(c); } static ssize_t ocfs2_control_cfu(char *target, size_t target_len, static ssize_t ocfs2_control_cfu(void *target, size_t target_len, const char __user *buf, size_t count) { /* The T01 expects write(2) calls to have exactly one command */ Loading Loading @@ -185,6 +202,73 @@ static ssize_t ocfs2_control_validate_handshake(struct file *file, return count; } static void ocfs2_control_send_down(const char *uuid, int nodenum) { struct ocfs2_live_connection *c; mutex_lock(&ocfs2_control_lock); c = ocfs2_connection_find(uuid); if (c) { BUG_ON(c->oc_conn == NULL); c->oc_conn->cc_recovery_handler(nodenum, c->oc_conn->cc_recovery_data); } mutex_unlock(&ocfs2_control_lock); } /* DOWN<space><32-char-cap-hex-uuid><space><8-char-hex-nodenum><newline> */ struct ocfs2_control_message_down { char tag[OCFS2_CONTROL_MESSAGE_DOWN_LEN]; char space1; char uuid[OCFS2_TEXT_UUID_LEN]; char space2; char nodestr[OCFS2_CONTROL_MESSAGE_NODENUM_LEN]; char newline; }; static ssize_t ocfs2_control_message(struct file *file, const char __user *buf, size_t count) { ssize_t ret; char *p = NULL; long nodenum; struct ocfs2_control_message_down msg; /* Try to catch padding issues */ WARN_ON(offsetof(struct ocfs2_control_message_down, uuid) != (sizeof(msg.tag) + sizeof(msg.space1))); memset(&msg, 0, sizeof(struct ocfs2_control_message_down)); ret = ocfs2_control_cfu(&msg, OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN, buf, count); if (ret != count) return ret; if (strncmp(msg.tag, OCFS2_CONTROL_MESSAGE_DOWN, strlen(OCFS2_CONTROL_MESSAGE_DOWN))) return -EINVAL; if ((msg.space1 != ' ') || (msg.space2 != ' ') || (msg.newline != '\n')) return -EINVAL; msg.space1 = msg.space2 = msg.newline = '\0'; nodenum = simple_strtol(msg.nodestr, &p, 16); if (!p || *p) return -EINVAL; if ((nodenum == LONG_MIN) || (nodenum == LONG_MAX) || (nodenum > INT_MAX) || (nodenum < 0)) return -ERANGE; ocfs2_control_send_down(msg.uuid, nodenum); return count; } static ssize_t ocfs2_control_write(struct file *file, const char __user *buf, Loading @@ -204,7 +288,7 @@ static ssize_t ocfs2_control_write(struct file *file, break; case OCFS2_CONTROL_HANDSHAKE_VALID: ret = count; /* XXX */ ret = ocfs2_control_message(file, buf, count); break; default: Loading Loading
fs/ocfs2/stack_user.c +89 −5 Original line number Diff line number Diff line Loading @@ -35,9 +35,21 @@ * of output is a supported protocol tag. All protocol tags are a single * character followed by a two hex digit version number. Currently the * only things supported is T01, for "Text-base version 0x01". Next, the * client writes the version they would like to use. If the version tag * written is unknown, -EINVAL is returned. Once the negotiation is * complete, the client can start sending messages. * client writes the version they would like to use, including the newline. * Thus, the protocol tag is 'T01\n'. If the version tag written is * unknown, -EINVAL is returned. Once the negotiation is complete, the * client can start sending messages. * * The T01 protocol only has one message, "DOWN". It has the following * syntax: * * DOWN<space><32-char-cap-hex-uuid><space><8-char-hex-nodenum><newline> * * eg: * * DOWN 632A924FDD844190BDA93C0DF6B94899 00000001\n * * This is 47 characters. */ /* Loading @@ -49,6 +61,11 @@ #define OCFS2_CONTROL_HANDSHAKE_INVALID (0) #define OCFS2_CONTROL_HANDSHAKE_READ (1) #define OCFS2_CONTROL_HANDSHAKE_VALID (2) #define OCFS2_CONTROL_MESSAGE_DOWN "DOWN" #define OCFS2_CONTROL_MESSAGE_DOWN_LEN 4 #define OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN 47 #define OCFS2_TEXT_UUID_LEN 32 #define OCFS2_CONTROL_MESSAGE_NODENUM_LEN 8 /* * ocfs2_live_connection is refcounted because the filesystem and Loading Loading @@ -149,7 +166,7 @@ static void ocfs2_live_connection_drop(struct ocfs2_live_connection *c) kfree(c); } static ssize_t ocfs2_control_cfu(char *target, size_t target_len, static ssize_t ocfs2_control_cfu(void *target, size_t target_len, const char __user *buf, size_t count) { /* The T01 expects write(2) calls to have exactly one command */ Loading Loading @@ -185,6 +202,73 @@ static ssize_t ocfs2_control_validate_handshake(struct file *file, return count; } static void ocfs2_control_send_down(const char *uuid, int nodenum) { struct ocfs2_live_connection *c; mutex_lock(&ocfs2_control_lock); c = ocfs2_connection_find(uuid); if (c) { BUG_ON(c->oc_conn == NULL); c->oc_conn->cc_recovery_handler(nodenum, c->oc_conn->cc_recovery_data); } mutex_unlock(&ocfs2_control_lock); } /* DOWN<space><32-char-cap-hex-uuid><space><8-char-hex-nodenum><newline> */ struct ocfs2_control_message_down { char tag[OCFS2_CONTROL_MESSAGE_DOWN_LEN]; char space1; char uuid[OCFS2_TEXT_UUID_LEN]; char space2; char nodestr[OCFS2_CONTROL_MESSAGE_NODENUM_LEN]; char newline; }; static ssize_t ocfs2_control_message(struct file *file, const char __user *buf, size_t count) { ssize_t ret; char *p = NULL; long nodenum; struct ocfs2_control_message_down msg; /* Try to catch padding issues */ WARN_ON(offsetof(struct ocfs2_control_message_down, uuid) != (sizeof(msg.tag) + sizeof(msg.space1))); memset(&msg, 0, sizeof(struct ocfs2_control_message_down)); ret = ocfs2_control_cfu(&msg, OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN, buf, count); if (ret != count) return ret; if (strncmp(msg.tag, OCFS2_CONTROL_MESSAGE_DOWN, strlen(OCFS2_CONTROL_MESSAGE_DOWN))) return -EINVAL; if ((msg.space1 != ' ') || (msg.space2 != ' ') || (msg.newline != '\n')) return -EINVAL; msg.space1 = msg.space2 = msg.newline = '\0'; nodenum = simple_strtol(msg.nodestr, &p, 16); if (!p || *p) return -EINVAL; if ((nodenum == LONG_MIN) || (nodenum == LONG_MAX) || (nodenum > INT_MAX) || (nodenum < 0)) return -ERANGE; ocfs2_control_send_down(msg.uuid, nodenum); return count; } static ssize_t ocfs2_control_write(struct file *file, const char __user *buf, Loading @@ -204,7 +288,7 @@ static ssize_t ocfs2_control_write(struct file *file, break; case OCFS2_CONTROL_HANDSHAKE_VALID: ret = count; /* XXX */ ret = ocfs2_control_message(file, buf, count); break; default: Loading