Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 377715
b: refs/heads/master
c: 98e1b60
h: refs/heads/master
i:
  377713: 26f3d80
  377711: e97b1c9
v: v3
  • Loading branch information
Mike Christie authored and David Teigland committed Jun 14, 2013
1 parent 094d389 commit 6d02a15
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b390ca38d27bd3d2f409e64a6f13d6ff67eb4825
refs/heads/master: 98e1b60ecc441625c91013e88f14cbd1b3c1fa08
61 changes: 50 additions & 11 deletions trunk/fs/dlm/lowcomms.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ struct connection {
struct connection *othercon;
struct work_struct rwork; /* Receive workqueue */
struct work_struct swork; /* Send workqueue */
bool try_new_addr;
};
#define sock2con(x) ((struct connection *)(x)->sk_user_data)

Expand All @@ -144,6 +145,7 @@ struct dlm_node_addr {
struct list_head list;
int nodeid;
int addr_count;
int curr_addr_index;
struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT];
};

Expand Down Expand Up @@ -310,7 +312,7 @@ static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y)
}

static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out,
struct sockaddr *sa_out)
struct sockaddr *sa_out, bool try_new_addr)
{
struct sockaddr_storage sas;
struct dlm_node_addr *na;
Expand All @@ -320,8 +322,16 @@ static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out,

spin_lock(&dlm_node_addrs_spin);
na = find_node_addr(nodeid);
if (na && na->addr_count)
memcpy(&sas, na->addr[0], sizeof(struct sockaddr_storage));
if (na && na->addr_count) {
if (try_new_addr) {
na->curr_addr_index++;
if (na->curr_addr_index == na->addr_count)
na->curr_addr_index = 0;
}

memcpy(&sas, na->addr[na->curr_addr_index ],
sizeof(struct sockaddr_storage));
}
spin_unlock(&dlm_node_addrs_spin);

if (!na)
Expand Down Expand Up @@ -353,19 +363,22 @@ static int addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid)
{
struct dlm_node_addr *na;
int rv = -EEXIST;
int addr_i;

spin_lock(&dlm_node_addrs_spin);
list_for_each_entry(na, &dlm_node_addrs, list) {
if (!na->addr_count)
continue;

if (!addr_compare(na->addr[0], addr))
continue;

*nodeid = na->nodeid;
rv = 0;
break;
for (addr_i = 0; addr_i < na->addr_count; addr_i++) {
if (addr_compare(na->addr[addr_i], addr)) {
*nodeid = na->nodeid;
rv = 0;
goto unlock;
}
}
}
unlock:
spin_unlock(&dlm_node_addrs_spin);
return rv;
}
Expand Down Expand Up @@ -561,6 +574,21 @@ static void sctp_send_shutdown(sctp_assoc_t associd)

static void sctp_init_failed_foreach(struct connection *con)
{

/*
* Don't try to recover base con and handle race where the
* other node's assoc init creates a assoc and we get that
* notification, then we get a notification that our attempt
* failed due. This happens when we are still trying the primary
* address, but the other node has already tried secondary addrs
* and found one that worked.
*/
if (!con->nodeid || con->sctp_assoc)
return;

log_print("Retrying SCTP association init for node %d\n", con->nodeid);

con->try_new_addr = true;
con->sctp_assoc = 0;
if (test_and_clear_bit(CF_INIT_PENDING, &con->flags)) {
if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags))
Expand Down Expand Up @@ -663,6 +691,7 @@ static void process_sctp_notification(struct connection *con,
nodeid, (int)sn->sn_assoc_change.sac_assoc_id);

new_con->sctp_assoc = sn->sn_assoc_change.sac_assoc_id;
new_con->try_new_addr = false;
/* Send any pending writes */
clear_bit(CF_CONNECT_PENDING, &new_con->flags);
clear_bit(CF_INIT_PENDING, &new_con->flags);
Expand Down Expand Up @@ -984,7 +1013,8 @@ static void sctp_init_assoc(struct connection *con)
if (con->retries++ > MAX_CONNECT_RETRIES)
return;

if (nodeid_to_addr(con->nodeid, NULL, (struct sockaddr *)&rem_addr)) {
if (nodeid_to_addr(con->nodeid, NULL, (struct sockaddr *)&rem_addr,
con->try_new_addr)) {
log_print("no address for nodeid %d", con->nodeid);
return;
}
Expand Down Expand Up @@ -1016,6 +1046,14 @@ static void sctp_init_assoc(struct connection *con)
iov[0].iov_base = page_address(e->page)+offset;
iov[0].iov_len = len;

if (rem_addr.ss_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)&rem_addr;
log_print("Trying to connect to %pI4", &sin->sin_addr.s_addr);
} else {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&rem_addr;
log_print("Trying to connect to %pI6", &sin6->sin6_addr);
}

cmsg = CMSG_FIRSTHDR(&outmessage);
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
Expand All @@ -1024,6 +1062,7 @@ static void sctp_init_assoc(struct connection *con)
memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
sinfo->sinfo_ppid = cpu_to_le32(dlm_our_nodeid());
outmessage.msg_controllen = cmsg->cmsg_len;
sinfo->sinfo_flags |= SCTP_ADDR_OVER;

ret = kernel_sendmsg(base_con->sock, &outmessage, iov, 1, len);
if (ret < 0) {
Expand Down Expand Up @@ -1076,7 +1115,7 @@ static void tcp_connect_to_sock(struct connection *con)
goto out_err;

memset(&saddr, 0, sizeof(saddr));
result = nodeid_to_addr(con->nodeid, &saddr, NULL);
result = nodeid_to_addr(con->nodeid, &saddr, NULL, false);
if (result < 0) {
log_print("no address for nodeid %d", con->nodeid);
goto out_err;
Expand Down

0 comments on commit 6d02a15

Please sign in to comment.