Re: [PATCH] NFS: Handle missing attributes in OPEN reply

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Jan 5, 2023 at 10:48 PM NeilBrown <neilb@xxxxxxx> wrote:
>
> On Fri, 06 Jan 2023, Trond Myklebust wrote:
> > On Fri, 2023-01-06 at 09:56 +1100, NeilBrown wrote:
> > > On Wed, 04 Jan 2023, NeilBrown wrote:
> > > > On Wed, 04 Jan 2023, Trond Myklebust wrote:
> > > > > On Wed, 2023-01-04 at 12:01 +1100, NeilBrown wrote:
> > > > > > On Wed, 04 Jan 2023, Trond Myklebust wrote:
> > > > > > >
> > > > > > >
> > > > > > > If the server starts to reply NFS4ERR_STALE to GETATTR
> > > > > > > requests,
> > > > > > > why do
> > > > > > > we care about stateid values? Just mark the inode as stale
> > > > > > > and drop
> > > > > > > it
> > > > > > > on the floor.
> > > > > >
> > > > > > We have a valid state from the server - we really shouldn't
> > > > > > just
> > > > > > ignore
> > > > > > it.
> > > > > >
> > > > > > Maybe it would be OK to mark the inode stale.  I don't know if
> > > > > > various
> > > > > > retry loops abort properly when the inode is stale.
> > > > >
> > > > > Yes, they are all supposed to do that. Otherwise we would end up
> > > > > looping forever in close(), for instance, since the PUTFH,
> > > > > GETATTR and
> > > > > CLOSE can all return NFS4ERR_STALE as well.
> > > >
> > > > To mark the inode as STALE we still need to find the inode, and
> > > > that is
> > > > the key bit missing in the current code.  Once we find the inode,
> > > > we
> > > > could mark it stale, but maybe some other error resulted in the
> > > > missing
> > > > GETATTR...
> > > >
> > > > It might make sense to put the new code in _nfs4_proc_open() after
> > > > the
> > > > explicit nfs4_proc_getattr() fails.  We would need to find the
> > > > inode
> > > > given only the filehandle.  Is there any easy way to do that?
> > > >
> > > > Thanks,
> > > > NeilBrown
> > > >
> > >
> > > I couldn't see a consistent pattern to follow for when to mark an
> > > inode
> > > as stale.  Do this, on top of the previous patch, seem reasonable?
> > >
> > > Thanks,
> > > NeilBrown
> > >
> > >
> > >
> > > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> > > index b441b1d14a50..04497cb42154 100644
> > > --- a/fs/nfs/nfs4proc.c
> > > +++ b/fs/nfs/nfs4proc.c
> > > @@ -489,6 +489,8 @@ static int nfs4_do_handle_exception(struct
> > > nfs_server *server,
> > >                 case -ESTALE:
> > >                         if (inode != NULL && S_ISREG(inode->i_mode))
> > >                                 pnfs_destroy_layout(NFS_I(inode));
> > > +                       if (inode)
> > > +                               nfs_set_inode_stale(inode);
> >
> > This is normally dealt with in the generic code inside
> > nfs_revalidate_inode(). There should be no need to duplicate it here.
> >
> > >                         break;
> > >                 case -NFS4ERR_DELEG_REVOKED:
> > >                 case -NFS4ERR_ADMIN_REVOKED:
> > > @@ -2713,8 +2715,12 @@ static int _nfs4_proc_open(struct
> > > nfs4_opendata *data,
> > >                         return status;
> > >         }
> > >         if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) {
> > > +               struct inode *inode = nfs4_get_inode_by_stateid(
> > > +                       &data->o_res.stateid,
> > > +                       data->owner);
> >
> > There shouldn't be a need to go looking for open descriptors here,
> > because they will hit ESTALE at some point later anyway.
>
> The problem is that they don't hit ESTALE later.  Unless we update our
> stored stateid with the result of the OPEN, we can use the old stateid,
> and get the corresponding error.
>
> The only way to avoid the infinite loop is to either mark the inode as
> stale, or update the state-id.  For either of those we need to find the
> inode.  We don't have fileid so we cannot use iget.  We do have file
> handle and state-id.
>
> Maybe you are saying this is a server bug that the client cannot be
> expect to cope with at all, and that an infinite loop is a valid client
> response to this particular server behaviour.  In that case, I guess no
> patch is needed.

I'm not arguing that the server should do something else. But I would
like to talk about it from the spec perspective. When PUTFH+WRITE is
sent to the server (with an incorrect stateid) and it's processing the
WRITE compound (as the spec doesn't require the server to validate a
filehandle on PUTFH. The spec says PUTFH is to "set" the correct
filehandle), the server is dealing with 2 errors that it can possibly
return to the client ERR_STALE and ERR_OLD_STATEID. There is nothing
in the spec that speaks to the orders of errors to be returned. Of
course I'd like to say that the server should prioritize ERR_STALE
over ERR_OLD_STATEID (simply because it's a MUST in the spec and
ERR_OLD_STATEIDs are written as "rules").

>
> NeilBrown
>
>
> >
> > If we're going to change anything, I'd rather see us return -EACCES and
> > -ESTALE from the decode_access() and decode_getfattr() calls in
> > nfs4_xdr_dec_open() (and only those errors from those two calls!) so
> > that we can skip the unnecessary getattr call here.
> >
> > In fact, the only case that this extra getattr should be trying to
> > address is the one where the server returns NFS4ERR_DELAY to either the
> > decode_access() or the decode_getfattr() calls specifically, and where
> > we therefore don't want to replay the entire open call.
> >
> > >                 nfs4_sequence_free_slot(&o_res->seq_res);
> > > -               nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr,
> > > NULL);
> > > +               nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr,
> > > inode);
> > > +               iput(inode);
> > >         }
> > >         return 0;
> > >  }
> > > @@ -4335,6 +4341,7 @@ int nfs4_proc_getattr(struct nfs_server
> > > *server, struct nfs_fh *fhandle,
> > >  {
> > >         struct nfs4_exception exception = {
> > >                 .interruptible = true,
> > > +               .inode = inode,
> > >         };
> > >         int err;
> > >         do {
> >
> > --
> > Trond Myklebust
> > Linux NFS client maintainer, Hammerspace
> > trond.myklebust@xxxxxxxxxxxxxxx
> >
> >
> >



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux