Skip to content

Commit 9827144

Browse files
author
Trond Myklebust
committed
NFS: Treat ENETUNREACH errors as fatal in containers
Propagate the NFS_MOUNT_NETUNREACH_FATAL flag to work with the generic NFS client. If the flag is set, the client will receive ENETDOWN and ENETUNREACH errors from the RPC layer, and is expected to treat them as being fatal. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Tested-by: Jeff Layton <jlayton@kernel.org> Acked-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 487fae0 commit 9827144

File tree

8 files changed

+39
-9
lines changed

8 files changed

+39
-9
lines changed

fs/nfs/client.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ int nfs_create_rpc_client(struct nfs_client *clp,
546546
args.flags |= RPC_CLNT_CREATE_NOPING;
547547
if (test_bit(NFS_CS_REUSEPORT, &clp->cl_flags))
548548
args.flags |= RPC_CLNT_CREATE_REUSEPORT;
549+
if (test_bit(NFS_CS_NETUNREACH_FATAL, &clp->cl_flags))
550+
args.flags |= RPC_CLNT_CREATE_NETUNREACH_FATAL;
549551

550552
if (!IS_ERR(clp->cl_rpcclient))
551553
return 0;
@@ -709,6 +711,9 @@ static int nfs_init_server(struct nfs_server *server,
709711
if (ctx->flags & NFS_MOUNT_NORESVPORT)
710712
set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
711713

714+
if (ctx->flags & NFS_MOUNT_NETUNREACH_FATAL)
715+
__set_bit(NFS_CS_NETUNREACH_FATAL, &cl_init.init_flags);
716+
712717
/* Allocate or find a client reference we can use */
713718
clp = nfs_get_client(&cl_init);
714719
if (IS_ERR(clp))

fs/nfs/nfs4client.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
233233
__set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags);
234234
if (test_bit(NFS_CS_PNFS, &cl_init->init_flags))
235235
__set_bit(NFS_CS_PNFS, &clp->cl_flags);
236+
if (test_bit(NFS_CS_NETUNREACH_FATAL, &cl_init->init_flags))
237+
__set_bit(NFS_CS_NETUNREACH_FATAL, &clp->cl_flags);
236238
/*
237239
* Set up the connection to the server before we add add to the
238240
* global list.

fs/nfs/nfs4proc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ static int nfs4_map_errors(int err)
195195
return -EBUSY;
196196
case -NFS4ERR_NOT_SAME:
197197
return -ENOTSYNC;
198+
case -ENETDOWN:
199+
case -ENETUNREACH:
200+
break;
198201
default:
199202
dprintk("%s could not handle NFSv4 error %d\n",
200203
__func__, -err);

include/linux/nfs_fs_sb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ struct nfs_client {
5050
#define NFS_CS_DS 7 /* - Server is a DS */
5151
#define NFS_CS_REUSEPORT 8 /* - reuse src port on reconnect */
5252
#define NFS_CS_PNFS 9 /* - Server used for pnfs */
53+
#define NFS_CS_NETUNREACH_FATAL 10 /* - ENETUNREACH errors are fatal */
5354
struct sockaddr_storage cl_addr; /* server identifier */
5455
size_t cl_addrlen;
5556
char * cl_hostname; /* hostname of server */

include/linux/sunrpc/clnt.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ struct rpc_clnt {
6464
cl_noretranstimeo: 1,/* No retransmit timeouts */
6565
cl_autobind : 1,/* use getport() */
6666
cl_chatty : 1,/* be verbose */
67-
cl_shutdown : 1;/* rpc immediate -EIO */
67+
cl_shutdown : 1,/* rpc immediate -EIO */
68+
cl_netunreach_fatal : 1;
69+
/* Treat ENETUNREACH errors as fatal */
6870
struct xprtsec_parms cl_xprtsec; /* transport security policy */
6971

7072
struct rpc_rtt * cl_rtt; /* RTO estimator data */
@@ -175,6 +177,7 @@ struct rpc_add_xprt_test {
175177
#define RPC_CLNT_CREATE_SOFTERR (1UL << 10)
176178
#define RPC_CLNT_CREATE_REUSEPORT (1UL << 11)
177179
#define RPC_CLNT_CREATE_CONNECTED (1UL << 12)
180+
#define RPC_CLNT_CREATE_NETUNREACH_FATAL (1UL << 13)
178181

179182
struct rpc_clnt *rpc_create(struct rpc_create_args *args);
180183
struct rpc_clnt *rpc_bind_new_program(struct rpc_clnt *,

include/linux/sunrpc/sched.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ struct rpc_task_setup {
134134
#define RPC_TASK_MOVEABLE 0x0004 /* nfs4.1+ rpc tasks */
135135
#define RPC_TASK_NULLCREDS 0x0010 /* Use AUTH_NULL credential */
136136
#define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */
137+
#define RPC_TASK_NETUNREACH_FATAL 0x0040 /* ENETUNREACH is fatal */
137138
#define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */
138139
#define RPC_TASK_NO_ROUND_ROBIN 0x0100 /* send requests on "main" xprt */
139140
#define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */

include/trace/events/sunrpc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ TRACE_EVENT(rpc_request,
343343
{ RPC_TASK_MOVEABLE, "MOVEABLE" }, \
344344
{ RPC_TASK_NULLCREDS, "NULLCREDS" }, \
345345
{ RPC_CALL_MAJORSEEN, "MAJORSEEN" }, \
346+
{ RPC_TASK_NETUNREACH_FATAL, "NETUNREACH_FATAL"}, \
346347
{ RPC_TASK_DYNAMIC, "DYNAMIC" }, \
347348
{ RPC_TASK_NO_ROUND_ROBIN, "NO_ROUND_ROBIN" }, \
348349
{ RPC_TASK_SOFT, "SOFT" }, \

net/sunrpc/clnt.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,8 @@ static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
512512
clnt->cl_discrtry = 1;
513513
if (!(args->flags & RPC_CLNT_CREATE_QUIET))
514514
clnt->cl_chatty = 1;
515+
if (args->flags & RPC_CLNT_CREATE_NETUNREACH_FATAL)
516+
clnt->cl_netunreach_fatal = 1;
515517

516518
return clnt;
517519
}
@@ -662,6 +664,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args,
662664
new->cl_noretranstimeo = clnt->cl_noretranstimeo;
663665
new->cl_discrtry = clnt->cl_discrtry;
664666
new->cl_chatty = clnt->cl_chatty;
667+
new->cl_netunreach_fatal = clnt->cl_netunreach_fatal;
665668
new->cl_principal = clnt->cl_principal;
666669
new->cl_max_connect = clnt->cl_max_connect;
667670
return new;
@@ -1195,6 +1198,8 @@ void rpc_task_set_client(struct rpc_task *task, struct rpc_clnt *clnt)
11951198
task->tk_flags |= RPC_TASK_TIMEOUT;
11961199
if (clnt->cl_noretranstimeo)
11971200
task->tk_flags |= RPC_TASK_NO_RETRANS_TIMEOUT;
1201+
if (clnt->cl_netunreach_fatal)
1202+
task->tk_flags |= RPC_TASK_NETUNREACH_FATAL;
11981203
atomic_inc(&clnt->cl_task_count);
11991204
}
12001205

@@ -2102,14 +2107,17 @@ call_bind_status(struct rpc_task *task)
21022107
case -EPROTONOSUPPORT:
21032108
trace_rpcb_bind_version_err(task);
21042109
goto retry_timeout;
2110+
case -ENETDOWN:
2111+
case -ENETUNREACH:
2112+
if (task->tk_flags & RPC_TASK_NETUNREACH_FATAL)
2113+
break;
2114+
fallthrough;
21052115
case -ECONNREFUSED: /* connection problems */
21062116
case -ECONNRESET:
21072117
case -ECONNABORTED:
21082118
case -ENOTCONN:
21092119
case -EHOSTDOWN:
2110-
case -ENETDOWN:
21112120
case -EHOSTUNREACH:
2112-
case -ENETUNREACH:
21132121
case -EPIPE:
21142122
trace_rpcb_unreachable_err(task);
21152123
if (!RPC_IS_SOFTCONN(task)) {
@@ -2191,19 +2199,22 @@ call_connect_status(struct rpc_task *task)
21912199

21922200
task->tk_status = 0;
21932201
switch (status) {
2202+
case -ENETDOWN:
2203+
case -ENETUNREACH:
2204+
if (task->tk_flags & RPC_TASK_NETUNREACH_FATAL)
2205+
break;
2206+
fallthrough;
21942207
case -ECONNREFUSED:
21952208
case -ECONNRESET:
21962209
/* A positive refusal suggests a rebind is needed. */
2197-
if (RPC_IS_SOFTCONN(task))
2198-
break;
21992210
if (clnt->cl_autobind) {
22002211
rpc_force_rebind(clnt);
2212+
if (RPC_IS_SOFTCONN(task))
2213+
break;
22012214
goto out_retry;
22022215
}
22032216
fallthrough;
22042217
case -ECONNABORTED:
2205-
case -ENETDOWN:
2206-
case -ENETUNREACH:
22072218
case -EHOSTUNREACH:
22082219
case -EPIPE:
22092220
case -EPROTO:
@@ -2455,10 +2466,13 @@ call_status(struct rpc_task *task)
24552466
trace_rpc_call_status(task);
24562467
task->tk_status = 0;
24572468
switch(status) {
2458-
case -EHOSTDOWN:
24592469
case -ENETDOWN:
2460-
case -EHOSTUNREACH:
24612470
case -ENETUNREACH:
2471+
if (task->tk_flags & RPC_TASK_NETUNREACH_FATAL)
2472+
goto out_exit;
2473+
fallthrough;
2474+
case -EHOSTDOWN:
2475+
case -EHOSTUNREACH:
24622476
case -EPERM:
24632477
if (RPC_IS_SOFTCONN(task))
24642478
goto out_exit;

0 commit comments

Comments
 (0)