bug fix for enfs: nfs v4 io hang when losts of sockets disconnect

This commit is contained in:
zhangmingqian 2023-12-04 11:24:15 +08:00
parent 9b4ffa23fd
commit 79dac37a91
5 changed files with 180 additions and 90 deletions

View File

@ -1,5 +1,5 @@
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 7d02dc52209d..50820a8a684a 100644
index 7d02dc522..b1194a3fb 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -48,7 +48,7 @@
@ -19,17 +19,34 @@ index 7d02dc52209d..50820a8a684a 100644
kfree(clp);
}
EXPORT_SYMBOL_GPL(nfs_free_client);
@@ -330,6 +331,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
@@ -324,11 +325,26 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
continue;
/* Match the full socket address */
if (!rpc_cmp_addr_port(sap, clap))
+#if IS_ENABLED(CONFIG_ENFS)
+ {
+ if (data->enfs_option != NULL)
+ continue;
+ else {
+ if (IS_ERR(clp->cl_rpcclient) ||
+ !rpc_clnt_xprt_switch_has_addr(
+ clp->cl_rpcclient, sap))
+ continue;
+ }
+ }
+#else
/* Match all xprt_switch full socket addresses */
if (IS_ERR(clp->cl_rpcclient) ||
!rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient,
sap))
continue;
+#endif
+ if (!nfs_multipath_client_match(clp, data))
+ continue;
+
refcount_inc(&clp->cl_count);
return clp;
}
@@ -512,6 +516,9 @@ int nfs_create_rpc_client(struct nfs_client *clp,
@@ -512,6 +528,9 @@ int nfs_create_rpc_client(struct nfs_client *clp,
.program = &nfs_program,
.version = clp->rpc_ops->version,
.authflavor = flavor,
@ -39,7 +56,7 @@ index 7d02dc52209d..50820a8a684a 100644
};
if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
@@ -634,6 +641,13 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
@@ -634,6 +653,13 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
/* the client is already initialised */
if (clp->cl_cons_state == NFS_CS_READY)
return clp;
@ -53,7 +70,7 @@ index 7d02dc52209d..50820a8a684a 100644
/*
* Create a client RPC handle for doing FSSTAT with UNIX auth only
@@ -666,6 +680,9 @@ static int nfs_init_server(struct nfs_server *server,
@@ -666,6 +692,9 @@ static int nfs_init_server(struct nfs_server *server,
.net = data->net,
.timeparms = &timeparms,
.init_flags = (1UL << NFS_CS_REUSEPORT),
@ -65,10 +82,10 @@ index 7d02dc52209d..50820a8a684a 100644
int error;
diff --git a/fs/nfs/enfs_adapter.c b/fs/nfs/enfs_adapter.c
new file mode 100644
index 000000000000..7fde5b6fae90
index 000000000..e0f3841c1
--- /dev/null
+++ b/fs/nfs/enfs_adapter.c
@@ -0,0 +1,273 @@
@@ -0,0 +1,276 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Client-side ENFS adapter.
@ -285,7 +302,8 @@ index 000000000000..7fde5b6fae90
+{
+ int ret = 0;
+ struct enfs_adapter_ops *ops;
+ struct nfs_parsed_mount_data *parsed_data = (struct nfs_parsed_mount_data *)data;
+ struct nfs_parsed_mount_data *parsed_data =
+ (struct nfs_parsed_mount_data *)data;
+
+ if (!parsed_data->enfs_option)
+ return 0;
@ -295,7 +313,8 @@ index 000000000000..7fde5b6fae90
+
+ ops = nfs_multipath_router_get();
+ if (ops != NULL && ops->remount_ip_list != NULL)
+ ret = ops->remount_ip_list(nfs_client, parsed_data->enfs_option);
+ ret = ops->remount_ip_list(nfs_client,
+ parsed_data->enfs_option);
+ nfs_multipath_router_put(ops);
+ return ret;
+}
@ -312,9 +331,10 @@ index 000000000000..7fde5b6fae90
+{
+ char *string;
+ int rc;
+
+ string = match_strdup(args);
+ if (string == NULL) {
+ printk(KERN_INFO "NFS: not enough memory to parse option\n");
+ pr_info("NFS: not enough memory to parse option\n");
+ return 0;
+ }
+ rc = enfs_parse_mount_options(get_nfs_multi_path_opt(token),
@ -325,26 +345,26 @@ index 000000000000..7fde5b6fae90
+ case 0:
+ return 1;
+ case -ENOMEM:
+ printk(KERN_INFO "NFS: not enough memory to parse option\n");
+ pr_info("NFS: not enough memory to parse option\n");
+ return 0;
+ case -ENOSPC:
+ printk(KERN_INFO "NFS: param is more than supported limit: %d\n", rc);
+ pr_info("NFS: param is more than supported limit: %d\n", rc);
+ return 0;
+ case -EINVAL:
+ printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
+ pr_info("NFS: bad IP address specified: %s\n", p);
+ return 0;
+ case -ENOTSUPP:
+ printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
+ pr_info("NFS: bad IP address specified: %s\n", p);
+ return 0;
+ case -EOPNOTSUPP:
+ printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
+ pr_info("NFS: bad IP address specified: %s\n", p);
+ return 0;
+ }
+ return 1;
+}
diff --git a/fs/nfs/enfs_adapter.h b/fs/nfs/enfs_adapter.h
new file mode 100644
index 000000000000..c7483ca1222a
index 000000000..98b4e3292
--- /dev/null
+++ b/fs/nfs/enfs_adapter.h
@@ -0,0 +1,116 @@
@ -465,7 +485,7 @@ index 000000000000..c7483ca1222a
+#endif // CONFIG_ENFS
+#endif // _NFS_MULTIPATH_H_
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 0ce5a90640c4..84ac82dbb300 100644
index 0ce5a9064..84ac82dbb 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -93,6 +93,9 @@ struct nfs_client_initdata {
@ -500,7 +520,7 @@ index 0ce5a90640c4..84ac82dbb300 100644
extern void nfs_start_io_read(struct inode *inode);
extern void nfs_end_io_read(struct inode *inode);
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 1350ea673672..f97646b9882e 100644
index 1350ea673..f97646b98 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -10,7 +10,7 @@
@ -612,7 +632,7 @@ index 1350ea673672..f97646b9882e 100644
if (error != 0) {
nfs_server_insert_lists(server);
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index a05e1eb2c3fd..f26bdaa45fca 100644
index a05e1eb2c..168da9700 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -51,7 +51,6 @@
@ -727,7 +747,7 @@ index a05e1eb2c3fd..f26bdaa45fca 100644
+ case Opt_remote_dnslist:
+ rc = enfs_check_mount_parse_info(p,
+ token, mnt, args);
+ if (rc != 1)
+ if (rc != 1)
+ return rc;
+ break;
+ case Opt_enfs_info:
@ -757,7 +777,7 @@ index a05e1eb2c3fd..f26bdaa45fca 100644
return error;
}
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 7023ae64e3d7..2c19678afe8d 100644
index 7023ae64e..2c19678af 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -123,6 +123,11 @@ struct nfs_client {

View File

@ -1,5 +1,5 @@
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 8aa865bce4f6..89178f78de8c 100644
index 8aa865b..0425aaa 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -70,6 +70,10 @@ struct rpc_clnt {
@ -23,7 +23,7 @@ index 8aa865bce4f6..89178f78de8c 100644
};
struct rpc_add_xprt_test {
@@ -221,6 +228,12 @@ bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
@@ -221,6 +228,13 @@ bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
const struct sockaddr *sap);
void rpc_cleanup_clids(void);
@ -31,13 +31,14 @@ index 8aa865bce4f6..89178f78de8c 100644
+int
+rpc_clnt_test_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
+ const struct rpc_call_ops *ops, void *data, int flags);
+struct rpc_xprt *rpc_task_get_next_xprt(struct rpc_clnt *clnt);
+#endif /* CONFIG_ENFS */
+
static inline int rpc_reply_expected(struct rpc_task *task)
{
return (task->tk_msg.rpc_proc != NULL) &&
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index ad2e243f3f03..124f5a0faf3e 100644
index ad2e243..124f5a0 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -90,6 +90,9 @@ struct rpc_task {
@ -72,10 +73,10 @@ index ad2e243f3f03..124f5a0faf3e 100644
{
diff --git a/include/linux/sunrpc/sunrpc_enfs_adapter.h b/include/linux/sunrpc/sunrpc_enfs_adapter.h
new file mode 100644
index 000000000000..28abedcf5cf6
index 0000000..cdd7fa6
--- /dev/null
+++ b/include/linux/sunrpc/sunrpc_enfs_adapter.h
@@ -0,0 +1,128 @@
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Client-side SUNRPC ENFS adapter header.
+ * Copyright (c) 2023. Huawei Technologies Co., Ltd. All rights reserved.
@ -112,6 +113,7 @@ index 000000000000..28abedcf5cf6
+ void (*adjust_task_timeout)(struct rpc_task *task, void *condition);
+ void (*init_task_req)(struct rpc_task *task, struct rpc_rqst *req);
+ bool (*prepare_transmit)(struct rpc_task *task);
+ void (*set_transport)(struct rpc_task *task, struct rpc_clnt *clnt);
+};
+
+extern struct rpc_multipath_ops __rcu *multipath_ops;
@ -134,7 +136,8 @@ index 000000000000..28abedcf5cf6
+void rpc_multipath_ops_init_task_req(struct rpc_task *task,
+ struct rpc_rqst *req);
+bool rpc_multipath_ops_prepare_transmit(struct rpc_task *task);
+
+void rpc_multipath_ops_set_transport(struct rpc_task *task,
+ struct rpc_clnt *clnt);
+#else
+static inline struct rpc_xprt *rpc_task_get_xprt(struct rpc_clnt *clnt,
+ struct rpc_xprt *xprt)
@ -202,10 +205,15 @@ index 000000000000..28abedcf5cf6
+ return false;
+}
+
+static inline void
+rpc_multipath_ops_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
+{
+}
+
+#endif
+#endif // _SUNRPC_ENFS_ADAPTER_H_
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
index ccfacca1eba9..2e47b3577947 100644
index ccfacca..2e47b35 100644
--- a/include/linux/sunrpc/xprt.h
+++ b/include/linux/sunrpc/xprt.h
@@ -279,6 +279,10 @@ struct rpc_xprt {
@ -220,21 +228,22 @@ index ccfacca1eba9..2e47b3577947 100644
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
diff --git a/include/linux/sunrpc/xprtmultipath.h b/include/linux/sunrpc/xprtmultipath.h
index af1257c030d2..d54e4dbbbf34 100644
index af1257c..5677a46 100644
--- a/include/linux/sunrpc/xprtmultipath.h
+++ b/include/linux/sunrpc/xprtmultipath.h
@@ -22,6 +22,10 @@ struct rpc_xprt_switch {
@@ -22,6 +22,11 @@ struct rpc_xprt_switch {
const struct rpc_xprt_iter_ops *xps_iter_ops;
struct rcu_head xps_rcu;
+#if IS_ENABLED(CONFIG_ENFS)
+ unsigned int xps_nactive;
+ atomic_long_t xps_queuelen;
+ unsigned long xps_tmp_time;
+#endif
};
struct rpc_xprt_iter {
@@ -69,4 +73,8 @@ extern struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi);
@@ -69,4 +74,8 @@ extern struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi);
extern bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps,
const struct sockaddr *sap);
@ -244,7 +253,7 @@ index af1257c030d2..d54e4dbbbf34 100644
+#endif
#endif
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 0fc540b0d183..5ad3f18eb1c0 100644
index 0fc540b..ebdcd02 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -37,6 +37,7 @@
@ -297,28 +306,30 @@ index 0fc540b0d183..5ad3f18eb1c0 100644
if (clnt != NULL) {
/* Remove from client task list */
spin_lock(&clnt->cl_lock);
@@ -999,14 +1014,29 @@ void rpc_task_release_client(struct rpc_task *task)
@@ -999,14 +1014,31 @@ void rpc_task_release_client(struct rpc_task *task)
rpc_release_client(clnt);
}
- rpc_task_release_transport(task);
+
+
+ if (!IS_ENABLED(CONFIG_ENFS))
+ rpc_task_release_transport(task);
+
}
+#if IS_ENABLED(CONFIG_ENFS)
+static struct rpc_xprt *
+struct rpc_xprt *
+rpc_task_get_next_xprt(struct rpc_clnt *clnt)
+{
+ return rpc_task_get_xprt(clnt, xprt_iter_get_next(&clnt->cl_xpi));
+}
+EXPORT_SYMBOL_GPL(rpc_task_get_next_xprt);
+#endif
+
static
void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
{
+ rpc_multipath_ops_set_transport(task, clnt);
if (!task->tk_xprt)
+#if IS_ENABLED(CONFIG_ENFS)
+ task->tk_xprt = rpc_task_get_next_xprt(clnt);
@ -328,7 +339,7 @@ index 0fc540b0d183..5ad3f18eb1c0 100644
}
static
@@ -1597,6 +1627,14 @@ call_reserveresult(struct rpc_task *task)
@@ -1597,6 +1629,14 @@ call_reserveresult(struct rpc_task *task)
return;
case -EIO: /* probably a shutdown */
break;
@ -343,7 +354,7 @@ index 0fc540b0d183..5ad3f18eb1c0 100644
default:
printk(KERN_ERR "%s: unrecognized error %d, exiting\n",
__func__, status);
@@ -1962,6 +2000,10 @@ call_transmit(struct rpc_task *task)
@@ -1962,6 +2002,10 @@ call_transmit(struct rpc_task *task)
return;
if (!xprt_prepare_transmit(task))
return;
@ -354,7 +365,7 @@ index 0fc540b0d183..5ad3f18eb1c0 100644
task->tk_action = call_transmit_status;
/* Encode here so that rpcsec_gss can use correct sequence number. */
if (rpc_task_need_encode(task)) {
@@ -2277,6 +2319,7 @@ call_timeout(struct rpc_task *task)
@@ -2277,6 +2321,7 @@ call_timeout(struct rpc_task *task)
retry:
task->tk_action = call_bind;
@ -362,7 +373,21 @@ index 0fc540b0d183..5ad3f18eb1c0 100644
task->tk_status = 0;
}
@@ -2961,3 +3004,30 @@ rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
@@ -2798,8 +2843,12 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
xprt->ops->set_connect_timeout(xprt,
connect_timeout,
reconnect_timeout);
-
+#if IS_ENABLED(CONFIG_ENFS)
+ if (!clnt->cl_enfs)
+ rpc_xprt_switch_set_roundrobin(xps);
+#else
rpc_xprt_switch_set_roundrobin(xps);
+#endif
if (setup) {
ret = setup(clnt, xps, xprt, data);
if (ret != 0)
@@ -2961,3 +3010,30 @@ rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
}
EXPORT_SYMBOL_GPL(rpc_clnt_swap_deactivate);
#endif /* CONFIG_SUNRPC_SWAP */
@ -394,7 +419,7 @@ index 0fc540b0d183..5ad3f18eb1c0 100644
+EXPORT_SYMBOL_GPL(rpc_clnt_test_xprt);
+#endif
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index a873c92a4898..2254fea0e863 100644
index a873c92..2254fea 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -20,7 +20,7 @@
@ -421,10 +446,10 @@ index a873c92a4898..2254fea0e863 100644
task->tk_action = rpc_prepare_task;
diff --git a/net/sunrpc/sunrpc_enfs_adapter.c b/net/sunrpc/sunrpc_enfs_adapter.c
new file mode 100644
index 000000000000..c1543545c6de
index 0000000..106ad73
--- /dev/null
+++ b/net/sunrpc/sunrpc_enfs_adapter.c
@@ -0,0 +1,214 @@
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Client-side SUNRPC ENFS adapter header.
+ * Copyright (c) 2023. Huawei Technologies Co., Ltd. All rights reserved.
@ -639,8 +664,19 @@ index 000000000000..c1543545c6de
+ rpc_multipath_ops_put(mops);
+ return false;
+}
+
+void rpc_multipath_ops_set_transport(struct rpc_task *task,
+ struct rpc_clnt *clnt)
+{
+ struct rpc_multipath_ops *mops = NULL;
+
+ mops = rpc_multipath_ops_get();
+ if (mops && mops->set_transport)
+ mops->set_transport(task, clnt);
+ rpc_multipath_ops_put(mops);
+}
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index c912bf20faa2..c2b63b3d5217 100644
index c912bf2..c2b63b3 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -48,6 +48,7 @@
@ -651,7 +687,7 @@ index c912bf20faa2..c2b63b3d5217 100644
#include <linux/rcupdate.h>
#include <trace/events/sunrpc.h>
@@ -259,6 +260,9 @@ int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
@@ -259,6 +260,9 @@ out_sleep:
dprintk("RPC: %5u failed to lock transport %p\n",
task->tk_pid, xprt);
task->tk_timeout = 0;
@ -721,7 +757,7 @@ index c912bf20faa2..c2b63b3d5217 100644
* Tear down transport state and free the rpc_xprt
*/
diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c
index 6ebaa58b4eff..f6a004ee7a27 100644
index 6ebaa58..f6a004e 100644
--- a/net/sunrpc/xprtmultipath.c
+++ b/net/sunrpc/xprtmultipath.c
@@ -18,6 +18,7 @@

View File

@ -1,9 +1,9 @@
diff --git a/fs/nfs/enfs/enfs_multipath.c b/fs/nfs/enfs/enfs_multipath.c
new file mode 100644
index 000000000000..7a58cab74869
index 000000000..d49dc91e1
--- /dev/null
+++ b/fs/nfs/enfs/enfs_multipath.c
@@ -0,0 +1,627 @@
@@ -0,0 +1,654 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
@ -60,19 +60,43 @@ index 000000000000..7a58cab74869
+
+static DECLARE_WAIT_QUEUE_HEAD(path_attach_wait_queue);
+
+
+static void sockaddr_set_port(struct sockaddr *addr, int port)
+/**
+ * set socket port.
+ * @ns: need transform to network byte order
+ */
+static void sockaddr_set_port(struct sockaddr *addr, __be16 port, bool ns)
+{
+ switch (addr->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)addr)->sin_port = htons(port);
+ ((struct sockaddr_in *)addr)->sin_port =
+ ns ? htons(port) : port;
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
+ ((struct sockaddr_in6 *)addr)->sin6_port =
+ ns ? htons(port) : port;
+ break;
+ }
+}
+
+static __be16 get_rpc_clnt_port(struct rpc_clnt *clnt)
+{
+ struct sockaddr_storage ss;
+ struct sockaddr *addr = (struct sockaddr *)&ss;
+
+ rpc_peeraddr(clnt, (struct sockaddr *)&ss, sizeof(ss));
+ switch (addr->sa_family) {
+ case AF_INET:
+ return ((struct sockaddr_in *)addr)->sin_port;
+
+ case AF_INET6:
+ return ((struct sockaddr_in6 *)addr)->sin6_port;
+
+ default:
+ enfs_log_error("not support family:%d.\n", addr->sa_family);
+ return -1;
+ }
+}
+
+static int sockaddr_ip_to_str(struct sockaddr *addr, char *buf, int len)
+{
+ switch (addr->sa_family) {
@ -176,12 +200,14 @@ index 000000000000..7a58cab74869
+ struct xprt_attach_info *attach_info)
+{
+ int err = 0;
+ __be16 port;
+
+ xprtargs->srcaddr = (struct sockaddr *)attach_info->localAddress;
+ xprtargs->dstaddr = (struct sockaddr *)attach_info->remoteAddress;
+
+ sockaddr_set_port((struct sockaddr *)attach_info->localAddress, 2049);
+ sockaddr_set_port((struct sockaddr *)attach_info->remoteAddress, 2049);
+ port = get_rpc_clnt_port(clnt);
+ sockaddr_set_port((struct sockaddr *)attach_info->remoteAddress, port,
+ false);
+ print_enfs_multipath_addr((struct sockaddr *)attach_info->localAddress,
+ (struct sockaddr *)attach_info->remoteAddress);
+
@ -634,7 +660,7 @@ index 000000000000..7a58cab74869
+}
diff --git a/fs/nfs/enfs/enfs_multipath.h b/fs/nfs/enfs/enfs_multipath.h
new file mode 100644
index 000000000000..3c58b0c4cdf7
index 000000000..3c58b0c4c
--- /dev/null
+++ b/fs/nfs/enfs/enfs_multipath.h
@@ -0,0 +1,23 @@
@ -663,7 +689,7 @@ index 000000000000..3c58b0c4cdf7
+#endif // ENFS_MULTIPATH_H
diff --git a/fs/nfs/enfs/enfs_path.c b/fs/nfs/enfs/enfs_path.c
new file mode 100644
index 000000000000..7355f8c2f672
index 000000000..7355f8c2f
--- /dev/null
+++ b/fs/nfs/enfs/enfs_path.c
@@ -0,0 +1,47 @@
@ -716,7 +742,7 @@ index 000000000000..7355f8c2f672
+}
diff --git a/fs/nfs/enfs/enfs_path.h b/fs/nfs/enfs/enfs_path.h
new file mode 100644
index 000000000000..97b1ef3730b8
index 000000000..97b1ef373
--- /dev/null
+++ b/fs/nfs/enfs/enfs_path.h
@@ -0,0 +1,12 @@
@ -734,7 +760,7 @@ index 000000000000..97b1ef3730b8
+#endif // ENFS_PATH_H
diff --git a/fs/nfs/enfs/enfs_proc.c b/fs/nfs/enfs/enfs_proc.c
new file mode 100644
index 000000000000..53fa1a07642f
index 000000000..53fa1a076
--- /dev/null
+++ b/fs/nfs/enfs/enfs_proc.c
@@ -0,0 +1,545 @@
@ -1285,7 +1311,7 @@ index 000000000000..53fa1a07642f
+}
diff --git a/fs/nfs/enfs/enfs_proc.h b/fs/nfs/enfs/enfs_proc.h
new file mode 100644
index 000000000000..321951031c2e
index 000000000..321951031
--- /dev/null
+++ b/fs/nfs/enfs/enfs_proc.h
@@ -0,0 +1,21 @@
@ -1312,7 +1338,7 @@ index 000000000000..321951031c2e
+#endif
diff --git a/fs/nfs/enfs/enfs_remount.c b/fs/nfs/enfs/enfs_remount.c
new file mode 100644
index 000000000000..3b7d6a03d78a
index 000000000..3b7d6a03d
--- /dev/null
+++ b/fs/nfs/enfs/enfs_remount.c
@@ -0,0 +1,220 @@
@ -1538,7 +1564,7 @@ index 000000000000..3b7d6a03d78a
+}
diff --git a/fs/nfs/enfs/enfs_remount.h b/fs/nfs/enfs/enfs_remount.h
new file mode 100644
index 000000000000..c7a1dcbb65b9
index 000000000..c7a1dcbb6
--- /dev/null
+++ b/fs/nfs/enfs/enfs_remount.h
@@ -0,0 +1,14 @@
@ -1558,7 +1584,7 @@ index 000000000000..c7a1dcbb65b9
+#endif
diff --git a/fs/nfs/enfs/enfs_roundrobin.c b/fs/nfs/enfs/enfs_roundrobin.c
new file mode 100644
index 000000000000..4e4eda784a3e
index 000000000..4e4eda784
--- /dev/null
+++ b/fs/nfs/enfs/enfs_roundrobin.c
@@ -0,0 +1,255 @@
@ -1819,7 +1845,7 @@ index 000000000000..4e4eda784a3e
+};
diff --git a/fs/nfs/enfs/enfs_roundrobin.h b/fs/nfs/enfs/enfs_roundrobin.h
new file mode 100644
index 000000000000..b72b088a6258
index 000000000..b72b088a6
--- /dev/null
+++ b/fs/nfs/enfs/enfs_roundrobin.h
@@ -0,0 +1,9 @@

View File

@ -1,6 +1,6 @@
diff --git a/fs/nfs/enfs/enfs_config.c b/fs/nfs/enfs/enfs_config.c
new file mode 100644
index 000000000000..a0ca93114a92
index 000000000..a0ca93114
--- /dev/null
+++ b/fs/nfs/enfs/enfs_config.c
@@ -0,0 +1,378 @@
@ -384,7 +384,7 @@ index 000000000000..a0ca93114a92
+}
diff --git a/fs/nfs/enfs/enfs_config.h b/fs/nfs/enfs/enfs_config.h
new file mode 100644
index 000000000000..4eff0ccc3e01
index 000000000..4eff0ccc3
--- /dev/null
+++ b/fs/nfs/enfs/enfs_config.h
@@ -0,0 +1,31 @@
@ -421,7 +421,7 @@ index 000000000000..4eff0ccc3e01
+#endif // ENFS_CONFIG_H
diff --git a/fs/nfs/enfs/enfs_errcode.h b/fs/nfs/enfs/enfs_errcode.h
new file mode 100644
index 000000000000..ffa0890889cf
index 000000000..ffa089088
--- /dev/null
+++ b/fs/nfs/enfs/enfs_errcode.h
@@ -0,0 +1,16 @@
@ -443,7 +443,7 @@ index 000000000000..ffa0890889cf
+#endif // ENFS_ERRCODE_H
diff --git a/fs/nfs/enfs/enfs_log.h b/fs/nfs/enfs/enfs_log.h
new file mode 100644
index 000000000000..e12f8f3aefca
index 000000000..e12f8f3ae
--- /dev/null
+++ b/fs/nfs/enfs/enfs_log.h
@@ -0,0 +1,24 @@
@ -473,7 +473,7 @@ index 000000000000..e12f8f3aefca
+#endif // ENFS_ERRCODE_H
diff --git a/fs/nfs/enfs/failover_com.h b/fs/nfs/enfs/failover_com.h
new file mode 100644
index 000000000000..c52940da232e
index 000000000..c52940da2
--- /dev/null
+++ b/fs/nfs/enfs/failover_com.h
@@ -0,0 +1,23 @@
@ -502,10 +502,10 @@ index 000000000000..c52940da232e
+#endif // FAILOVER_COMMON_H
diff --git a/fs/nfs/enfs/failover_path.c b/fs/nfs/enfs/failover_path.c
new file mode 100644
index 000000000000..dadb913b94d2
index 000000000..2f5387216
--- /dev/null
+++ b/fs/nfs/enfs/failover_path.c
@@ -0,0 +1,206 @@
@@ -0,0 +1,212 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
@ -534,10 +534,16 @@ index 000000000000..dadb913b94d2
+
+static void failover_retry_path(struct rpc_task *task)
+{
+ xprt_release(task);
+ rpc_init_task_retry_counters(task);
+ rpc_task_release_transport(task);
+ rpc_restart_call(task);
+ int ret;
+
+ ret = rpc_restart_call(task);
+
+ if (ret == 1) {
+ xprt_release(task);
+ rpc_init_task_retry_counters(task);
+ rpc_task_release_transport(task);
+ task->tk_xprt = rpc_task_get_next_xprt(task->tk_client);
+ }
+}
+
+static void failover_retry_path_delay(struct rpc_task *task, int32_t delay)
@ -714,7 +720,7 @@ index 000000000000..dadb913b94d2
+}
diff --git a/fs/nfs/enfs/failover_path.h b/fs/nfs/enfs/failover_path.h
new file mode 100644
index 000000000000..180d8dc80673
index 000000000..9159ada07
--- /dev/null
+++ b/fs/nfs/enfs/failover_path.h
@@ -0,0 +1,16 @@
@ -736,7 +742,7 @@ index 000000000000..180d8dc80673
+#endif // FAILOVER_PATH_H
diff --git a/fs/nfs/enfs/failover_time.c b/fs/nfs/enfs/failover_time.c
new file mode 100644
index 000000000000..866ea82d13fc
index 000000000..866ea82d1
--- /dev/null
+++ b/fs/nfs/enfs/failover_time.c
@@ -0,0 +1,99 @@
@ -841,7 +847,7 @@ index 000000000000..866ea82d13fc
+}
diff --git a/fs/nfs/enfs/failover_time.h b/fs/nfs/enfs/failover_time.h
new file mode 100644
index 000000000000..ede25b577a2a
index 000000000..ede25b577
--- /dev/null
+++ b/fs/nfs/enfs/failover_time.h
@@ -0,0 +1,16 @@
@ -863,7 +869,7 @@ index 000000000000..ede25b577a2a
+#endif // FAILOVER_TIME_H
diff --git a/fs/nfs/enfs/init.h b/fs/nfs/enfs/init.h
new file mode 100644
index 000000000000..d81af9b02402
index 000000000..d81af9b02
--- /dev/null
+++ b/fs/nfs/enfs/init.h
@@ -0,0 +1,16 @@
@ -885,7 +891,7 @@ index 000000000000..d81af9b02402
+#endif
diff --git a/fs/nfs/enfs/mgmt_init.c b/fs/nfs/enfs/mgmt_init.c
new file mode 100644
index 000000000000..122790775fe8
index 000000000..122790775
--- /dev/null
+++ b/fs/nfs/enfs/mgmt_init.c
@@ -0,0 +1,21 @@
@ -912,7 +918,7 @@ index 000000000000..122790775fe8
+}
diff --git a/fs/nfs/enfs/mgmt_init.h b/fs/nfs/enfs/mgmt_init.h
new file mode 100644
index 000000000000..779732740008
index 000000000..779732740
--- /dev/null
+++ b/fs/nfs/enfs/mgmt_init.h
@@ -0,0 +1,17 @@
@ -935,7 +941,7 @@ index 000000000000..779732740008
+#endif // MGMT_INIT_H
diff --git a/fs/nfs/enfs/pm_ping.c b/fs/nfs/enfs/pm_ping.c
new file mode 100644
index 000000000000..9ecbe9a7716f
index 000000000..9ecbe9a77
--- /dev/null
+++ b/fs/nfs/enfs/pm_ping.c
@@ -0,0 +1,420 @@
@ -1361,7 +1367,7 @@ index 000000000000..9ecbe9a7716f
+}
diff --git a/fs/nfs/enfs/pm_ping.h b/fs/nfs/enfs/pm_ping.h
new file mode 100644
index 000000000000..8b159b286fba
index 000000000..8b159b286
--- /dev/null
+++ b/fs/nfs/enfs/pm_ping.h
@@ -0,0 +1,32 @@
@ -1399,10 +1405,10 @@ index 000000000000..8b159b286fba
+#endif // PM_PING_H
diff --git a/fs/nfs/enfs/pm_state.c b/fs/nfs/enfs/pm_state.c
new file mode 100644
index 000000000000..8dd520ebfeef
index 000000000..279028dc0
--- /dev/null
+++ b/fs/nfs/enfs/pm_state.c
@@ -0,0 +1,157 @@
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
@ -1462,7 +1468,6 @@ index 000000000000..8dd520ebfeef
+
+ cur_state = atomic_read(&ctx->path_state);
+ if (cur_state == state) {
+ enfs_log_debug("The xprt is already {%d}.\n", state);
+ xprt_put(xprt);
+ return;
+ }
@ -1562,7 +1567,7 @@ index 000000000000..8dd520ebfeef
+}
diff --git a/fs/nfs/enfs/pm_state.h b/fs/nfs/enfs/pm_state.h
new file mode 100644
index 000000000000..469af998d1ef
index 000000000..469af998d
--- /dev/null
+++ b/fs/nfs/enfs/pm_state.h
@@ -0,0 +1,27 @@

View File

@ -32,7 +32,7 @@
Name: kernel
Version: 4.19.90
Release: %{hulkrelease}.0253
Release: %{hulkrelease}.0254
Summary: Linux Kernel
License: GPLv2
URL: http://www.kernel.org/
@ -849,6 +849,9 @@ fi
%endif
%changelog
* Sat Dec 2 2023 Zhang Mingqian <zhangmingqian.zhang@huawei.com> - 4.19.90-2311.5.0.0254
- bug fix for enfs, when diconnect many sockets io is hang
* Tue Nov 28 2023 Yuan Zhang <zhangyuan162@huawei.com> - 4.19.90-2311.5.0.0253
- arm64: cpufeature: Extract capped perfmon fields
- KVM: arm64: limit PMU version to PMUv3 for ARMv8.1
@ -1342,7 +1345,7 @@ fi
- drivers/gmjstcm: fix a dev_err() call in spi tcm device probe
- SCSI: SSSRAID: Support 3SNIC 3S5XX serial RAID/HBA controllers
* TUE Nov 14 2023 YunYi Yang <yangyunyi2@huawei.com> - 4.19.90-2311.2.0.0243
* Tue Nov 14 2023 YunYi Yang <yangyunyi2@huawei.com> - 4.19.90-2311.2.0.0243
- config: arm64: Build HiSilicon SPI/SFC driver as module
- spi: hisi-sfc-v3xx: drop unnecessary ACPI_PTR and related ifendif protection
- spi: hisi-sfc-v3xx: fix potential irq race condition