lustre-devel-lustre.org archive mirror
 help / color / mirror / Atom feed
From: James Simmons <jsimmons@infradead.org>
To: Andreas Dilger <adilger@whamcloud.com>,
	Oleg Drokin <green@whamcloud.com>, NeilBrown <neilb@suse.de>
Cc: Chris Horn <chris.horn@hpe.com>,
	Cyril Bordage <cbordage@whamcloud.com>,
	Serguei Smirnov <ssmirnov@whamcloud.com>,
	Lustre Development List <lustre-devel@lists.lustre.org>
Subject: [lustre-devel] [PATCH 21/33] lnet: collect data about routes by using Netlink
Date: Sun,  2 Feb 2025 15:46:21 -0500	[thread overview]
Message-ID: <20250202204633.1148872-22-jsimmons@infradead.org> (raw)
In-Reply-To: <20250202204633.1148872-1-jsimmons@infradead.org>

Migrate the LNet route API to use the Netlink API for
the case of collecting data about routes. This change also
allows large NID support for IPv6. Support for adding and
deleting routes with Netlink will be done in an follow on
patch.

WC-bug-id: https://jira.whamcloud.com/browse/LU-9680
Lustre-commit: 4ccac8297d0a60027 ("LU-9680 lnet: collect data about routes by using Netlink")
Signed-off-by: James Simmons <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/49839
WC-bug-id: https://jira.whamcloud.com/brose/LU-10391
Lustre-commit: 7d9643b5b9373b1f8 ("LU-10391 lnet: use GFP_ATOMIC for alloc under spinlock")
Signed-off-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53597
Reviewed-by: Serguei Smirnov <ssmirnov@whamcloud.com>
Reviewed-by: Chris Horn <chris.horn@hpe.com>
Reviewed-by: Cyril Bordage <cbordage@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
---
 include/linux/lnet/lib-types.h     |  40 +++
 include/uapi/linux/lnet/lnet-dlc.h |   7 +-
 net/lnet/lnet/api-ni.c             | 396 +++++++++++++++++++++++++++++
 3 files changed, 440 insertions(+), 3 deletions(-)

diff --git a/include/linux/lnet/lib-types.h b/include/linux/lnet/lib-types.h
index bc9f0020f93a..0de7654e3a67 100644
--- a/include/linux/lnet/lib-types.h
+++ b/include/linux/lnet/lib-types.h
@@ -557,6 +557,46 @@ enum lnet_net_local_ni_tunables_attr {
 
 #define LNET_NET_LOCAL_NI_TUNABLES_ATTR_MAX (__LNET_NET_LOCAL_NI_TUNABLES_ATTR_MAX_PLUS_ONE - 1)
 
+/** enum lnet_route_attrs		      - LNet route netlink
+ *						attributes that describe
+ *						LNet routes
+ *
+ * @LNET_ROUTE_ATTR_UNSPEC:			unspecified attribute to
+ *						catch errors
+ *
+ * @LNET_ROUTE_ATTR_HDR:			grouping for LNet route data
+ *						(NLA_NUL_STRING)
+ * @LNET_ROUTE_ATTR_NET:			LNet remote network reached
+ *						by the route (NLA_STRING)
+ * @LNET_ROUTE_ATTR_GATEWAY:			gateway for the route
+ *						(NLA_STRING)
+ * @LNET_ROUTE_ATTR_HOP:			route hop count (NLA_S32)
+ *
+ * @LNET_ROUTE_ATTR_PRIORITY:			rank of this network path
+ *						(NLA_U32)
+ * @LNET_ROUTE_ATTR_HEALTH_SENSITIVITY:		rate of health value change
+ *						for the route (NLA_U32)
+ * @LNET_ROUTE_ATTR_STATE:			state of route (NLA_STRING)
+ *
+ * @LNET_ROUTE_ATTR_TYPE:			Report if we support multi-hop
+ *						(NLA_STRING)
+ */
+enum lnet_route_attrs {
+	LNET_ROUTE_ATTR_UNSPEC = 0,
+
+	LNET_ROUTE_ATTR_HDR,
+	LNET_ROUTE_ATTR_NET,
+	LNET_ROUTE_ATTR_GATEWAY,
+	LNET_ROUTE_ATTR_HOP,
+	LNET_ROUTE_ATTR_PRIORITY,
+	LNET_ROUTE_ATTR_HEALTH_SENSITIVITY,
+	LNET_ROUTE_ATTR_STATE,
+	LNET_ROUTE_ATTR_TYPE,
+	__LNET_ROUTE_ATTR_MAX_PLUS_ONE,
+};
+
+#define LNET_ROUTE_ATTR_MAX (__LNET_ROUTE_ATTR_MAX_PLUS_ONE - 1)
+
 /** LNet netlink ping API */
 
 /** enum lnet_ping_atts				      - LNet ping netlink properties
diff --git a/include/uapi/linux/lnet/lnet-dlc.h b/include/uapi/linux/lnet/lnet-dlc.h
index fc1d40ce8756..d7592f3fd1f8 100644
--- a/include/uapi/linux/lnet/lnet-dlc.h
+++ b/include/uapi/linux/lnet/lnet-dlc.h
@@ -54,10 +54,11 @@
 
 /* enum lnet_commands	      - Supported core LNet Netlink commands
  *
- *  @LNET_CMD_UNSPEC:		unspecified command to catch errors
+ * @LNET_CMD_UNSPEC:		unspecified command to catch errors
  *
- *  @LNET_CMD_NETS:		command to manage the LNet networks
- *  @LNET_CMD_PING:		command to send pings to LNet connections
+ * @LNET_CMD_NETS:		command to manage the LNet networks
+ * @LNET_CMD_ROUTES:		command to manage LNet routes
+ * @LNET_CMD_PING:		command to send pings to LNet connections
  */
 enum lnet_commands {
 	LNET_CMD_UNSPEC		= 0,
diff --git a/net/lnet/lnet/api-ni.c b/net/lnet/lnet/api-ni.c
index fa42cfd99aa7..d3d51acdf2ad 100644
--- a/net/lnet/lnet/api-ni.c
+++ b/net/lnet/lnet/api-ni.c
@@ -5322,6 +5322,395 @@ static int lnet_net_cmd(struct sk_buff *skb, struct genl_info *info)
 	return rc;
 }
 
+/** LNet route handling */
+
+/* We can't use struct lnet_ioctl_config_data since it lacks
+ * support for large NIDS
+ */
+struct lnet_route_properties {
+	struct lnet_nid		lrp_gateway;
+	u32			lrp_net;
+	s32			lrp_hop;
+	u32			lrp_flags;
+	u32			lrp_priority;
+	u32			lrp_sensitivity;
+};
+
+struct lnet_genl_route_list {
+	unsigned int				lgrl_index;
+	unsigned int				lgrl_count;
+	GENRADIX(struct lnet_route_properties)	lgrl_list;
+};
+
+static inline struct lnet_genl_route_list *
+lnet_route_dump_ctx(struct netlink_callback *cb)
+{
+	return (struct lnet_genl_route_list *)cb->args[0];
+}
+
+static int lnet_route_show_done(struct netlink_callback *cb)
+{
+	struct lnet_genl_route_list *rlist = lnet_route_dump_ctx(cb);
+
+	if (rlist) {
+		genradix_free(&rlist->lgrl_list);
+		kfree(rlist);
+	}
+	cb->args[0] = 0;
+
+	return 0;
+}
+
+int lnet_scan_route(struct lnet_genl_route_list *rlist,
+		    struct lnet_route_properties *settings)
+{
+	struct lnet_remotenet *rnet;
+	struct list_head *rn_list;
+	struct lnet_route *route;
+	int cpt, i, rc = 0;
+
+	cpt = lnet_net_lock_current();
+
+	for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++) {
+		rn_list = &the_lnet.ln_remote_nets_hash[i];
+		list_for_each_entry(rnet, rn_list, lrn_list) {
+			if (settings->lrp_net != LNET_NET_ANY &&
+			    settings->lrp_net != rnet->lrn_net)
+				continue;
+
+			list_for_each_entry(route, &rnet->lrn_routes,
+					    lr_list) {
+				struct lnet_route_properties *prop;
+
+				if (!LNET_NID_IS_ANY(&settings->lrp_gateway) &&
+				    !nid_same(&settings->lrp_gateway,
+					      &route->lr_nid)) {
+					continue;
+				}
+
+				if (settings->lrp_hop != -1 &&
+				    settings->lrp_hop != route->lr_hops)
+					continue;
+
+				if (settings->lrp_priority != -1 &&
+				    settings->lrp_priority != route->lr_priority)
+					continue;
+
+				if (settings->lrp_sensitivity != -1 &&
+				    settings->lrp_sensitivity !=
+				    route->lr_gateway->lp_health_sensitivity)
+					continue;
+
+				prop = genradix_ptr_alloc(&rlist->lgrl_list,
+							  rlist->lgrl_count++,
+							  GFP_ATOMIC);
+				if (!prop) {
+					rc = -ENOMEM;
+					goto failed_alloc;
+				}
+
+				prop->lrp_net = rnet->lrn_net;
+				prop->lrp_gateway = route->lr_nid;
+				prop->lrp_hop = route->lr_hops;
+				prop->lrp_priority = route->lr_priority;
+				prop->lrp_sensitivity =
+					route->lr_gateway->lp_health_sensitivity;
+				if (lnet_is_route_alive(route))
+					prop->lrp_flags |= LNET_RT_ALIVE;
+				else
+					prop->lrp_flags &= ~LNET_RT_ALIVE;
+				if (route->lr_single_hop)
+					prop->lrp_flags &= ~LNET_RT_MULTI_HOP;
+				else
+					prop->lrp_flags |= LNET_RT_MULTI_HOP;
+			}
+		}
+	}
+
+failed_alloc:
+	lnet_net_unlock(cpt);
+	return rc;
+}
+
+/* LNet route ->start() handler for GET requests */
+static int lnet_route_show_start(struct netlink_callback *cb)
+{
+	struct genlmsghdr *gnlh = nlmsg_data(cb->nlh);
+	struct netlink_ext_ack *extack = cb->extack;
+	struct lnet_genl_route_list *rlist;
+	int msg_len = genlmsg_len(gnlh);
+	int rc = 0;
+
+	if (the_lnet.ln_refcount == 0 ||
+	    the_lnet.ln_state != LNET_STATE_RUNNING) {
+		NL_SET_ERR_MSG(extack, "Network is down");
+		return -ENETDOWN;
+	}
+
+	rlist = kzalloc(sizeof(*rlist), GFP_KERNEL);
+	if (!rlist) {
+		NL_SET_ERR_MSG(extack, "No memory for route list");
+		return -ENOMEM;
+	}
+
+	genradix_init(&rlist->lgrl_list);
+	rlist->lgrl_count = 0;
+	rlist->lgrl_index = 0;
+	cb->args[0] = (long)rlist;
+
+	mutex_lock(&the_lnet.ln_api_mutex);
+	if (!msg_len) {
+		struct lnet_route_properties tmp = {
+			.lrp_gateway		= LNET_ANY_NID,
+			.lrp_net		= LNET_NET_ANY,
+			.lrp_hop		= -1,
+			.lrp_priority		= -1,
+			.lrp_sensitivity	= -1,
+		};
+
+		rc = lnet_scan_route(rlist, &tmp);
+		if (rc < 0) {
+			NL_SET_ERR_MSG(extack,
+				       "failed to allocate router data");
+			goto report_err;
+		}
+	} else {
+		struct nlattr *params = genlmsg_data(gnlh);
+		struct nlattr *attr;
+		int rem;
+
+		nla_for_each_nested(attr, params, rem) {
+			struct lnet_route_properties tmp = {
+				.lrp_gateway		= LNET_ANY_NID,
+				.lrp_net		= LNET_NET_ANY,
+				.lrp_hop		= -1,
+				.lrp_priority		= -1,
+				.lrp_sensitivity	= -1,
+			};
+			struct nlattr *route;
+			int rem2;
+
+			if (nla_type(attr) != LN_SCALAR_ATTR_LIST)
+				continue;
+
+			nla_for_each_nested(route, attr, rem2) {
+				if (nla_type(route) != LN_SCALAR_ATTR_VALUE)
+					continue;
+
+				if (nla_strcmp(route, "net") == 0) {
+					char nw[LNET_NIDSTR_SIZE];
+
+					route = nla_next(route, &rem2);
+					if (nla_type(route) !=
+					    LN_SCALAR_ATTR_VALUE) {
+						NL_SET_ERR_MSG(extack,
+							       "invalid net param");
+						rc = -EINVAL;
+						goto report_err;
+					}
+
+					rc = nla_strlcpy(nw, route, sizeof(nw));
+					if (rc < 0) {
+						NL_SET_ERR_MSG(extack,
+							       "failed to get route param");
+						goto report_err;
+					}
+					rc = 0;
+					tmp.lrp_net = libcfs_str2net(strim(nw));
+				} else if (nla_strcmp(route, "gateway") == 0) {
+					char gw[LNET_NIDSTR_SIZE];
+
+					route = nla_next(route, &rem2);
+					if (nla_type(route) !=
+					    LN_SCALAR_ATTR_VALUE) {
+						NL_SET_ERR_MSG(extack,
+							       "invalid gateway param");
+						rc = -EINVAL;
+						goto report_err;
+					}
+
+					rc = nla_strlcpy(gw, route, sizeof(gw));
+					if (rc < 0) {
+						NL_SET_ERR_MSG(extack,
+							       "failed to get route param");
+						goto report_err;
+					}
+					rc = 0;
+					libcfs_strnid(&tmp.lrp_gateway, strim(gw));
+				} else if (nla_strcmp(route, "hop") == 0) {
+					route = nla_next(route, &rem2);
+					if (nla_type(route) !=
+					    LN_SCALAR_ATTR_INT_VALUE) {
+						NL_SET_ERR_MSG(extack,
+							       "invalid hop param");
+						rc = -EINVAL;
+						goto report_err;
+					}
+
+					tmp.lrp_hop = nla_get_s64(route);
+					if (tmp.lrp_hop != -1)
+						clamp_t(s32, tmp.lrp_hop, 1, 127);
+				} else if (nla_strcmp(route, "priority") == 0) {
+					route = nla_next(route, &rem2);
+					if (nla_type(route) !=
+					    LN_SCALAR_ATTR_INT_VALUE) {
+						NL_SET_ERR_MSG(extack,
+							       "invalid priority param");
+						rc = -EINVAL;
+						goto report_err;
+					}
+
+					tmp.lrp_priority = nla_get_s64(route);
+				}
+			}
+
+			rc = lnet_scan_route(rlist, &tmp);
+			if (rc < 0) {
+				NL_SET_ERR_MSG(extack,
+					       "failed to allocate router data");
+				goto report_err;
+			}
+		}
+	}
+report_err:
+	mutex_unlock(&the_lnet.ln_api_mutex);
+
+	if (rc < 0)
+		lnet_route_show_done(cb);
+
+	return rc;
+}
+
+static const struct ln_key_list route_props_list = {
+	.lkl_maxattr			= LNET_ROUTE_ATTR_MAX,
+	.lkl_list			= {
+		[LNET_ROUTE_ATTR_HDR]			= {
+			.lkp_value			= "route",
+			.lkp_key_format			= LNKF_SEQUENCE | LNKF_MAPPING,
+			.lkp_data_type			= NLA_NUL_STRING,
+		},
+		[LNET_ROUTE_ATTR_NET]			= {
+			.lkp_value			= "net",
+			.lkp_data_type			= NLA_STRING
+		},
+		[LNET_ROUTE_ATTR_GATEWAY]		= {
+			.lkp_value			= "gateway",
+			.lkp_data_type			= NLA_STRING
+		},
+		[LNET_ROUTE_ATTR_HOP]			= {
+			.lkp_value			= "hop",
+			.lkp_data_type			= NLA_S32
+		},
+		[LNET_ROUTE_ATTR_PRIORITY]		= {
+			.lkp_value			= "priority",
+			.lkp_data_type			= NLA_U32
+		},
+		[LNET_ROUTE_ATTR_HEALTH_SENSITIVITY]	= {
+			.lkp_value			= "health_sensitivity",
+			.lkp_data_type			= NLA_U32
+		},
+		[LNET_ROUTE_ATTR_STATE]	= {
+			.lkp_value			= "state",
+			.lkp_data_type			= NLA_STRING,
+		},
+		[LNET_ROUTE_ATTR_TYPE]	= {
+			.lkp_value			= "type",
+			.lkp_data_type			= NLA_STRING,
+		},
+	},
+};
+
+static int lnet_route_show_dump(struct sk_buff *msg,
+				struct netlink_callback *cb)
+{
+	struct lnet_genl_route_list *rlist = lnet_route_dump_ctx(cb);
+	struct genlmsghdr *gnlh = nlmsg_data(cb->nlh);
+	struct netlink_ext_ack *extack = cb->extack;
+	int portid = NETLINK_CB(cb->skb).portid;
+	int seq = cb->nlh->nlmsg_seq;
+	int idx = rlist->lgrl_index;
+	int rc = 0;
+
+	if (!rlist->lgrl_count) {
+		NL_SET_ERR_MSG(extack, "No routes found");
+		rc = -ENOENT;
+		goto send_error;
+	}
+
+	if (!idx) {
+		const struct ln_key_list *all[] = {
+			&route_props_list, NULL
+		};
+
+		rc = lnet_genl_send_scalar_list(msg, portid, seq,
+						&lnet_family,
+						NLM_F_CREATE | NLM_F_MULTI,
+						LNET_CMD_ROUTES, all);
+		if (rc < 0) {
+			NL_SET_ERR_MSG(extack, "failed to send key table");
+			goto send_error;
+		}
+	}
+
+	/* If not routes found send an empty message and not an error */
+	if (!rlist->lgrl_count) {
+		void *hdr;
+
+		hdr = genlmsg_put(msg, portid, seq, &lnet_family,
+				  NLM_F_MULTI, LNET_CMD_ROUTES);
+		if (!hdr) {
+			NL_SET_ERR_MSG(extack, "failed to send values");
+			genlmsg_cancel(msg, hdr);
+			rc = -EMSGSIZE;
+			goto send_error;
+		}
+		genlmsg_end(msg, hdr);
+
+		goto send_error;
+	}
+
+	while (idx < rlist->lgrl_count) {
+		struct lnet_route_properties *prop;
+		void *hdr;
+
+		prop = genradix_ptr(&rlist->lgrl_list, idx++);
+
+		hdr = genlmsg_put(msg, portid, seq, &lnet_family,
+				  NLM_F_MULTI, LNET_CMD_ROUTES);
+		if (!hdr) {
+			NL_SET_ERR_MSG(extack, "failed to send values");
+			genlmsg_cancel(msg, hdr);
+			rc = -EMSGSIZE;
+			goto send_error;
+		}
+
+		if (idx == 1)
+			nla_put_string(msg, LNET_ROUTE_ATTR_HDR, "");
+
+		nla_put_string(msg, LNET_ROUTE_ATTR_NET,
+			       libcfs_net2str(prop->lrp_net));
+		nla_put_string(msg, LNET_ROUTE_ATTR_GATEWAY,
+			       libcfs_nidstr(&prop->lrp_gateway));
+		if (gnlh->version) {
+			nla_put_s32(msg, LNET_ROUTE_ATTR_HOP, prop->lrp_hop);
+			nla_put_u32(msg, LNET_ROUTE_ATTR_PRIORITY, prop->lrp_priority);
+			nla_put_u32(msg, LNET_ROUTE_ATTR_HEALTH_SENSITIVITY,
+				    prop->lrp_sensitivity);
+
+			nla_put_string(msg, LNET_ROUTE_ATTR_STATE,
+				       prop->lrp_flags & LNET_RT_ALIVE ?
+				       "up" : "down");
+			nla_put_string(msg, LNET_ROUTE_ATTR_TYPE,
+				       prop->lrp_flags & LNET_RT_MULTI_HOP ?
+				       "multi-hop" : "single-hop");
+		}
+		genlmsg_end(msg, hdr);
+	}
+	rlist->lgrl_index = idx;
+send_error:
+	return rc;
+};
+
 static inline struct lnet_genl_ping_list *
 lnet_ping_dump_ctx(struct netlink_callback *cb)
 {
@@ -5654,6 +6043,7 @@ static int lnet_ping_show_dump(struct sk_buff *msg,
 static const struct genl_multicast_group lnet_mcast_grps[] = {
 	{ .name	=	"ip2net",	},
 	{ .name =	"net",		},
+	{ .name	=	"route",	},
 	{ .name	=	"ping",		},
 };
 
@@ -5666,6 +6056,12 @@ static const struct genl_ops lnet_genl_ops[] = {
 		.done		= lnet_net_show_done,
 		.doit		= lnet_net_cmd,
 	},
+	{
+		.cmd		= LNET_CMD_ROUTES,
+		.start		= lnet_route_show_start,
+		.dumpit		= lnet_route_show_dump,
+		.done		= lnet_route_show_done,
+	},
 	{
 		.cmd		= LNET_CMD_PING,
 		.start		= lnet_ping_show_start,
-- 
2.39.3

_______________________________________________
lustre-devel mailing list
lustre-devel@lists.lustre.org
http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org

  parent reply	other threads:[~2025-02-02 21:00 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-02 20:46 [lustre-devel] [PATCH 00/33] lustre: sync to OpenSFS branch May 31, 2023 James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 01/33] lnet: set msg field for lnet message header James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 02/33] Revert "lustre: llite: Check vmpage in releasepage" James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 03/33] lustre: llite: EIO is possible on a race with page reclaim James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 04/33] lustre: llite: add __GFP_NORETRY for read-ahead page James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 05/33] lustre: obd: change lmd flags to bitmap James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 06/33] lustre: uapi: cleanup FSFILT defines James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 07/33] lustre: obd: Reserve metadata overstriping flags James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 08/33] lnet: selftest: manage the workqueue state properly James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 09/33] lustre: remove cl_{offset, index, page_size} helpers James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 10/33] lustre: csdc: reserve layout bits for compress component James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 11/33] lustre: obd: replace simple_strtoul() James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 12/33] lnet: Use dynamic allocation for LND tunables James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 13/33] lustre: cksum: fix generating T10PI guard tags for partial brw page James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 14/33] lustre: llite: remove OBD_ -> CFS_ macros James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 15/33] lustre: obd: " James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 16/33] lnet: improve numeric NID to CPT hashing James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 17/33] lnet: libcfs: Remove unsed LASSERT_ATOMIC_* macros James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 18/33] lustre: misc: replace obsolete ioctl numbers James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 19/33] lustre: lmv: treat unknown hash type as sane type James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 20/33] lustre: llite: Fix return for non-queued aio James Simmons
2025-02-02 20:46 ` James Simmons [this message]
2025-02-02 20:46 ` [lustre-devel] [PATCH 22/33] lustre: ptlrpc: switch sptlrpc_rule_set_choose to large nid James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 23/33] lnet: use list_first_entry() where appropriate James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 24/33] lustre: statahead: using try lock for batched RPCs James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 25/33] lnet: libcfs: use round_up directly James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 26/33] lustre: mdc: md_open_data should keep ref on close_req James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 27/33] lustre: llite: update comment of ll_swap_layouts_close James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 28/33] lustre: ldlm: replace OBD_ -> CFS_ macros James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 29/33] lustre: mdc: remove " James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 30/33] lnet: libcfs: move cfs_expr_list_print to nidstrings.c James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 31/33] lnet: libcfs: Remove reference to LASSERT_ATOMIC_POS James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 32/33] lnet: ksocklnd: ksocklnd_ni_get_eth_intf_speed() must use only rtnl lock James Simmons
2025-02-02 20:46 ` [lustre-devel] [PATCH 33/33] lustre: ldlm: convert ldlm extent locks to linux extent-tree James Simmons

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250202204633.1148872-22-jsimmons@infradead.org \
    --to=jsimmons@infradead.org \
    --cc=adilger@whamcloud.com \
    --cc=cbordage@whamcloud.com \
    --cc=chris.horn@hpe.com \
    --cc=green@whamcloud.com \
    --cc=lustre-devel@lists.lustre.org \
    --cc=neilb@suse.de \
    --cc=ssmirnov@whamcloud.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).