#include "config.h"
#include "midcomms.h"
-static struct sockaddr_storage *local_addr[DLM_MAX_ADDR_COUNT];
-static int local_count;
-static int local_nodeid;
+static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT];
+static int dlm_local_count;
+static int dlm_local_nodeid;
/* One of these per connected node */
struct sockaddr_storage addr;
int error;
- if (!local_count)
+ if (!dlm_local_count)
return -1;
error = dlm_nodeid_to_addr(nodeid, &addr);
if (error)
return error;
- if (local_addr[0]->ss_family == AF_INET) {
+ if (dlm_local_addr[0]->ss_family == AF_INET) {
struct sockaddr_in *in4 = (struct sockaddr_in *) &addr;
struct sockaddr_in *ret4 = (struct sockaddr_in *) retaddr;
ret4->sin_addr.s_addr = in4->sin_addr.s_addr;
return 0;
}
-static struct nodeinfo *nodeid2nodeinfo(int nodeid, int alloc)
+static struct nodeinfo *nodeid2nodeinfo(int nodeid, gfp_t alloc)
{
struct nodeinfo *ni;
int r;
struct sockaddr_in *local4_addr;
struct sockaddr_in6 *local6_addr;
- if (!local_count)
+ if (!dlm_local_count)
return;
if (!port) {
- if (local_addr[0]->ss_family == AF_INET) {
- local4_addr = (struct sockaddr_in *)local_addr[0];
+ if (dlm_local_addr[0]->ss_family == AF_INET) {
+ local4_addr = (struct sockaddr_in *)dlm_local_addr[0];
port = be16_to_cpu(local4_addr->sin_port);
} else {
- local6_addr = (struct sockaddr_in6 *)local_addr[0];
+ local6_addr = (struct sockaddr_in6 *)dlm_local_addr[0];
port = be16_to_cpu(local6_addr->sin6_port);
}
}
- saddr->ss_family = local_addr[0]->ss_family;
- if (local_addr[0]->ss_family == AF_INET) {
+ saddr->ss_family = dlm_local_addr[0]->ss_family;
+ if (dlm_local_addr[0]->ss_family == AF_INET) {
struct sockaddr_in *in4_addr = (struct sockaddr_in *)saddr;
in4_addr->sin_port = cpu_to_be16(port);
memset(&in4_addr->sin_zero, 0, sizeof(in4_addr->sin_zero));
msg.msg_flags = 0;
msg.msg_control = incmsg;
msg.msg_controllen = sizeof(incmsg);
+ msg.msg_iovlen = 1;
/* I don't see why this circular buffer stuff is necessary for SCTP
* which is a packet-based protocol, but the whole thing breaks under
}
len = iov[0].iov_len + iov[1].iov_len;
- r = ret = kernel_recvmsg(sctp_con.sock, &msg, iov, 1, len,
+ r = ret = kernel_recvmsg(sctp_con.sock, &msg, iov, msg.msg_iovlen, len,
MSG_NOSIGNAL | MSG_DONTWAIT);
if (ret <= 0)
goto out_close;
struct sockaddr_storage sas, *addr;
int i;
- local_nodeid = dlm_our_nodeid();
+ dlm_local_nodeid = dlm_our_nodeid();
for (i = 0; i < DLM_MAX_ADDR_COUNT - 1; i++) {
if (dlm_our_addr(&sas, i))
if (!addr)
break;
memcpy(addr, &sas, sizeof(*addr));
- local_addr[local_count++] = addr;
+ dlm_local_addr[dlm_local_count++] = addr;
}
}
struct sctp_event_subscribe subscribe;
int result = -EINVAL, num = 1, i, addr_len;
- if (!local_count) {
+ if (!dlm_local_count) {
init_local();
- if (!local_count) {
+ if (!dlm_local_count) {
log_print("no local IP address has been set");
goto out;
}
}
- result = sock_create_kern(local_addr[0]->ss_family, SOCK_SEQPACKET,
+ result = sock_create_kern(dlm_local_addr[0]->ss_family, SOCK_SEQPACKET,
IPPROTO_SCTP, &sock);
if (result < 0) {
log_print("Can't create comms socket, check SCTP is loaded");
sctp_con.sock->sk->sk_data_ready = lowcomms_data_ready;
/* Bind to all interfaces. */
- for (i = 0; i < local_count; i++) {
- memcpy(&localaddr, local_addr[i], sizeof(localaddr));
+ for (i = 0; i < dlm_local_count; i++) {
+ memcpy(&localaddr, dlm_local_addr[i], sizeof(localaddr));
make_sockaddr(&localaddr, dlm_config.tcp_port, &addr_len);
result = add_bind_addr(&localaddr, addr_len, num);
}
-static struct writequeue_entry *new_writequeue_entry(int allocation)
+static struct writequeue_entry *new_writequeue_entry(gfp_t allocation)
{
struct writequeue_entry *entry;
return entry;
}
-void *dlm_lowcomms_get_buffer(int nodeid, int len, int allocation, char **ppc)
+void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc)
{
struct writequeue_entry *e;
int offset = 0;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
- sinfo->sinfo_ppid = cpu_to_le32(local_nodeid);
+ sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid);
outmessage.msg_controllen = cmsg->cmsg_len;
ret = kernel_sendmsg(sctp_con.sock, &outmessage, iov, 1, 1);
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
- sinfo->sinfo_ppid = cpu_to_le32(local_nodeid);
+ sinfo->sinfo_ppid = cpu_to_le32(dlm_local_nodeid);
sinfo->sinfo_assoc_id = ni->assoc_id;
outmsg.msg_controllen = cmsg->cmsg_len;
break;
e = list_entry(ni->writequeue.next, struct writequeue_entry,
list);
- kmap(e->page);
len = e->len;
offset = e->offset;
BUG_ON(len == 0 && e->users == 0);
spin_unlock(&ni->writequeue_lock);
+ kmap(e->page);
ret = 0;
if (len) {
}
}
+int dlm_lowcomms_close(int nodeid)
+{
+ struct nodeinfo *ni;
+
+ ni = nodeid2nodeinfo(nodeid, 0);
+ if (!ni)
+ return -1;
+
+ spin_lock(&ni->lock);
+ if (ni->assoc_id) {
+ ni->assoc_id = 0;
+ /* Don't send shutdown here, sctp will just queue it
+ till the node comes back up! */
+ }
+ spin_unlock(&ni->lock);
+
+ clean_one_writequeue(ni);
+ clear_bit(NI_INIT_PENDING, &ni->flags);
+ return 0;
+}
+
static int write_list_empty(void)
{
int status;
{
int error;
- spin_lock_init(&write_nodes_lock);
- INIT_LIST_HEAD(&write_nodes);
- init_rwsem(&nodeinfo_lock);
-
error = init_sock();
if (error)
goto fail_sock;
int dlm_lowcomms_init(void)
{
init_waitqueue_head(&lowcomms_recv_wait);
+ spin_lock_init(&write_nodes_lock);
+ INIT_LIST_HEAD(&write_nodes);
+ init_rwsem(&nodeinfo_lock);
return 0;
}
{
int i;
- for (i = 0; i < local_count; i++)
- kfree(local_addr[i]);
- local_count = 0;
- local_nodeid = 0;
+ for (i = 0; i < dlm_local_count; i++)
+ kfree(dlm_local_addr[i]);
+ dlm_local_count = 0;
+ dlm_local_nodeid = 0;
}