summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trondmy@gmail.com>2019-04-07 13:59:01 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2019-04-25 14:18:14 -0400
commit91a575e1a98451d12df713f267a9a210a9e5dcf9 (patch)
tree89a147e126c5ab04a22041e20fcae2c670e5ec9e
parent7b1355b615c67e8fcbfb508e6baee83aed9dee96 (diff)
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 <trond.myklebust@hammerspace.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/super.c15
-rw-r--r--include/linux/nfs_fs_sb.h1
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,
598 sizeof(server->client->cl_timeout_default)); 598 sizeof(server->client->cl_timeout_default));
599 server->client->cl_timeout = &server->client->cl_timeout_default; 599 server->client->cl_timeout = &server->client->cl_timeout_default;
600 server->client->cl_softrtry = 0; 600 server->client->cl_softrtry = 0;
601 if (server->flags & NFS_MOUNT_SOFTERR)
602 server->client->cl_softerr = 1;
601 if (server->flags & NFS_MOUNT_SOFT) 603 if (server->flags & NFS_MOUNT_SOFT)
602 server->client->cl_softrtry = 1; 604 server->client->cl_softrtry = 1;
603 605
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 @@
78 78
79enum { 79enum {
80 /* Mount options that take no arguments */ 80 /* Mount options that take no arguments */
81 Opt_soft, Opt_hard, 81 Opt_soft, Opt_softerr, Opt_hard,
82 Opt_posix, Opt_noposix, 82 Opt_posix, Opt_noposix,
83 Opt_cto, Opt_nocto, 83 Opt_cto, Opt_nocto,
84 Opt_ac, Opt_noac, 84 Opt_ac, Opt_noac,
@@ -125,6 +125,7 @@ static const match_table_t nfs_mount_option_tokens = {
125 { Opt_sloppy, "sloppy" }, 125 { Opt_sloppy, "sloppy" },
126 126
127 { Opt_soft, "soft" }, 127 { Opt_soft, "soft" },
128 { Opt_softerr, "softerr" },
128 { Opt_hard, "hard" }, 129 { Opt_hard, "hard" },
129 { Opt_deprecated, "intr" }, 130 { Opt_deprecated, "intr" },
130 { Opt_deprecated, "nointr" }, 131 { Opt_deprecated, "nointr" },
@@ -628,7 +629,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
628 const char *str; 629 const char *str;
629 const char *nostr; 630 const char *nostr;
630 } nfs_info[] = { 631 } nfs_info[] = {
631 { NFS_MOUNT_SOFT, ",soft", ",hard" }, 632 { NFS_MOUNT_SOFT, ",soft", "" },
633 { NFS_MOUNT_SOFTERR, ",softerr", "" },
632 { NFS_MOUNT_POSIX, ",posix", "" }, 634 { NFS_MOUNT_POSIX, ",posix", "" },
633 { NFS_MOUNT_NOCTO, ",nocto", "" }, 635 { NFS_MOUNT_NOCTO, ",nocto", "" },
634 { NFS_MOUNT_NOAC, ",noac", "" }, 636 { NFS_MOUNT_NOAC, ",noac", "" },
@@ -658,6 +660,8 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
658 seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ); 660 seq_printf(m, ",acdirmin=%u", nfss->acdirmin/HZ);
659 if (nfss->acdirmax != NFS_DEF_ACDIRMAX*HZ || showdefaults) 661 if (nfss->acdirmax != NFS_DEF_ACDIRMAX*HZ || showdefaults)
660 seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ); 662 seq_printf(m, ",acdirmax=%u", nfss->acdirmax/HZ);
663 if (!(nfss->flags & (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR)))
664 seq_puts(m, ",hard");
661 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) { 665 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
662 if (nfss->flags & nfs_infop->flag) 666 if (nfss->flags & nfs_infop->flag)
663 seq_puts(m, nfs_infop->str); 667 seq_puts(m, nfs_infop->str);
@@ -1239,10 +1243,15 @@ static int nfs_parse_mount_options(char *raw,
1239 */ 1243 */
1240 case Opt_soft: 1244 case Opt_soft:
1241 mnt->flags |= NFS_MOUNT_SOFT; 1245 mnt->flags |= NFS_MOUNT_SOFT;
1246 mnt->flags &= ~NFS_MOUNT_SOFTERR;
1242 break; 1247 break;
1243 case Opt_hard: 1248 case Opt_softerr:
1249 mnt->flags |= NFS_MOUNT_SOFTERR;
1244 mnt->flags &= ~NFS_MOUNT_SOFT; 1250 mnt->flags &= ~NFS_MOUNT_SOFT;
1245 break; 1251 break;
1252 case Opt_hard:
1253 mnt->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR);
1254 break;
1246 case Opt_posix: 1255 case Opt_posix:
1247 mnt->flags |= NFS_MOUNT_POSIX; 1256 mnt->flags |= NFS_MOUNT_POSIX;
1248 break; 1257 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 {
147#define NFS_MOUNT_LEGACY_INTERFACE 0x80000 147#define NFS_MOUNT_LEGACY_INTERFACE 0x80000
148#define NFS_MOUNT_LOCAL_FLOCK 0x100000 148#define NFS_MOUNT_LOCAL_FLOCK 0x100000
149#define NFS_MOUNT_LOCAL_FCNTL 0x200000 149#define NFS_MOUNT_LOCAL_FCNTL 0x200000
150#define NFS_MOUNT_SOFTERR 0x400000
150 151
151 unsigned int caps; /* server capabilities */ 152 unsigned int caps; /* server capabilities */
152 unsigned int rsize; /* read size */ 153 unsigned int rsize; /* read size */