All of lore.kernel.org
 help / color / mirror / Atom feed
From: Olga Kornievskaia <aglo@umich.edu>
To: Jeff Layton <jlayton@kernel.org>
Cc: chuck.lever@oracle.com, linux-nfs@vger.kernel.org
Subject: Re: [PATCH 1/6] nfsd: don't take nfsd4_copy ref for OP_OFFLOAD_STATUS
Date: Wed, 18 Jan 2023 13:08:54 -0500	[thread overview]
Message-ID: <CAN-5tyHnhk9sV-jfnDvQ66brYtqY7NPvsq3D1-hWe7vYUxjgUQ@mail.gmail.com> (raw)
In-Reply-To: <944bf7f3e6956989933d07aabd4a632de2ec4667.camel@kernel.org>

On Wed, Jan 18, 2023 at 12:49 PM Jeff Layton <jlayton@kernel.org> wrote:
>
> On Wed, 2023-01-18 at 12:43 -0500, Olga Kornievskaia wrote:
> > On Wed, Jan 18, 2023 at 12:35 PM Jeff Layton <jlayton@kernel.org> wrote:
> > >
> > > We're not doing any blocking operations for OP_OFFLOAD_STATUS, so taking
> > > and putting a reference is a waste of effort. Take the client lock,
> > > search for the copy and fetch the wr_bytes_written field and return.
> > >
> > > Also, make find_async_copy a static function.
> > >
> > > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > > ---
> > >  fs/nfsd/nfs4proc.c | 35 ++++++++++++++++++++++++-----------
> > >  fs/nfsd/state.h    |  2 --
> > >  2 files changed, 24 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
> > > index 62b9d6c1b18b..731c2b22f163 100644
> > > --- a/fs/nfsd/nfs4proc.c
> > > +++ b/fs/nfsd/nfs4proc.c
> > > @@ -1823,23 +1823,34 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
> > >         goto out;
> > >  }
> > >
> > > -struct nfsd4_copy *
> > > -find_async_copy(struct nfs4_client *clp, stateid_t *stateid)
> > > +static struct nfsd4_copy *
> > > +find_async_copy_locked(struct nfs4_client *clp, stateid_t *stateid)
> > >  {
> > >         struct nfsd4_copy *copy;
> > >
> > > -       spin_lock(&clp->async_lock);
> > > +       lockdep_assert_held(&clp->async_lock);
> > > +
> > >         list_for_each_entry(copy, &clp->async_copies, copies) {
> > >                 if (memcmp(&copy->cp_stateid.cs_stid, stateid, NFS4_STATEID_SIZE))
> > >                         continue;
> > > -               refcount_inc(&copy->refcount);
> >
> > If we don't take a refcount on the copy, this copy could be removed
> > between the time we found it in the list of copies and when we then
> > look inside to check the amount written so far. This would lead to a
> > null (or bad) pointer dereference?
> >
>
> No. The existing code finds this object, takes a reference to it,
> fetches a single integer out of it and then puts the reference. This
> patch just has it avoid the reference altogether and fetch the value
> while we still hold the spinlock. This should be completely safe
> (assuming the locking around the existing list handling is correct,
> which it does seem to be).

Thank you for the explanation. I see it now.

>
>
> > > -               spin_unlock(&clp->async_lock);
> > >                 return copy;
> > >         }
> > > -       spin_unlock(&clp->async_lock);
> > >         return NULL;
> > >  }
> > >
> > > +static struct nfsd4_copy *
> > > +find_async_copy(struct nfs4_client *clp, stateid_t *stateid)
> > > +{
> > > +       struct nfsd4_copy *copy;
> > > +
> > > +       spin_lock(&clp->async_lock);
> > > +       copy = find_async_copy_locked(clp, stateid);
> > > +       if (copy)
> > > +               refcount_inc(&copy->refcount);
> > > +       spin_unlock(&clp->async_lock);
> > > +       return copy;
> > > +}
> > > +
> > >  static __be32
> > >  nfsd4_offload_cancel(struct svc_rqst *rqstp,
> > >                      struct nfsd4_compound_state *cstate,
> > > @@ -1924,22 +1935,24 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
> > >         nfsd_file_put(nf);
> > >         return status;
> > >  }
> > > +
> > >  static __be32
> > >  nfsd4_offload_status(struct svc_rqst *rqstp,
> > >                      struct nfsd4_compound_state *cstate,
> > >                      union nfsd4_op_u *u)
> > >  {
> > >         struct nfsd4_offload_status *os = &u->offload_status;
> > > -       __be32 status = 0;
> > > +       __be32 status = nfs_ok;
> > >         struct nfsd4_copy *copy;
> > >         struct nfs4_client *clp = cstate->clp;
> > >
> > > -       copy = find_async_copy(clp, &os->stateid);
> > > -       if (copy) {
> > > +       spin_lock(&clp->async_lock);
> > > +       copy = find_async_copy_locked(clp, &os->stateid);
> > > +       if (copy)
> > >                 os->count = copy->cp_res.wr_bytes_written;
> > > -               nfs4_put_copy(copy);
> > > -       } else
> > > +       else
> > >                 status = nfserr_bad_stateid;
> > > +       spin_unlock(&clp->async_lock);
> > >
> > >         return status;
> > >  }
> > > diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
> > > index e94634d30591..d49d3060ed4f 100644
> > > --- a/fs/nfsd/state.h
> > > +++ b/fs/nfsd/state.h
> > > @@ -705,8 +705,6 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(struct xdr_netobj name
> > >  extern bool nfs4_has_reclaimed_state(struct xdr_netobj name, struct nfsd_net *nn);
> > >
> > >  void put_nfs4_file(struct nfs4_file *fi);
> > > -extern struct nfsd4_copy *
> > > -find_async_copy(struct nfs4_client *clp, stateid_t *staetid);
> > >  extern void nfs4_put_cpntf_state(struct nfsd_net *nn,
> > >                                  struct nfs4_cpntf_state *cps);
> > >  extern __be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st,
> > > --
> > > 2.39.0
> > >
>
> --
> Jeff Layton <jlayton@kernel.org>

  reply	other threads:[~2023-01-18 18:10 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-18 17:31 [PATCH 0/6] nfsd: random cleanup and doc work Jeff Layton
2023-01-18 17:31 ` [PATCH 1/6] nfsd: don't take nfsd4_copy ref for OP_OFFLOAD_STATUS Jeff Layton
2023-01-18 17:43   ` Olga Kornievskaia
2023-01-18 17:49     ` Jeff Layton
2023-01-18 18:08       ` Olga Kornievskaia [this message]
2023-01-18 18:53         ` Chuck Lever III
2023-01-19  1:46           ` Olga Kornievskaia
2023-01-18 17:31 ` [PATCH 2/6] nfsd: eliminate find_deleg_file_locked Jeff Layton
2023-01-18 17:31 ` [PATCH 3/6] nfsd: simplify the delayed disposal list code Jeff Layton
2023-01-18 19:08   ` Chuck Lever III
2023-01-18 19:42     ` Jeff Layton
2023-01-18 20:44       ` Chuck Lever III
2023-04-14 18:20   ` Chuck Lever III
2023-04-14 19:01     ` Jeff Layton
2023-04-14 19:17     ` Jeff Layton
2023-04-14 20:56       ` Chuck Lever III
2023-01-18 17:31 ` [PATCH 4/6] nfsd: don't take/put an extra reference when putting a file Jeff Layton
2023-01-18 17:31 ` [PATCH 5/6] nfsd: add some kerneldoc comments for stateid preprocessing functions Jeff Layton
2023-01-18 17:31 ` [PATCH 6/6] nfsd: eliminate __nfs4_get_fd Jeff Layton

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=CAN-5tyHnhk9sV-jfnDvQ66brYtqY7NPvsq3D1-hWe7vYUxjgUQ@mail.gmail.com \
    --to=aglo@umich.edu \
    --cc=chuck.lever@oracle.com \
    --cc=jlayton@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.