From: Jeff Layton <jlayton@poochiereds.net>
To: trond.myklebust@primarydata.com
Cc: Anna Schumaker <Anna.Schumaker@netapp.com>, linux-nfs@vger.kernel.org
Subject: [PATCH v2 7/7] nfs: have flexfiles mirror keep creds for both ro and rw layouts
Date: Thu, 21 Apr 2016 20:52:00 -0400 [thread overview]
Message-ID: <1461286320-24601-8-git-send-email-jeff.layton@primarydata.com> (raw)
In-Reply-To: <1461286320-24601-1-git-send-email-jeff.layton@primarydata.com>
A mirror can be shared between multiple layouts, even with different
iomodes. That makes stats gathering simpler, but it causes a problem
when we get different creds in READ vs. RW layouts.
The current code drops the newer credentials onto the floor when this
occurs. That's problematic when you fetch a READ layout first, and then
a RW. If the READ layout doesn't have the correct creds to do a write,
then writes will fail.
We could just overwrite the READ credentials with the RW ones, but that
would break the ability for the server to fence the layout for reads if
things go awry. We need to be able to revert to the earlier READ creds
if the RW layout is returned afterward.
The simplest fix is to just keep two sets of creds per mirror. One for
READ layouts and one for RW, and then use the appropriate set depending
on the iomode of the layout segment.
Also fix up some RCU nits that sparse found.
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
---
fs/nfs/flexfilelayout/flexfilelayout.c | 30 +++++++++++++++++++++++-------
fs/nfs/flexfilelayout/flexfilelayout.h | 3 ++-
fs/nfs/flexfilelayout/flexfilelayoutdev.c | 7 +++++--
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 19806caa8ff2..61b27d99df18 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -213,10 +213,16 @@ static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(gfp_t gfp_flags)
static void ff_layout_free_mirror(struct nfs4_ff_layout_mirror *mirror)
{
+ struct rpc_cred *cred;
+
ff_layout_remove_mirror(mirror);
kfree(mirror->fh_versions);
- if (mirror->cred)
- put_rpccred(mirror->cred);
+ cred = rcu_access_pointer(mirror->ro_cred);
+ if (cred)
+ put_rpccred(cred);
+ cred = rcu_access_pointer(mirror->rw_cred);
+ if (cred)
+ put_rpccred(cred);
nfs4_ff_layout_put_deviceid(mirror->mirror_ds);
kfree(mirror);
}
@@ -410,7 +416,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
struct nfs4_deviceid devid;
struct nfs4_deviceid_node *idnode;
struct auth_cred acred = { .group_info = ff_zero_group };
- struct rpc_cred *cred;
+ struct rpc_cred __rcu *cred;
u32 ds_count, fh_count, id;
int j;
@@ -501,23 +507,33 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
acred.gid = make_kgid(&init_user_ns, id);
/* find the cred for it */
- cred = rpc_lookup_generic_cred(&acred, 0, gfp_flags);
+ rcu_assign_pointer(cred, rpc_lookup_generic_cred(&acred, 0, gfp_flags));
if (IS_ERR(cred)) {
rc = PTR_ERR(cred);
goto out_err_free;
}
- rcu_assign_pointer(fls->mirror_array[i]->cred, cred);
+ if (lgr->range.iomode == IOMODE_READ)
+ rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred);
+ else
+ rcu_assign_pointer(fls->mirror_array[i]->rw_cred, cred);
mirror = ff_layout_add_mirror(lh, fls->mirror_array[i]);
if (mirror != fls->mirror_array[i]) {
/* swap cred ptrs so free_mirror will clean up old */
- fls->mirror_array[i]->cred = xchg(&mirror->cred, cred);
+ if (lgr->range.iomode == IOMODE_READ) {
+ cred = xchg(&mirror->ro_cred, cred);
+ rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred);
+ } else {
+ cred = xchg(&mirror->rw_cred, cred);
+ rcu_assign_pointer(fls->mirror_array[i]->rw_cred, cred);
+ }
ff_layout_free_mirror(fls->mirror_array[i]);
fls->mirror_array[i] = mirror;
}
- dprintk("%s: uid %u gid %u\n", __func__,
+ dprintk("%s: iomode %s uid %u gid %u\n", __func__,
+ lgr->range.iomode == IOMODE_READ ? "READ" : "RW",
from_kuid(&init_user_ns, acred.uid),
from_kgid(&init_user_ns, acred.gid));
}
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h
index c29fc853ce74..1318c77aeb35 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.h
+++ b/fs/nfs/flexfilelayout/flexfilelayout.h
@@ -76,7 +76,8 @@ struct nfs4_ff_layout_mirror {
u32 fh_versions_cnt;
struct nfs_fh *fh_versions;
nfs4_stateid stateid;
- struct rpc_cred *cred;
+ struct rpc_cred __rcu *ro_cred;
+ struct rpc_cred __rcu *rw_cred;
atomic_t ref;
spinlock_t lock;
struct nfs4_ff_layoutstat read_stat;
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index 6ddd8a5c5ae0..56296f3df19c 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -305,9 +305,12 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
static struct rpc_cred *
ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode)
{
- struct rpc_cred *cred, **pcred;
+ struct rpc_cred *cred, __rcu **pcred;
- pcred = &mirror->cred;
+ if (iomode == IOMODE_READ)
+ pcred = &mirror->ro_cred;
+ else
+ pcred = &mirror->rw_cred;
rcu_read_lock();
do {
--
2.5.5
prev parent reply other threads:[~2016-04-22 0:52 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-22 0:51 [PATCH v2 0/7] nfs/sunrpc: fix flexfiles credential handling Jeff Layton
2016-04-22 0:51 ` [PATCH v2 1/7] sunrpc: plumb gfp_t parm into crcreate operation Jeff Layton
2016-04-27 18:00 ` Anna Schumaker
2016-04-27 18:36 ` Jeff Layton
2016-04-22 0:51 ` [PATCH v2 2/7] sunrpc: add rpc_lookup_generic_cred Jeff Layton
2016-04-22 0:51 ` [PATCH v2 3/7] sunrpc: add a get_rpccred_rcu inline Jeff Layton
2016-04-22 0:51 ` [PATCH v2 4/7] nfs: don't call nfs4_ff_layout_prepare_ds from ff_layout_get_ds_cred Jeff Layton
2016-04-22 0:51 ` [PATCH v2 5/7] nfs: have ff_layout_get_ds_cred take a reference to the cred Jeff Layton
2016-04-22 0:51 ` [PATCH v2 6/7] nfs: get a reference to the credential in ff_layout_alloc_lseg Jeff Layton
2016-04-28 20:37 ` Anna Schumaker
2016-04-29 10:49 ` Jeff Layton
2016-04-29 12:58 ` Anna Schumaker
2016-04-22 0:52 ` Jeff Layton [this message]
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=1461286320-24601-8-git-send-email-jeff.layton@primarydata.com \
--to=jlayton@poochiereds.net \
--cc=Anna.Schumaker@netapp.com \
--cc=linux-nfs@vger.kernel.org \
--cc=trond.myklebust@primarydata.com \
/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;
as well as URLs for NNTP newsgroup(s).