From: Chris Horn Date: Sun, 23 Jun 2019 23:26:30 +0000 (-0500) Subject: LU-12410 libcfs: Implement address range expansion X-Git-Tag: 2.13.51~63 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=b0d131cd725b82adbfa44b082a9c5446ef7194d4 LU-12410 libcfs: Implement address range expansion Implements a new top-level API function for the nidstrings library. cfs_expand_nidlist iterates over each nidrange on a nidlist and expands the range to create the lnet_nid_t's defined by the nidrange. The caller supplies the nidlist, an lnet_nid_t array pointer where the lnet_nid_t's are stored, and the maximum number of LNet nids to generate (i.e. the size of the lnet_nid_t array pointer). cfs_expand_nidlist returns the number of lnet_nid_t's that were added to the lnet_nid_t array. If the provided nidlist defines more NIDs than the specified maximum then the return value is -1. Test-Parameters: trivial Signed-off-by: Chris Horn Change-Id: I3e02f1ec466a8bc90142944b62565ebc7ef82e88 Reviewed-on: https://review.whamcloud.com/35303 Reviewed-by: James Simmons Reviewed-by: Petros Koutoupis Reviewed-by: Shaun Tancheff Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/libcfs/libcfs/util/nidstrings.c b/libcfs/libcfs/util/nidstrings.c index 246d420..69641a4 100644 --- a/libcfs/libcfs/util/nidstrings.c +++ b/libcfs/libcfs/util/nidstrings.c @@ -190,6 +190,46 @@ out: } static int +libcfs_num_addr_range_expand(struct list_head *addrranges, __u32 *addrs, + int max_addrs) +{ + struct cfs_expr_list *expr_list; + struct cfs_range_expr *range; + int i; + int max_idx = max_addrs - 1; + int addrs_idx = max_idx; + + list_for_each_entry(expr_list, addrranges, el_link) { + list_for_each_entry(range, &expr_list->el_exprs, re_link) { + for (i = range->re_lo; i <= range->re_hi; + i += range->re_stride) { + if (addrs_idx < 0) + return -1; + + addrs[addrs_idx] = i; + addrs_idx--; + } + } + } + + return max_idx - addrs_idx; +} + +static int +libcfs_ip_addr_range_expand(struct list_head *addrranges, __u32 *addrs, + int max_addrs) +{ + int rc = 0; + + rc = cfs_ip_addr_range_gen(addrs, max_addrs, addrranges); + + if (rc == -1) + return rc; + else + return max_addrs - rc - 1; +} + +static int libcfs_ip_addr_range_print(char *buffer, int count, struct list_head *list) { int i = 0, j = 0; @@ -390,7 +430,8 @@ static struct netstrfns libcfs_netstrfns[] = { .nf_parse_addrlist = libcfs_num_parse, .nf_print_addrlist = libcfs_num_addr_range_print, .nf_match_addr = libcfs_num_match, - .nf_min_max = cfs_num_min_max + .nf_min_max = cfs_num_min_max, + .nf_expand_addrrange = libcfs_num_addr_range_expand }, { .nf_type = SOCKLND, @@ -401,7 +442,8 @@ static struct netstrfns libcfs_netstrfns[] = { .nf_parse_addrlist = cfs_ip_addr_parse, .nf_print_addrlist = libcfs_ip_addr_range_print, .nf_match_addr = cfs_ip_addr_match, - .nf_min_max = cfs_ip_min_max + .nf_min_max = cfs_ip_min_max, + .nf_expand_addrrange = libcfs_ip_addr_range_expand }, { .nf_type = O2IBLND, @@ -412,7 +454,8 @@ static struct netstrfns libcfs_netstrfns[] = { .nf_parse_addrlist = cfs_ip_addr_parse, .nf_print_addrlist = libcfs_ip_addr_range_print, .nf_match_addr = cfs_ip_addr_match, - .nf_min_max = cfs_ip_min_max + .nf_min_max = cfs_ip_min_max, + .nf_expand_addrrange = libcfs_ip_addr_range_expand }, { .nf_type = GNILND, @@ -423,7 +466,8 @@ static struct netstrfns libcfs_netstrfns[] = { .nf_parse_addrlist = libcfs_num_parse, .nf_print_addrlist = libcfs_num_addr_range_print, .nf_match_addr = libcfs_num_match, - .nf_min_max = cfs_num_min_max + .nf_min_max = cfs_num_min_max, + .nf_expand_addrrange = libcfs_num_addr_range_expand }, { .nf_type = GNIIPLND, @@ -434,7 +478,8 @@ static struct netstrfns libcfs_netstrfns[] = { .nf_parse_addrlist = cfs_ip_addr_parse, .nf_print_addrlist = libcfs_ip_addr_range_print, .nf_match_addr = cfs_ip_addr_match, - .nf_min_max = cfs_ip_min_max + .nf_min_max = cfs_ip_min_max, + .nf_expand_addrrange = libcfs_ip_addr_range_expand }, { .nf_type = PTL4LND, @@ -445,7 +490,8 @@ static struct netstrfns libcfs_netstrfns[] = { .nf_parse_addrlist = libcfs_num_parse, .nf_print_addrlist = libcfs_num_addr_range_print, .nf_match_addr = libcfs_num_match, - .nf_min_max = cfs_num_min_max + .nf_min_max = cfs_num_min_max, + .nf_expand_addrrange = libcfs_num_addr_range_expand } }; @@ -1303,3 +1349,57 @@ static int cfs_ip_min_max(struct list_head *nidlist, __u32 *min_nid, return 0; } + +static int +libcfs_expand_nidrange(struct nidrange *nr, __u32 *addrs, int max_nids) +{ + struct addrrange *ar; + int rc = 0, count = max_nids; + struct netstrfns *nf = nr->nr_netstrfns; + + list_for_each_entry(ar, &nr->nr_addrranges, ar_link) { + rc = nf->nf_expand_addrrange(&ar->ar_numaddr_ranges, addrs, + count); + if (rc < 0) + return rc; + + count -= rc; + } + + return max_nids - count; +} + +int cfs_expand_nidlist(struct list_head *nidlist, lnet_nid_t *lnet_nidlist, + int max_nids) +{ + struct nidrange *nr; + int rc = 0, count = max_nids; + int i, j = 0; + __u32 *addrs; + struct netstrfns *nf; + __u32 net; + + addrs = calloc(max_nids, sizeof(__u32)); + if (!addrs) + return -ENOMEM; + + list_for_each_entry(nr, nidlist, nr_link) { + rc = libcfs_expand_nidrange(nr, addrs, count); + + if (rc < 0) { + free(addrs); + return rc; + } + + nf = nr->nr_netstrfns; + net = LNET_MKNET(nf->nf_type, nr->nr_netnum); + + for (i = count - 1; i >= count - rc; i--) + lnet_nidlist[j++] = LNET_MKNID(net, addrs[i]); + + count -= rc; + } + + free(addrs); + return max_nids - count; +} diff --git a/lnet/include/uapi/linux/lnet/nidstr.h b/lnet/include/uapi/linux/lnet/nidstr.h index c41b915..6e3f4ca 100644 --- a/lnet/include/uapi/linux/lnet/nidstr.h +++ b/lnet/include/uapi/linux/lnet/nidstr.h @@ -98,7 +98,8 @@ void cfs_free_nidlist(struct list_head *list); int cfs_parse_nidlist(char *str, int len, struct list_head *list); int cfs_print_nidlist(char *buffer, int count, struct list_head *list); int cfs_match_nid(lnet_nid_t nid, struct list_head *list); - +int cfs_expand_nidlist(struct list_head *nidlist, lnet_nid_t *lnet_nidlist, + int max_nids); int cfs_ip_addr_parse(char *str, int len, struct list_head *list); int cfs_ip_addr_match(__u32 addr, struct list_head *list); int cfs_nidrange_find_min_max(struct list_head *nidlist, char *min_nid, @@ -117,6 +118,8 @@ struct netstrfns { int (*nf_match_addr)(__u32 addr, struct list_head *list); int (*nf_min_max)(struct list_head *nidlist, __u32 *min_nid, __u32 *max_nid); + int (*nf_expand_addrrange)(struct list_head *addrranges, + __u32 *addrs, int max_addrs); }; #endif /* _LNET_NIDSTRINGS_H */