From 91a575e1a98451d12df713f267a9a210a9e5dcf9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 7 Apr 2019 13:59:01 -0400 Subject: [PATCH] NFS: Add a mount option "softerr" to allow clients to see ETIMEDOUT errors Add a mount option that exposes the ETIMEDOUT errors that occur during soft timeouts to the application. This allows aware applications to distinguish between server disk IO errors and client timeout errors. Signed-off-by: Trond Myklebust Signed-off-by: Anna Schumaker --- fs/nfs/client.c | 2 ++ fs/nfs/super.c | 15 ++++++++++++--- include/linux/nfs_fs_sb.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 90d71fda65ce..f74638c5e5b4 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -598,6 +598,8 @@ int nfs_init_server_rpcclient(struct nfs_server *server, sizeof(server->client->cl_timeout_default)); server->client->cl_timeout = &server->client->cl_timeout_default; server->client->cl_softrtry = 0; + if (server->flags & NFS_MOUNT_SOFTERR) + server->client->cl_softerr = 1; if (server->flags & NFS_MOUNT_SOFT) server->client->cl_softrtry = 1; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index c27ac96a95bd..19783e8ba9fb 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -78,7 +78,7 @@ enum { /* Mount options that take no arguments */ - Opt_soft, Opt_hard, + Opt_soft, Opt_softerr, Opt_hard, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, Opt_noac, @@ -125,6 +125,7 @@ static const match_table_t nfs_mount_option_tokens = { { Opt_sloppy, "sloppy" }, { Opt_soft, "soft" }, + { Opt_softerr, "softerr" }, { Opt_hard, "hard" }, { Opt_deprecated, "intr" }, { Opt_deprecated, "nointr" }, @@ -628,7 +629,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, const char *str; const char *nostr; } nfs_info[] = { - { NFS_MOUNT_SOFT, ",soft", ",hard" }, + { NFS_MOUNT_SOFT, ",soft", "" }, + { NFS_MOUNT_SOFTERR, ",softerr", "" }, { NFS_MOUNT_POSIX, ",posix", "" }, { NFS_MOUNT_NOCTO, ",nocto", "" }, { NFS_MOUNT_NOAC, ",noac", "" }, @@ -658,6 +660,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ); if (nfss->acdirmax != NFS_DEF_ACDIRMAX*HZ || showdefaults) seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ); + if (!(nfss->flags & (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))) + seq_puts(m, ",hard"); for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { if (nfss->flags & nfs_infop->flag) seq_puts(m, nfs_infop->str); @@ -1239,10 +1243,15 @@ static int nfs_parse_mount_options(char *raw, */ case Opt_soft: mnt->flags |= NFS_MOUNT_SOFT; + mnt->flags &= ~NFS_MOUNT_SOFTERR; break; - case Opt_hard: + case Opt_softerr: + mnt->flags |= NFS_MOUNT_SOFTERR; mnt->flags &= ~NFS_MOUNT_SOFT; break; + case Opt_hard: + mnt->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR); + break; case Opt_posix: mnt->flags |= NFS_MOUNT_POSIX; break; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 013ac5b54a09..0fbc5d3c5e53 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -147,6 +147,7 @@ struct nfs_server { #define NFS_MOUNT_LEGACY_INTERFACE 0x80000 #define NFS_MOUNT_LOCAL_FLOCK 0x100000 #define NFS_MOUNT_LOCAL_FCNTL 0x200000 +#define NFS_MOUNT_SOFTERR 0x400000 unsigned int caps; /* server capabilities */ unsigned int rsize; /* read size */ -- 2.30.2