From: "J. Bruce Fields" <bfields@redhat.com>
To: Chuck Lever <chuck.lever@oracle.com>
Cc: linux-nfs@vger.kernel.org, "J. Bruce Fields" <bfields@redhat.com>
Subject: [PATCH 3/5] nfsd: track filehandle aliasing in nfs4_files
Date: Fri, 16 Apr 2021 14:00:16 -0400 [thread overview]
Message-ID: <1618596018-9899-3-git-send-email-bfields@redhat.com> (raw)
In-Reply-To: <1618596018-9899-1-git-send-email-bfields@redhat.com>
From: "J. Bruce Fields" <bfields@redhat.com>
It's unusual but possible for multiple filehandles to point to the same
file. In that case, we may end up with multiple nfs4_files referencing
the same inode.
For delegation purposes it will turn out to be useful to flag those
cases.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
---
fs/nfsd/nfs4state.c | 37 ++++++++++++++++++++++++++++---------
fs/nfsd/state.h | 2 ++
2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index b0c74dbde07b..c1ba60db671a 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4075,6 +4075,8 @@ static void nfsd4_init_file(struct svc_fh *fh, unsigned int hashval,
fp->fi_share_deny = 0;
memset(fp->fi_fds, 0, sizeof(fp->fi_fds));
memset(fp->fi_access, 0, sizeof(fp->fi_access));
+ fp->fi_aliased = false;
+ fp->fi_inode = d_inode(fh->fh_dentry);
#ifdef CONFIG_NFSD_PNFS
INIT_LIST_HEAD(&fp->fi_lo_states);
atomic_set(&fp->fi_lo_recalls, 0);
@@ -4427,6 +4429,31 @@ find_file_locked(struct svc_fh *fh, unsigned int hashval)
return NULL;
}
+static struct nfs4_file *insert_file(struct nfs4_file *new, struct svc_fh *fh,
+ unsigned int hashval)
+{
+ struct nfs4_file *fp;
+ struct nfs4_file *ret = NULL;
+ bool alias_found = false;
+
+ spin_lock(&state_lock);
+ hlist_for_each_entry_rcu(fp, &file_hashtbl[hashval], fi_hash,
+ lockdep_is_held(&state_lock)) {
+ if (fh_match(&fp->fi_fhandle, &fh->fh_handle)) {
+ if (refcount_inc_not_zero(&fp->fi_ref))
+ ret = fp;
+ } else if (d_inode(fh->fh_dentry) == fp->fi_inode)
+ fp->fi_aliased = alias_found = true;
+ }
+ if (likely(ret == NULL)) {
+ nfsd4_init_file(fh, hashval, new);
+ new->fi_aliased = alias_found;
+ ret = new;
+ }
+ spin_unlock(&state_lock);
+ return ret;
+}
+
static struct nfs4_file * find_file(struct svc_fh *fh)
{
struct nfs4_file *fp;
@@ -4450,15 +4477,7 @@ find_or_add_file(struct nfs4_file *new, struct svc_fh *fh)
if (fp)
return fp;
- spin_lock(&state_lock);
- fp = find_file_locked(fh, hashval);
- if (likely(fp == NULL)) {
- nfsd4_init_file(fh, hashval, new);
- fp = new;
- }
- spin_unlock(&state_lock);
-
- return fp;
+ return insert_file(new, fh, hashval);
}
/*
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index af1d9f2e373e..7b10b3eaaa5c 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -512,6 +512,8 @@ struct nfs4_clnt_odstate {
*/
struct nfs4_file {
refcount_t fi_ref;
+ struct inode * fi_inode;
+ bool fi_aliased;
spinlock_t fi_lock;
struct hlist_node fi_hash; /* hash on fi_fhandle */
struct list_head fi_stateids;
--
2.30.2
next prev parent reply other threads:[~2021-04-16 18:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-16 18:00 [PATCH 1/5] nfsd: ensure new clients break delegations J. Bruce Fields
2021-04-16 18:00 ` [PATCH 2/5] nfsd: hash nfs4_files by inode number J. Bruce Fields
2021-04-16 19:21 ` Chuck Lever III
2021-04-19 19:53 ` J. Bruce Fields
2021-04-19 20:42 ` Chuck Lever III
2021-04-16 18:00 ` J. Bruce Fields [this message]
2021-04-16 18:00 ` [PATCH 4/5] nfsd: reshuffle some code J. Bruce Fields
2021-04-16 18:00 ` [PATCH 5/5] nfsd: grant read delegations to clients holding writes J. Bruce Fields
2021-04-16 19:11 ` [PATCH 1/5] nfsd: ensure new clients break delegations Chuck Lever III
2021-04-19 19: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=1618596018-9899-3-git-send-email-bfields@redhat.com \
--to=bfields@redhat.com \
--cc=chuck.lever@oracle.com \
--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