Reserve space in superblock for IPv6 addresses

Define a family field, and add a union for IPv4 and v6 variants, although
v6 is not supported yet.

Family field is now used to determine presence of address in a quorum slot,
instead of checking if addr is zero.

Signed-off-by: Andy Grover <agrover@versity.com>
This commit is contained in:
Andy Grover
2021-03-05 14:17:06 -08:00
parent d39e56d953
commit efe5d92458
6 changed files with 60 additions and 35 deletions

View File

@@ -86,11 +86,33 @@ struct scoutfs_timespec {
__u8 __pad[4];
};
/* XXX ipv6 */
struct scoutfs_inet_addr {
__le32 addr;
enum scoutfs_inet_family {
SCOUTFS_AF_NONE = 0,
SCOUTFS_AF_IPV4 = 1,
SCOUTFS_AF_IPV6 = 2,
};
struct scoutfs_inet_addr4 {
__le16 family;
__le16 port;
__u8 __pad[2];
__le32 addr;
};
/*
* Not yet supported by code.
*/
struct scoutfs_inet_addr6 {
__le16 family;
__le16 port;
__u8 addr[16];
__le32 flow_info;
__le32 scope_id;
__u8 __pad[4];
};
union scoutfs_inet_addr {
struct scoutfs_inet_addr4 v4;
struct scoutfs_inet_addr6 v6;
};
/*
@@ -591,7 +613,7 @@ struct scoutfs_quorum_message {
struct scoutfs_quorum_config {
__le64 version;
struct scoutfs_quorum_slot {
struct scoutfs_inet_addr addr;
union scoutfs_inet_addr addr;
} slots[SCOUTFS_QUORUM_MAX_SLOTS];
};

View File

@@ -90,19 +90,13 @@ enum conn_flags {
#define SIN_ARG(sin) sin, be16_to_cpu((sin)->sin_port)
static inline void scoutfs_addr_to_sin(struct sockaddr_in *sin,
struct scoutfs_inet_addr *addr)
union scoutfs_inet_addr *addr)
{
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = cpu_to_be32(le32_to_cpu(addr->addr));
sin->sin_port = cpu_to_be16(le16_to_cpu(addr->port));
}
BUG_ON(addr->v4.family != cpu_to_le16(SCOUTFS_AF_IPV4));
static inline void scoutfs_addr_from_sin(struct scoutfs_inet_addr *addr,
struct sockaddr_in *sin)
{
addr->addr = be32_to_le32(sin->sin_addr.s_addr);
addr->port = be16_to_le16(sin->sin_port);
memset(addr->__pad, 0, sizeof(addr->__pad));
sin->sin_family = AF_INET;
sin->sin_addr.s_addr = cpu_to_be32(le32_to_cpu(addr->v4.addr));
sin->sin_port = cpu_to_be16(le16_to_cpu(addr->v4.port));
}
struct scoutfs_net_connection *

View File

@@ -138,7 +138,7 @@ static bool quorum_slot_present(struct scoutfs_super_block *super, int i)
{
BUG_ON(i < 0 || i > SCOUTFS_QUORUM_MAX_SLOTS);
return super->qconf.slots[i].addr.addr != 0;
return super->qconf.slots[i].addr.v4.family == cpu_to_le16(SCOUTFS_AF_IPV4);
}
static ktime_t election_timeout(void)
@@ -976,6 +976,9 @@ static int verify_quorum_slots(struct super_block *sb)
}
for (j = i + 1; j < SCOUTFS_QUORUM_MAX_SLOTS; j++) {
if (!quorum_slot_present(super, j))
continue;
scoutfs_quorum_slot_sin(super, j, &other);
if (sin.sin_addr.s_addr == other.sin_addr.s_addr &&

View File

@@ -361,12 +361,12 @@ static int do_mkfs(struct mkfs_args *args)
struct scoutfs_quorum_slot *sl = &super->qconf.slots[i];
struct in_addr in;
if (sl->addr.addr == 0)
if (sl->addr.v4.family != cpu_to_le16(SCOUTFS_AF_IPV4))
continue;
in.s_addr = htonl(le32_to_cpu(sl->addr.addr));
in.s_addr = htonl(le32_to_cpu(sl->addr.v4.addr));
printf("%s%u: %s:%u", indent,
i, inet_ntoa(in), le16_to_cpu(sl->addr.port));
i, inet_ntoa(in), le16_to_cpu(sl->addr.v4.port));
indent = "\n ";
}
printf("\n");
@@ -395,22 +395,28 @@ static bool valid_quorum_slots(struct scoutfs_quorum_slot *slots)
int j;
for (i = 0; i < SCOUTFS_QUORUM_MAX_SLOTS; i++) {
if (slots[i].addr.addr == 0)
if (slots[i].addr.v4.family == cpu_to_le16(SCOUTFS_AF_NONE))
continue;
if (slots[i].addr.v4.family != cpu_to_le16(SCOUTFS_AF_IPV4)) {
fprintf(stderr, "quorum slot nr %u has invalid family %u\n",
i, le16_to_cpu(slots[i].addr.v4.family));
valid = false;
}
for (j = i + 1; j < SCOUTFS_QUORUM_MAX_SLOTS; j++) {
if (slots[j].addr.addr == 0)
if (slots[i].addr.v4.family != cpu_to_le16(SCOUTFS_AF_IPV4))
continue;
if (slots[i].addr.addr == slots[j].addr.addr &&
slots[i].addr.port == slots[j].addr.port) {
if (slots[i].addr.v4.addr == slots[j].addr.v4.addr &&
slots[i].addr.v4.port == slots[j].addr.v4.port) {
in.s_addr =
htonl(le32_to_cpu(slots[i].addr.addr));
htonl(le32_to_cpu(slots[i].addr.v4.addr));
addr = inet_ntoa(in);
fprintf(stderr, "quorum slot nr %u and %u have the same address %s:%u\n",
i, j, addr,
le16_to_cpu(slots[i].addr.port));
le16_to_cpu(slots[i].addr.v4.port));
valid = false;
}
}
@@ -430,7 +436,7 @@ static int parse_opt(int key, char *arg, struct argp_state *state)
ret = parse_quorum_slot(&slot, arg);
if (ret < 0)
return ret;
if (args->slots[ret].addr.addr != 0)
if (args->slots[ret].addr.v4.family != cpu_to_le16(SCOUTFS_AF_NONE))
argp_error(state, "Quorum slot %u already specified before slot '%s'\n",
ret, arg);
args->slots[ret] = slot;

View File

@@ -213,7 +213,8 @@ int parse_quorum_slot(struct scoutfs_quorum_slot *slot, char *arg)
return -EINVAL;
}
slot->addr.addr = cpu_to_le32(htonl(in.s_addr));
slot->addr.port = cpu_to_le16(port);
slot->addr.v4.family = cpu_to_le16(SCOUTFS_AF_IPV4);
slot->addr.v4.addr = cpu_to_le32(htonl(in.s_addr));
slot->addr.v4.port = cpu_to_le16(port);
return nr;
}

View File

@@ -769,7 +769,7 @@ static int print_btree_leaf_items(int fd, struct scoutfs_super_block *super,
return 0;
}
static char *alloc_addr_str(struct scoutfs_inet_addr *ia)
static char *alloc_addr_str(union scoutfs_inet_addr *ia)
{
struct in_addr addr;
char *quad;
@@ -777,12 +777,12 @@ static char *alloc_addr_str(struct scoutfs_inet_addr *ia)
int len;
memset(&addr, 0, sizeof(addr));
addr.s_addr = htonl(le32_to_cpu(ia->addr));
addr.s_addr = htonl(le32_to_cpu(ia->v4.addr));
quad = inet_ntoa(addr);
if (quad == NULL)
return NULL;
len = snprintf(NULL, 0, "%s:%u", quad, le16_to_cpu(ia->port));
len = snprintf(NULL, 0, "%s:%u", quad, le16_to_cpu(ia->v4.port));
if (len < 1 || len > 22)
return NULL;
@@ -791,7 +791,7 @@ static char *alloc_addr_str(struct scoutfs_inet_addr *ia)
if (!str)
return NULL;
snprintf(str, len, "%s:%u", quad, le16_to_cpu(ia->port));
snprintf(str, len, "%s:%u", quad, le16_to_cpu(ia->v4.port));
return str;
}
@@ -915,8 +915,7 @@ static void print_super_block(struct scoutfs_super_block *super, u64 blkno)
printf(" quorum config version %llu\n",
le64_to_cpu(super->qconf.version));
for (i = 0; i < array_size(super->qconf.slots); i++) {
if (!super->qconf.slots[i].addr.addr &&
!super->qconf.slots[i].addr.port)
if (super->qconf.slots[i].addr.v4.family != cpu_to_le16(SCOUTFS_AF_IPV4))
continue;
addr = alloc_addr_str(&super->qconf.slots[i].addr);