From: Trond Myklebust <trond.myklebust@primarydata.com>
To: bfields@fieldses.org
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH v2 4/7] nfsd: Ensure we don't recognise lock stateids after freeing them
Date: Fri, 3 Nov 2017 08:00:13 -0400 [thread overview]
Message-ID: <20171103120016.6200-5-trond.myklebust@primarydata.com> (raw)
In-Reply-To: <20171103120016.6200-4-trond.myklebust@primarydata.com>
In order to deal with lookup races, nfsd4_free_lock_stateid() needs
to be able to signal to other stateful functions that the lock stateid
is no longer valid. Right now, nfsd_lock() will check whether or not an
existing stateid is still hashed, but only in the "new lock" path.
To ensure the stateid invalidation is also recognised by the "existing lock"
path, and also by a second call to nfsd4_free_lock_stateid() itself, we can
change the type to NFS4_CLOSED_STID under the stp->st_mutex.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
---
fs/nfsd/nfs4state.c | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 5ae6baff09e0..f93ca0682aaa 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -5076,7 +5076,9 @@ nfsd4_free_lock_stateid(stateid_t *stateid, struct nfs4_stid *s)
struct nfs4_ol_stateid *stp = openlockstateid(s);
__be32 ret;
- mutex_lock(&stp->st_mutex);
+ ret = nfsd4_lock_ol_stateid(stp);
+ if (ret)
+ goto out_put_stid;
ret = check_stateid_generation(stateid, &s->sc_stateid, 1);
if (ret)
@@ -5087,11 +5089,13 @@ nfsd4_free_lock_stateid(stateid_t *stateid, struct nfs4_stid *s)
lockowner(stp->st_stateowner)))
goto out;
+ stp->st_stid.sc_type = NFS4_CLOSED_STID;
release_lock_stateid(stp);
ret = nfs_ok;
out:
mutex_unlock(&stp->st_mutex);
+out_put_stid:
nfs4_put_stid(s);
return ret;
}
@@ -5660,6 +5664,8 @@ find_lock_stateid(struct nfs4_lockowner *lo, struct nfs4_file *fp)
lockdep_assert_held(&clp->cl_lock);
list_for_each_entry(lst, &lo->lo_owner.so_stateids, st_perstateowner) {
+ if (lst->st_stid.sc_type != NFS4_LOCK_STID)
+ continue;
if (lst->st_stid.sc_file == fp) {
atomic_inc(&lst->st_stid.sc_count);
return lst;
@@ -5734,7 +5740,6 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,
struct nfs4_lockowner *lo;
struct nfs4_ol_stateid *lst;
unsigned int strhashval;
- bool hashed;
lo = find_lockowner_str(cl, &lock->lk_new_owner);
if (!lo) {
@@ -5757,15 +5762,7 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,
goto out;
}
- mutex_lock(&lst->st_mutex);
-
- /* See if it's still hashed to avoid race with FREE_STATEID */
- spin_lock(&cl->cl_lock);
- hashed = !list_empty(&lst->st_perfile);
- spin_unlock(&cl->cl_lock);
-
- if (!hashed) {
- mutex_unlock(&lst->st_mutex);
+ if (nfsd4_lock_ol_stateid(lst) != nfs_ok) {
nfs4_put_stid(&lst->st_stid);
goto retry;
}
--
2.13.6
next prev parent reply other threads:[~2017-11-03 12:00 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-03 12:00 [PATCH v2 0/7] Tighten up locking around stateids in knfsd Trond Myklebust
2017-11-03 12:00 ` [PATCH v2 1/7] nfsd: Fix stateid races between OPEN and CLOSE Trond Myklebust
2017-11-03 12:00 ` [PATCH v2 2/7] nfsd: Fix another OPEN stateid race Trond Myklebust
2017-11-03 12:00 ` [PATCH v2 3/7] nfsd: CLOSE SHOULD return the invalid special stateid for NFSv4.x (x>0) Trond Myklebust
2017-11-03 12:00 ` Trond Myklebust [this message]
2017-11-03 12:00 ` [PATCH v2 5/7] nfsd: Fix race in lock stateid creation Trond Myklebust
2017-11-03 12:00 ` [PATCH v2 6/7] nfsd: Ensure we check stateid validity in the seqid operation checks Trond Myklebust
2017-11-03 12:00 ` [PATCH v2 7/7] nfsd: Fix races with check_stateid_generation() Trond Myklebust
2017-11-07 21:37 ` [PATCH v2 5/7] nfsd: Fix race in lock stateid creation J. Bruce Fields
2017-11-07 20:06 ` [PATCH v2 0/7] Tighten up locking around stateids in knfsd J. Bruce Fields
2017-11-07 20:47 ` J. Bruce Fields
2017-11-07 21:55 ` J. Bruce Fields
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=20171103120016.6200-5-trond.myklebust@primarydata.com \
--to=trond.myklebust@primarydata.com \
--cc=bfields@fieldses.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox