summaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2018-12-03 11:30:30 +1100
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2018-12-19 13:52:44 -0500
commit97f68c6b02e0225b38d327103c59cfe2ab5ecda7 (patch)
tree87d434407fef925b2d3fefad5dd759d33b9eb31a /fs/nfs
parentf06bc03339ad4c1baa964a5f0606247ac1c3c50b (diff)
downloadlinux-97f68c6b02e0225b38d327103c59cfe2ab5ecda7.tar.gz
linux-97f68c6b02e0225b38d327103c59cfe2ab5ecda7.tar.bz2
linux-97f68c6b02e0225b38d327103c59cfe2ab5ecda7.zip
SUNRPC: add 'struct cred *' to auth_cred and rpc_cred
The SUNRPC credential framework was put together before Linux has 'struct cred'. Now that we have it, it makes sense to use it. This first step just includes a suitable 'struct cred *' pointer in every 'struct auth_cred' and almost every 'struct rpc_cred'. The rpc_cred used for auth_null has a NULL 'struct cred *' as nothing else really makes sense. For rpc_cred, the pointer is reference counted. For auth_cred it isn't. struct auth_cred are either allocated on the stack, in which case the thread owns a reference to the auth, or are part of 'struct generic_cred' in which case gc_base owns the reference, and "acred" shares it. Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 310d7500f665..22e164106333 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -9,6 +9,7 @@
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
#include <linux/module.h>
+#include <linux/sched/mm.h>
#include <linux/sunrpc/metrics.h>
@@ -415,6 +416,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
struct nfs4_ff_layout_mirror *mirror;
struct auth_cred acred = { .group_info = ff_zero_group };
struct rpc_cred __rcu *cred;
+ struct cred *kcred;
u32 ds_count, fh_count, id;
int j;
@@ -491,8 +493,23 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
acred.gid = make_kgid(&init_user_ns, id);
+ if (gfp_flags & __GFP_FS)
+ kcred = prepare_kernel_cred(NULL);
+ else {
+ unsigned int nofs_flags = memalloc_nofs_save();
+ kcred = prepare_kernel_cred(NULL);
+ memalloc_nofs_restore(nofs_flags);
+ }
+ rc = -ENOMEM;
+ if (!kcred)
+ goto out_err_free;
+ kcred->fsuid = acred.uid;
+ kcred->fsgid = acred.gid;
+ acred.cred = kcred;
+
/* find the cred for it */
rcu_assign_pointer(cred, rpc_lookup_generic_cred(&acred, 0, gfp_flags));
+ put_cred(kcred);
if (IS_ERR(cred)) {
rc = PTR_ERR(cred);
goto out_err_free;