From: Joshua Watt <jpewhacker@gmail.com>
To: Chuck Lever <chuck.lever@oracle.com>
Cc: NeilBrown <neilb@suse.com>, Jeff Layton <jlayton@redhat.com>,
Trond Myklebust <trond.myklebust@primarydata.com>,
Linux NFS Mailing List <linux-nfs@vger.kernel.org>,
Al Viro <viro@zeniv.linux.org.uk>,
Bruce Fields <bfields@fieldses.org>,
David Howells <dhowells@redhat.com>
Subject: Re: [RFC v2 5/7] NFS: Add serverfailed mount option
Date: Mon, 13 Nov 2017 10:29:39 -0600 [thread overview]
Message-ID: <1510590579.2495.55.camel@gmail.com> (raw)
In-Reply-To: <73D48532-9CCD-47D4-B016-C317E4F93B68@oracle.com>
On Fri, 2017-11-10 at 17:45 -0500, Chuck Lever wrote:
> > On Nov 10, 2017, at 5:37 PM, Joshua Watt <jpewhacker@gmail.com>
> > wrote:
> >
> > Specifying the serverfailed mount option causes all subsequent RPC
> > tasks
> > that are queued to fail with -EIO instead of timing out. For
> > example, if
> > a server has disappeared, the sequence:
> >
> > mount -o remount,serverfailed
> > umount -f
> >
> > will ensure that all pending I/O requests are cancelled, and any
> > new
> > requests will also fail. In the event that the server returns, the
> > flag
> > can be removed with a remount:
> >
> > mount -o remount,noserverfailed
> >
> > Although bringing the server back may result in a loss of data
>
> Hi Joshua, interesting work!
>
> A couple of things I'm wondering:
>
> 1. Does this also change the serverfailed setting on submounts
> (ie mounts that the kernel did when traversing an NFSv4 referral or
> when going from the server's pseudofs into a real fs). These need
> to be unmounted first before the parent mount can be unmounted,
> and in the latter case they would all be backed by the same stuck
> NFS server.
I don't honestly know, but I will find out. Our use case doens't deal
with either of those cases much.
>
> 2. If there is a hanging sync(2), does the umount -f unstick it?
> That seems relevant for Neil's "make shutdown reliable" use case.
> I would like a stuck NFS mount not to result in local file system
> corruption, if possible, during a hard shutdown.
>
Several previous posts have aluded to calling "umount -f" repeatedly to
get a "stuck" NFS mount to actually unmount. This patch set is
effectively a way of automating that process. More formally, the
sequence of commands:
mount PATH -o remount,serverfailed
umount -f PATH
Is closely approximated by:
while(1)
umount2(PATH, MNT_FORCE);
from userspace.
In retrospect, I think that the "umount -f" shouldn't be required after
remount: If the serverfailed mount option is specified it should also
kill all pending RPCs. A umount -f is undesirable, because you may not
actually want to (potentially) unmount the file system just to cancel
the RPCs.
More directly to your question: I don't honestly know if this can
"unstick" a hanging sync(2). If repeatedly calling umount -f will
unstick it, then these patches will exhibit the same behavior. I will
continue to do some research on this, but if anyone knows the answer
they might be able to chime in.
Could you clarify on what you mean by a stuck NFS mount not resulting
in local filesystem corruption? I'm not sure I undertsand well enough
to follow that comment.
Thanks for the feedback
>
> > Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
> > ---
> > fs/nfs/inode.c | 6 ++++++
> > fs/nfs/super.c | 30 +++++++++++++++++++++++++-----
> > include/uapi/linux/nfs_mount.h | 1 +
> > 3 files changed, 32 insertions(+), 5 deletions(-)
> >
> > diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
> > index 134d9f560240..55b7cd40508d 100644
> > --- a/fs/nfs/inode.c
> > +++ b/fs/nfs/inode.c
> > @@ -723,6 +723,12 @@ static void
> > nfs_readdirplus_parent_cache_hit(struct dentry *dentry)
> >
> > static bool nfs_need_revalidate_inode(struct inode *inode)
> > {
> > + /* If the server has failed, it is not going to respond,
> > so don't try
> > + * and revalidated (otherwise, the serverfailed flag can't
> > be cleared by
> > + * a remount)
> > + */
> > + if (NFS_SERVER(inode)->flags & NFS_MOUNT_SERVERFAILED)
> > + return false;
> > if (NFS_I(inode)->cache_validity &
> > (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
> > return true;
> > diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> > index 777a0cc22704..bca38e1cdd85 100644
> > --- a/fs/nfs/super.c
> > +++ b/fs/nfs/super.c
> > @@ -90,6 +90,7 @@ enum {
> > Opt_resvport, Opt_noresvport,
> > Opt_fscache, Opt_nofscache,
> > Opt_migration, Opt_nomigration,
> > + Opt_serverfailed, Opt_noserverfailed,
> >
> > /* Mount options that take integer arguments */
> > Opt_port,
> > @@ -151,6 +152,8 @@ static const match_table_t
> > nfs_mount_option_tokens = {
> > { Opt_nofscache, "nofsc" },
> > { Opt_migration, "migration" },
> > { Opt_nomigration, "nomigration" },
> > + { Opt_serverfailed, "serverfailed" },
> > + { Opt_noserverfailed, "noserverfailed" },
> >
> > { Opt_port, "port=%s" },
> > { Opt_rsize, "rsize=%s" },
> > @@ -637,6 +640,7 @@ static void nfs_show_mount_options(struct
> > seq_file *m, struct nfs_server *nfss,
> > { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
> > { NFS_MOUNT_UNSHARED, ",nosharecache", "" },
> > { NFS_MOUNT_NORESVPORT, ",noresvport", "" },
> > + { NFS_MOUNT_SERVERFAILED, ",serverfailed", "" },
> > { 0, NULL, NULL }
> > };
> > const struct proc_nfs_info *nfs_infop;
> > @@ -1330,6 +1334,11 @@ static int nfs_parse_mount_options(char
> > *raw,
> > case Opt_nomigration:
> > mnt->options &= ~NFS_OPTION_MIGRATION;
> > break;
> > + case Opt_serverfailed:
> > + case Opt_noserverfailed:
> > + set_flag(mnt, NFS_MOUNT_SERVERFAILED,
> > + token == Opt_serverfailed);
> > + break;
> >
> > /*
> > * options that take numeric values
> > @@ -2192,6 +2201,8 @@ static int nfs_validate_text_mount_data(void
> > *options,
> > return -EINVAL;
> > }
> >
> > +#define NFS_REMOUNT_CHANGE_FLAGS (NFS_MOUNT_SERVERFAILED)
> > +
> > #define NFS_REMOUNT_CMP_FLAGMASK ~(NFS_MOUNT_INTR \
> > | NFS_MOUNT_SECURE \
> > | NFS_MOUNT_TCP \
> > @@ -2200,7 +2211,8 @@ static int nfs_validate_text_mount_data(void
> > *options,
> > | NFS_MOUNT_NONLM \
> > | NFS_MOUNT_BROKEN_SUID \
> > | NFS_MOUNT_STRICTLOCK \
> > - | NFS_MOUNT_LEGACY_INTERFACE)
> > + | NFS_MOUNT_LEGACY_INTERFACE \
> > + | NFS_REMOUNT_CHANGE_FLAGS)
> >
> > #define NFS_MOUNT_CMP_FLAGMASK (NFS_REMOUNT_CMP_FLAGMASK & \
> > ~(NFS_MOUNT_UNSHARED | NFS_MOUNT_NORESVPORT))
> > @@ -2209,12 +2221,15 @@ static int
> > nfs_compare_and_set_remount_data(struct nfs_server *nfss,
> > struct nfs_parsed_mount_data *data)
> > {
> > + int changed_flags_mask = data->flags_mask &
> > NFS_REMOUNT_CHANGE_FLAGS;
> > + struct rpc_clnt *cl = nfss->client;
> > +
> > if ((data->flags ^ nfss->flags) & NFS_REMOUNT_CMP_FLAGMASK ||
> > data->rsize != nfss->rsize ||
> > data->wsize != nfss->wsize ||
> > data->version != nfss->nfs_client->rpc_ops->version ||
> > data->minorversion != nfss->nfs_client->cl_minorversion ||
> > - !nfs_auth_info_match(&data->auth_info, nfss->client-
> > >cl_auth->au_flavor) ||
> > + !nfs_auth_info_match(&data->auth_info, cl->cl_auth-
> > >au_flavor) ||
> > data->acregmin != nfss->acregmin / HZ ||
> > data->acregmax != nfss->acregmax / HZ ||
> > data->acdirmin != nfss->acdirmin / HZ ||
> > @@ -2225,13 +2240,16 @@ nfs_compare_and_set_remount_data(struct
> > nfs_server *nfss,
> > (struct sockaddr *)&nfss->nfs_client-
> > >cl_addr))
> > return -EINVAL;
> >
> > - if (data->retrans != nfss->client->cl_timeout->to_retries
> > ||
> > - data->timeo != (10U * nfss->client->cl_timeout-
> > >to_initval / HZ)) {
> > + /* Update flags */
> > + nfss->flags = (nfss->flags & ~changed_flags_mask) |
> > + (data->flags & changed_flags_mask);
> > +
> > + if (data->retrans != cl->cl_timeout->to_retries ||
> > + data->timeo != (10U * cl->cl_timeout->to_initval /
> > HZ)) {
> > /* Note that this will affect all mounts from the same
> > server,
> > * that use the same protocol. The timeouts are always
> > forced
> > * to be the same.
> > */
> > - struct rpc_clnt *cl = nfss->client;
> > if (cl->cl_timeout != &cl->cl_timeout_default)
> > memcpy(&cl->cl_timeout_default, cl->cl_timeout,
> > sizeof(struct rpc_timeout));
> > @@ -2239,6 +2257,8 @@ nfs_compare_and_set_remount_data(struct
> > nfs_server *nfss,
> > cl->cl_timeout_default.to_initval = data->timeo * HZ /
> > 10U;
> > }
> >
> > + cl->cl_kill_new_tasks = !!(nfss->flags &
> > NFS_MOUNT_SERVERFAILED);
> > +
> > return 0;
> > }
> >
> > diff --git a/include/uapi/linux/nfs_mount.h
> > b/include/uapi/linux/nfs_mount.h
> > index e44e00616ab5..8ad931cdca20 100644
> > --- a/include/uapi/linux/nfs_mount.h
> > +++ b/include/uapi/linux/nfs_mount.h
> > @@ -74,5 +74,6 @@ struct nfs_mount_data {
> >
> > #define NFS_MOUNT_LOCAL_FLOCK 0x100000
> > #define NFS_MOUNT_LOCAL_FCNTL 0x200000
> > +#define NFS_MOUNT_SERVERFAILED 0x400000
> >
> > #endif
> > --
> > 2.13.6
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-
> > nfs" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> --
> Chuck Lever
>
>
>
next prev parent reply other threads:[~2017-11-13 16:29 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-10 22:37 [RFC v2 0/7] NFS Force Unmounting Joshua Watt
2017-11-10 22:37 ` [RFC v2 1/7] SUNRPC: Add flag to kill new tasks Joshua Watt
2017-11-10 22:37 ` [RFC v2 2/7] SUNRPC: Expose kill_new_tasks in debugfs Joshua Watt
2017-11-10 22:37 ` [RFC v2 3/7] SUNRPC: Simplify client shutdown Joshua Watt
2017-11-10 22:37 ` [RFC v2 4/7] NFS: Add mount flags mask Joshua Watt
2017-11-10 22:37 ` [RFC v2 5/7] NFS: Add serverfailed mount option Joshua Watt
2017-11-10 22:45 ` Chuck Lever
2017-11-13 16:29 ` Joshua Watt [this message]
2017-11-13 17:23 ` Chuck Lever
2017-11-10 22:37 ` [RFC v2 6/7] NFS: Propagate NFS_MOUNT_UNSHARED to clients Joshua Watt
2017-11-10 22:37 ` [RFC v2 7/7] NFS: Propagate operations to unshared clients Joshua Watt
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=1510590579.2495.55.camel@gmail.com \
--to=jpewhacker@gmail.com \
--cc=bfields@fieldses.org \
--cc=chuck.lever@oracle.com \
--cc=dhowells@redhat.com \
--cc=jlayton@redhat.com \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@suse.com \
--cc=trond.myklebust@primarydata.com \
--cc=viro@zeniv.linux.org.uk \
/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).