Re: [RFC PATCH] nfs: don't skip CTO on v2/3 mounts, regardless of order of reference puts

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

 



On Thu, 2022-07-28 at 10:24 -0400, Jeff Layton wrote:
> Olga reported a case of data corruption in a situation where two
> clients
> (v3 and v4) were alternately doing open/write/close the same file.
> 
> Looking at captures, the v3 client failed to perform any of the
> GETATTR
> calls for CTO during one of the events, leading it to overwrite some
> data that had been written by the v4 client.
> 
> We have two calls that work similarly: put_nfs_open_context and
> put_nfs_open_context_sync. The only difference is the is_sync
> parameter
> that gets passed to close_context. The only caller of the _sync
> variant
> is in the close codepath.
> 
> On a v2/3 mount, if the last reference is not put by
> put_nfs_open_context_sync, then CTO revalidation never happens. Fix
> this
> by adding a new flag to nfs_open_context and set that in
> put_nfs_open_context_sync. In nfs_close_context, check for that flag
> when we're checking is_sync and treat them as equivalent.
> 
> Cc: Scott Mayhew <smayhew@xxxxxxxxxx>
> Cc: Ben Coddington <bcodding@xxxxxxxxxx>
> Reported-by: Olga Kornieskaia <kolga@xxxxxxxxxx>
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
>  fs/nfs/inode.c         | 3 ++-
>  include/linux/nfs_fs.h | 3 ++-
>  2 files changed, 4 insertions(+), 2 deletions(-)
> 
> I'm not sure this is the right fix. Maybe we'd be better off just
> ignoring the is_sync parameter in nfs_close_context? It's probably
> functionally equivalent anyway.
> 
> Thoughts?
> 
> diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
> index b4e46b0ffa2d..58b506a0a2f2 100644
> --- a/fs/nfs/inode.c
> +++ b/fs/nfs/inode.c
> @@ -1005,7 +1005,7 @@ void nfs_close_context(struct nfs_open_context
> *ctx, int is_sync)
>  
>         if (!(ctx->mode & FMODE_WRITE))
>                 return;
> -       if (!is_sync)
> +       if (!is_sync && !test_bit(NFS_CONTEXT_DO_CLOSE, &ctx->flags))
>                 return;
>         inode = d_inode(ctx->dentry);
>         if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))

NACK. If the 'is_sync' flag is not set, then it is because the function
is being called from a context where it is not safe to do a synchronous
RPC call.


-- 
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