Re: [PATCH 1/1] NFSv4: make cache consistency bitmask dynamic

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

 



On Thu, Oct 1, 2020 at 1:14 PM Trond Myklebust <trondmy@xxxxxxxxxxxxxxx> wrote:
>
> Hi Olga,
>
> On Mon, 2020-09-14 at 17:05 -0400, Olga Kornievskaia wrote:
> > From: Olga Kornievskaia <kolga@xxxxxxxxxx>
> >
> > Client uses static bitmask for GETATTR on CLOSE/WRITE/DELEGRETURN
> > and ignores the fact that it might have some attributes marked
> > invalid in its cache. Compared to v3 where all attributes are
> > retrieved in postop attributes, v4's cache is frequently out of
> > sync and leads to standalone GETATTRs being sent to the server.
> >
> > Instead, in addition to the minimum cache consistency attributes
> > also check cache_validity and adjust the GETATTR request accordingly.
> >
> > Signed-off-by: Olga Kornievskaia <kolga@xxxxxxxxxx>
> > ---
> >  fs/nfs/nfs4proc.c       | 45 ++++++++++++++++++++++++++++++++++++++-
> > --
> >  include/linux/nfs_xdr.h |  6 +++---
> >  2 files changed, 45 insertions(+), 6 deletions(-)
> >
> > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> > index 6e95c85fe395..d7434a3697d9 100644
> > --- a/fs/nfs/nfs4proc.c
> > +++ b/fs/nfs/nfs4proc.c
> > @@ -107,6 +107,9 @@ static int nfs41_test_stateid(struct nfs_server
> > *, nfs4_stateid *,
> >  static int nfs41_free_stateid(struct nfs_server *, const
> > nfs4_stateid *,
> >               const struct cred *, bool);
> >  #endif
> > +static void nfs4_bitmask_adjust(__u32 *bitmask, struct inode *inode,
> > +             struct nfs_server *server,
> > +             struct nfs4_label *label);
> >
> >  #ifdef CONFIG_NFS_V4_SECURITY_LABEL
> >  static inline struct nfs4_label *
> > @@ -3632,9 +3635,10 @@ static void nfs4_close_prepare(struct rpc_task
> > *task, void *data)
> >
> >       if (calldata->arg.fmode == 0 || calldata->arg.fmode ==
> > FMODE_READ) {
> >               /* Close-to-open cache consistency revalidation */
> > -             if (!nfs4_have_delegation(inode, FMODE_READ))
> > +             if (!nfs4_have_delegation(inode, FMODE_READ)) {
> >                       calldata->arg.bitmask = NFS_SERVER(inode)-
> > >cache_consistency_bitmask;
> > -             else
> > +                     nfs4_bitmask_adjust(calldata->arg.bitmask,
> > inode, NFS_SERVER(inode), NULL);
> > +             } else
> >                       calldata->arg.bitmask = NULL;
> >       }
> >
> > @@ -5360,6 +5364,38 @@ bool
> > nfs4_write_need_cache_consistency_data(struct nfs_pgio_header *hdr)
> >       return nfs4_have_delegation(hdr->inode, FMODE_READ) == 0;
> >  }
> >
> > +static void nfs4_bitmask_adjust(__u32 *bitmask, struct inode *inode,
> > +                             struct nfs_server *server,
> > +                             struct nfs4_label *label)
> > +{
> > +
> > +     unsigned long cache_validity = READ_ONCE(NFS_I(inode)-
> > >cache_validity);
> > +
> > +     if ((cache_validity & NFS_INO_INVALID_DATA) ||
> > +             (cache_validity & NFS_INO_REVAL_PAGECACHE) ||
> > +             (cache_validity & NFS_INO_REVAL_FORCED) ||
> > +             (cache_validity & NFS_INO_INVALID_OTHER))
> > +             nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server,
> > label), inode);
> > +
> > +     if (cache_validity & NFS_INO_INVALID_ATIME)
> > +             bitmask[1] |= FATTR4_WORD1_TIME_ACCESS;
> > +     if (cache_validity & NFS_INO_INVALID_ACCESS)
> > +             bitmask[0] |= FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER |
> > +                             FATTR4_WORD1_OWNER_GROUP;
> > +     if (cache_validity & NFS_INO_INVALID_ACL)
> > +             bitmask[0] |= FATTR4_WORD0_ACL;
> > +     if (cache_validity & NFS_INO_INVALID_LABEL)
> > +             bitmask[2] |= FATTR4_WORD2_SECURITY_LABEL;
> > +     if (cache_validity & NFS_INO_INVALID_CTIME)
> > +             bitmask[0] |= FATTR4_WORD0_CHANGE;
> > +     if (cache_validity & NFS_INO_INVALID_MTIME)
> > +             bitmask[1] |= FATTR4_WORD1_TIME_MODIFY;
> > +     if (cache_validity & NFS_INO_INVALID_SIZE)
> > +             bitmask[0] |= FATTR4_WORD0_SIZE;
> > +     if (cache_validity & NFS_INO_INVALID_BLOCKS)
> > +             bitmask[1] |= FATTR4_WORD1_SPACE_USED;
>
> If we hold a delegation (which we could do when called
> from nfs4_proc_write_setup()) then we only want to get extra attributes
> if the NFS_INO_REVAL_FORCED flag is also set.

If we hold a delegation then nfs4_write_need_cache_consistency_data()
would be true and no getattr would be added (or need to be adjusted).
Am I mis-reading your comment?

> > +}
> > +
> >  static void nfs4_proc_write_setup(struct nfs_pgio_header *hdr,
> >                                 struct rpc_message *msg,
> >                                 struct rpc_clnt **clnt)
> > @@ -5369,8 +5405,10 @@ static void nfs4_proc_write_setup(struct
> > nfs_pgio_header *hdr,
> >       if (!nfs4_write_need_cache_consistency_data(hdr)) {
> >               hdr->args.bitmask = NULL;
> >               hdr->res.fattr = NULL;
> > -     } else
> > +     } else {
> >               hdr->args.bitmask = server->cache_consistency_bitmask;
> > +             nfs4_bitmask_adjust(hdr->args.bitmask, hdr->inode,
> > server, NULL);
> > +     }
> >
> >       if (!hdr->pgio_done_cb)
> >               hdr->pgio_done_cb = nfs4_write_done_cb;
> > @@ -6406,6 +6444,7 @@ static int _nfs4_proc_delegreturn(struct inode
> > *inode, const struct cred *cred,
> >       data->args.fhandle = &data->fh;
> >       data->args.stateid = &data->stateid;
> >       data->args.bitmask = server->cache_consistency_bitmask;
> > +     nfs4_bitmask_adjust(data->args.bitmask, inode, server, NULL);
> >       nfs_copy_fh(&data->fh, NFS_FH(inode));
> >       nfs4_stateid_copy(&data->stateid, stateid);
> >       data->res.fattr = &data->fattr;
> > diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
> > index 9408f3252c8e..bafbf6695796 100644
> > --- a/include/linux/nfs_xdr.h
> > +++ b/include/linux/nfs_xdr.h
> > @@ -525,7 +525,7 @@ struct nfs_closeargs {
> >       struct nfs_seqid *      seqid;
> >       fmode_t                 fmode;
> >       u32                     share_access;
> > -     const u32 *             bitmask;
> > +     u32 *                   bitmask;
> >       struct nfs4_layoutreturn_args *lr_args;
> >  };
> >
> > @@ -608,7 +608,7 @@ struct nfs4_delegreturnargs {
> >       struct nfs4_sequence_args       seq_args;
> >       const struct nfs_fh *fhandle;
> >       const nfs4_stateid *stateid;
> > -     const u32 * bitmask;
> > +     u32 * bitmask;
> >       struct nfs4_layoutreturn_args *lr_args;
> >  };
> >
> > @@ -648,7 +648,7 @@ struct nfs_pgio_args {
> >       union {
> >               unsigned int            replen;                 /*
> > used by read */
> >               struct {
> > -                     const u32 *             bitmask;        /*
> > used by write */
> > +                     u32 *                   bitmask;        /*
> > used by write */
> >                       enum nfs3_stable_how    stable;         /*
> > used by write */
> >               };
> >       };
>
> Otherwise this looks good. Thanks!
>
> --
> 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