diff mbox

[19/23] NFS/NFSD/SUNRPC: replace generic creds with 'struct cred'.

Message ID 151901654943.17421.16135174786512989263.stgit@noble (mailing list archive)
State New, archived
Headers show

Commit Message

NeilBrown Feb. 19, 2018, 5:02 a.m. UTC
SUNRPC has two sorts of credentials, both of which appear as
"struct rpc_cred".
There are "generic credentials" which are supplied by clients
such as NFS and passed in 'struct rpc_message' to indicate
which user should be used to authorize the request, and there
are low-level credentials such as AUTH_NULL, AUTH_UNIX, AUTH_GSS
which describe the credential to be sent over the wires.

This patch replaces all the generic credentials by 'struct cred'
pointers - the credential structure used throughout Linux.

For machine credentials, there is a special 'struct cred *' pointer
which is statically allocated and recognized where needed as
having a special meaning.  A look-up of a low-level cred will
map this to a machine credential.

Signed-off-by: NeilBrown <neilb@suse.com>

CHANGES: protect some put_cred() call if cred could be NULL.
---
 fs/lockd/clntproc.c                       |    6 +
 fs/nfs/blocklayout/blocklayout.c          |    2 
 fs/nfs/delegation.c                       |   26 ++---
 fs/nfs/delegation.h                       |   10 +-
 fs/nfs/flexfilelayout/flexfilelayout.c    |   31 ++---
 fs/nfs/flexfilelayout/flexfilelayout.h    |    8 +
 fs/nfs/flexfilelayout/flexfilelayoutdev.c |   16 +--
 fs/nfs/inode.c                            |   10 +-
 fs/nfs/internal.h                         |    8 +
 fs/nfs/nfs3proc.c                         |   18 ---
 fs/nfs/nfs4_fs.h                          |   56 +++++-----
 fs/nfs/nfs4client.c                       |    4 -
 fs/nfs/nfs4proc.c                         |  166 +++++++++++++----------------
 fs/nfs/nfs4renewd.c                       |    4 -
 fs/nfs/nfs4session.c                      |    4 -
 fs/nfs/nfs4state.c                        |   90 ++++++++--------
 fs/nfs/pagelist.c                         |    2 
 fs/nfs/pnfs.c                             |   10 +-
 fs/nfs/pnfs.h                             |   10 +-
 fs/nfs/pnfs_dev.c                         |    4 -
 fs/nfs/pnfs_nfs.c                         |    2 
 fs/nfs/proc.c                             |    9 --
 fs/nfs/unlink.c                           |   15 +--
 fs/nfs/write.c                            |    2 
 fs/nfsd/nfs4callback.c                    |   16 +--
 fs/nfsd/state.h                           |    2 
 include/linux/nfs_fs.h                    |    6 +
 include/linux/nfs_xdr.h                   |   14 +-
 include/linux/sunrpc/auth.h               |   20 ---
 include/linux/sunrpc/sched.h              |    2 
 net/sunrpc/auth.c                         |   14 ++
 net/sunrpc/clnt.c                         |    4 -
 net/sunrpc/sched.c                        |    2 
 33 files changed, 262 insertions(+), 331 deletions(-)



--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

kernel test robot Feb. 19, 2018, 2:58 p.m. UTC | #1
Hi NeilBrown,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on nfs/linux-next]
[also build test WARNING on v4.16-rc2 next-20180219]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/NeilBrown/Remove-generic-rpc-credentials-and-associated-changed-V3/20180219-190836
base:   git://git.linux-nfs.org/projects/trondmy/linux-nfs.git linux-next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> fs/nfs/flexfilelayout/flexfilelayout.c:517:40: sparse: incorrect type in initializer (different address spaces) @@ expected struct cred const @@ got cred const @@
   fs/nfs/flexfilelayout/flexfilelayout.c:517:40: expected struct cred const
   fs/nfs/flexfilelayout/flexfilelayout.c:517:40: got struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred
>> fs/nfs/flexfilelayout/flexfilelayout.c:517:38: sparse: incorrect type in assignment (different address spaces) @@ expected struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred @@ got struct cred conststruct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred @@
   fs/nfs/flexfilelayout/flexfilelayout.c:517:38: expected struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred
   fs/nfs/flexfilelayout/flexfilelayout.c:517:38: got struct cred const __ret
   fs/nfs/flexfilelayout/flexfilelayout.c:520:40: sparse: incorrect type in initializer (different address spaces) @@ expected struct cred const @@ got cred const @@
   fs/nfs/flexfilelayout/flexfilelayout.c:520:40: expected struct cred const
   fs/nfs/flexfilelayout/flexfilelayout.c:520:40: got struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred
   fs/nfs/flexfilelayout/flexfilelayout.c:520:38: sparse: incorrect type in assignment (different address spaces) @@ expected struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred @@ got struct cred conststruct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred @@
   fs/nfs/flexfilelayout/flexfilelayout.c:520:38: expected struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred
   fs/nfs/flexfilelayout/flexfilelayout.c:520:38: got struct cred const __ret

vim +517 fs/nfs/flexfilelayout/flexfilelayout.c

d67ae825 Tom Haynes      2014-12-11  360  
d67ae825 Tom Haynes      2014-12-11  361  static struct pnfs_layout_segment *
d67ae825 Tom Haynes      2014-12-11  362  ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
d67ae825 Tom Haynes      2014-12-11  363  		     struct nfs4_layoutget_res *lgr,
d67ae825 Tom Haynes      2014-12-11  364  		     gfp_t gfp_flags)
d67ae825 Tom Haynes      2014-12-11  365  {
d67ae825 Tom Haynes      2014-12-11  366  	struct pnfs_layout_segment *ret;
d67ae825 Tom Haynes      2014-12-11  367  	struct nfs4_ff_layout_segment *fls = NULL;
d67ae825 Tom Haynes      2014-12-11  368  	struct xdr_stream stream;
d67ae825 Tom Haynes      2014-12-11  369  	struct xdr_buf buf;
d67ae825 Tom Haynes      2014-12-11  370  	struct page *scratch;
d67ae825 Tom Haynes      2014-12-11  371  	u64 stripe_unit;
d67ae825 Tom Haynes      2014-12-11  372  	u32 mirror_array_cnt;
d67ae825 Tom Haynes      2014-12-11  373  	__be32 *p;
d67ae825 Tom Haynes      2014-12-11  374  	int i, rc;
d67ae825 Tom Haynes      2014-12-11  375  
d67ae825 Tom Haynes      2014-12-11  376  	dprintk("--> %s\n", __func__);
d67ae825 Tom Haynes      2014-12-11  377  	scratch = alloc_page(gfp_flags);
d67ae825 Tom Haynes      2014-12-11  378  	if (!scratch)
d67ae825 Tom Haynes      2014-12-11  379  		return ERR_PTR(-ENOMEM);
d67ae825 Tom Haynes      2014-12-11  380  
d67ae825 Tom Haynes      2014-12-11  381  	xdr_init_decode_pages(&stream, &buf, lgr->layoutp->pages,
d67ae825 Tom Haynes      2014-12-11  382  			      lgr->layoutp->len);
d67ae825 Tom Haynes      2014-12-11  383  	xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
d67ae825 Tom Haynes      2014-12-11  384  
d67ae825 Tom Haynes      2014-12-11  385  	/* stripe unit and mirror_array_cnt */
d67ae825 Tom Haynes      2014-12-11  386  	rc = -EIO;
d67ae825 Tom Haynes      2014-12-11  387  	p = xdr_inline_decode(&stream, 8 + 4);
d67ae825 Tom Haynes      2014-12-11  388  	if (!p)
d67ae825 Tom Haynes      2014-12-11  389  		goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  390  
d67ae825 Tom Haynes      2014-12-11  391  	p = xdr_decode_hyper(p, &stripe_unit);
d67ae825 Tom Haynes      2014-12-11  392  	mirror_array_cnt = be32_to_cpup(p++);
d67ae825 Tom Haynes      2014-12-11  393  	dprintk("%s: stripe_unit=%llu mirror_array_cnt=%u\n", __func__,
d67ae825 Tom Haynes      2014-12-11  394  		stripe_unit, mirror_array_cnt);
d67ae825 Tom Haynes      2014-12-11  395  
d67ae825 Tom Haynes      2014-12-11  396  	if (mirror_array_cnt > NFS4_FLEXFILE_LAYOUT_MAX_MIRROR_CNT ||
d67ae825 Tom Haynes      2014-12-11  397  	    mirror_array_cnt == 0)
d67ae825 Tom Haynes      2014-12-11  398  		goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  399  
d67ae825 Tom Haynes      2014-12-11  400  	rc = -ENOMEM;
d67ae825 Tom Haynes      2014-12-11  401  	fls = kzalloc(sizeof(*fls), gfp_flags);
d67ae825 Tom Haynes      2014-12-11  402  	if (!fls)
d67ae825 Tom Haynes      2014-12-11  403  		goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  404  
d67ae825 Tom Haynes      2014-12-11  405  	fls->mirror_array_cnt = mirror_array_cnt;
d67ae825 Tom Haynes      2014-12-11  406  	fls->stripe_unit = stripe_unit;
d67ae825 Tom Haynes      2014-12-11  407  	fls->mirror_array = kcalloc(fls->mirror_array_cnt,
d67ae825 Tom Haynes      2014-12-11  408  				    sizeof(fls->mirror_array[0]), gfp_flags);
d67ae825 Tom Haynes      2014-12-11  409  	if (fls->mirror_array == NULL)
d67ae825 Tom Haynes      2014-12-11  410  		goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  411  
d67ae825 Tom Haynes      2014-12-11  412  	for (i = 0; i < fls->mirror_array_cnt; i++) {
266d12d4 Trond Myklebust 2015-08-24  413  		struct nfs4_ff_layout_mirror *mirror;
bbf32642 NeilBrown       2018-02-19  414  		struct cred *kcred;
3c189a1f NeilBrown       2018-02-19  415  		const struct cred *cred;
df462af3 NeilBrown       2018-02-19  416  		kuid_t uid;
df462af3 NeilBrown       2018-02-19  417  		kgid_t gid;
90a0be00 Jeff Layton     2016-04-21  418  		u32 ds_count, fh_count, id;
d67ae825 Tom Haynes      2014-12-11  419  		int j;
d67ae825 Tom Haynes      2014-12-11  420  
d67ae825 Tom Haynes      2014-12-11  421  		rc = -EIO;
d67ae825 Tom Haynes      2014-12-11  422  		p = xdr_inline_decode(&stream, 4);
d67ae825 Tom Haynes      2014-12-11  423  		if (!p)
d67ae825 Tom Haynes      2014-12-11  424  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  425  		ds_count = be32_to_cpup(p);
d67ae825 Tom Haynes      2014-12-11  426  
d67ae825 Tom Haynes      2014-12-11  427  		/* FIXME: allow for striping? */
d67ae825 Tom Haynes      2014-12-11  428  		if (ds_count != 1)
d67ae825 Tom Haynes      2014-12-11  429  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  430  
28a0d72c Trond Myklebust 2015-08-24  431  		fls->mirror_array[i] = ff_layout_alloc_mirror(gfp_flags);
d67ae825 Tom Haynes      2014-12-11  432  		if (fls->mirror_array[i] == NULL) {
d67ae825 Tom Haynes      2014-12-11  433  			rc = -ENOMEM;
d67ae825 Tom Haynes      2014-12-11  434  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  435  		}
d67ae825 Tom Haynes      2014-12-11  436  
d67ae825 Tom Haynes      2014-12-11  437  		fls->mirror_array[i]->ds_count = ds_count;
d67ae825 Tom Haynes      2014-12-11  438  
d67ae825 Tom Haynes      2014-12-11  439  		/* deviceid */
65990d1a Fred Isaman     2016-09-30  440  		rc = decode_deviceid(&stream, &fls->mirror_array[i]->devid);
d67ae825 Tom Haynes      2014-12-11  441  		if (rc)
d67ae825 Tom Haynes      2014-12-11  442  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  443  
d67ae825 Tom Haynes      2014-12-11  444  		/* efficiency */
d67ae825 Tom Haynes      2014-12-11  445  		rc = -EIO;
d67ae825 Tom Haynes      2014-12-11  446  		p = xdr_inline_decode(&stream, 4);
d67ae825 Tom Haynes      2014-12-11  447  		if (!p)
d67ae825 Tom Haynes      2014-12-11  448  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  449  		fls->mirror_array[i]->efficiency = be32_to_cpup(p);
d67ae825 Tom Haynes      2014-12-11  450  
d67ae825 Tom Haynes      2014-12-11  451  		/* stateid */
93b717fd Trond Myklebust 2016-05-16  452  		rc = decode_pnfs_stateid(&stream, &fls->mirror_array[i]->stateid);
d67ae825 Tom Haynes      2014-12-11  453  		if (rc)
d67ae825 Tom Haynes      2014-12-11  454  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  455  
d67ae825 Tom Haynes      2014-12-11  456  		/* fh */
662f9a10 Dan Carpenter   2017-05-20  457  		rc = -EIO;
d67ae825 Tom Haynes      2014-12-11  458  		p = xdr_inline_decode(&stream, 4);
d67ae825 Tom Haynes      2014-12-11  459  		if (!p)
d67ae825 Tom Haynes      2014-12-11  460  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  461  		fh_count = be32_to_cpup(p);
d67ae825 Tom Haynes      2014-12-11  462  
d67ae825 Tom Haynes      2014-12-11  463  		fls->mirror_array[i]->fh_versions =
d67ae825 Tom Haynes      2014-12-11  464  			kzalloc(fh_count * sizeof(struct nfs_fh),
d67ae825 Tom Haynes      2014-12-11  465  				gfp_flags);
d67ae825 Tom Haynes      2014-12-11  466  		if (fls->mirror_array[i]->fh_versions == NULL) {
d67ae825 Tom Haynes      2014-12-11  467  			rc = -ENOMEM;
d67ae825 Tom Haynes      2014-12-11  468  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  469  		}
d67ae825 Tom Haynes      2014-12-11  470  
d67ae825 Tom Haynes      2014-12-11  471  		for (j = 0; j < fh_count; j++) {
d67ae825 Tom Haynes      2014-12-11  472  			rc = decode_nfs_fh(&stream,
d67ae825 Tom Haynes      2014-12-11  473  					   &fls->mirror_array[i]->fh_versions[j]);
d67ae825 Tom Haynes      2014-12-11  474  			if (rc)
d67ae825 Tom Haynes      2014-12-11  475  				goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  476  		}
d67ae825 Tom Haynes      2014-12-11  477  
d67ae825 Tom Haynes      2014-12-11  478  		fls->mirror_array[i]->fh_versions_cnt = fh_count;
d67ae825 Tom Haynes      2014-12-11  479  
d67ae825 Tom Haynes      2014-12-11  480  		/* user */
90a0be00 Jeff Layton     2016-04-21  481  		rc = decode_name(&stream, &id);
d67ae825 Tom Haynes      2014-12-11  482  		if (rc)
d67ae825 Tom Haynes      2014-12-11  483  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  484  
df462af3 NeilBrown       2018-02-19  485  		uid = make_kuid(&init_user_ns, id);
90a0be00 Jeff Layton     2016-04-21  486  
d67ae825 Tom Haynes      2014-12-11  487  		/* group */
90a0be00 Jeff Layton     2016-04-21  488  		rc = decode_name(&stream, &id);
d67ae825 Tom Haynes      2014-12-11  489  		if (rc)
d67ae825 Tom Haynes      2014-12-11  490  			goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  491  
df462af3 NeilBrown       2018-02-19  492  		gid = make_kgid(&init_user_ns, id);
90a0be00 Jeff Layton     2016-04-21  493  
bbf32642 NeilBrown       2018-02-19  494  		if (gfp_flags & __GFP_FS)
bbf32642 NeilBrown       2018-02-19  495  			kcred = prepare_kernel_cred(NULL);
bbf32642 NeilBrown       2018-02-19  496  		else {
bbf32642 NeilBrown       2018-02-19  497  			unsigned int nofs_flags = memalloc_nofs_save();
bbf32642 NeilBrown       2018-02-19  498  			kcred = prepare_kernel_cred(NULL);
bbf32642 NeilBrown       2018-02-19  499  			memalloc_nofs_restore(nofs_flags);
bbf32642 NeilBrown       2018-02-19  500  		}
bbf32642 NeilBrown       2018-02-19  501  		rc = -ENOMEM;
bbf32642 NeilBrown       2018-02-19  502  		if (!kcred)
bbf32642 NeilBrown       2018-02-19  503  			goto out_err_free;
df462af3 NeilBrown       2018-02-19  504  		kcred->fsuid = uid;
df462af3 NeilBrown       2018-02-19  505  		kcred->fsgid = gid;
3c189a1f NeilBrown       2018-02-19  506  		cred = kcred;
90a0be00 Jeff Layton     2016-04-21  507  
3064b686 Jeff Layton     2016-04-21  508  		if (lgr->range.iomode == IOMODE_READ)
3064b686 Jeff Layton     2016-04-21  509  			rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred);
3064b686 Jeff Layton     2016-04-21  510  		else
3064b686 Jeff Layton     2016-04-21  511  			rcu_assign_pointer(fls->mirror_array[i]->rw_cred, cred);
90a0be00 Jeff Layton     2016-04-21  512  
266d12d4 Trond Myklebust 2015-08-24  513  		mirror = ff_layout_add_mirror(lh, fls->mirror_array[i]);
266d12d4 Trond Myklebust 2015-08-24  514  		if (mirror != fls->mirror_array[i]) {
90a0be00 Jeff Layton     2016-04-21  515  			/* swap cred ptrs so free_mirror will clean up old */
3064b686 Jeff Layton     2016-04-21  516  			if (lgr->range.iomode == IOMODE_READ) {
3064b686 Jeff Layton     2016-04-21 @517  				cred = xchg(&mirror->ro_cred, cred);
3064b686 Jeff Layton     2016-04-21  518  				rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred);
3064b686 Jeff Layton     2016-04-21  519  			} else {
3064b686 Jeff Layton     2016-04-21  520  				cred = xchg(&mirror->rw_cred, cred);
3064b686 Jeff Layton     2016-04-21  521  				rcu_assign_pointer(fls->mirror_array[i]->rw_cred, cred);
3064b686 Jeff Layton     2016-04-21  522  			}
266d12d4 Trond Myklebust 2015-08-24  523  			ff_layout_free_mirror(fls->mirror_array[i]);
266d12d4 Trond Myklebust 2015-08-24  524  			fls->mirror_array[i] = mirror;
266d12d4 Trond Myklebust 2015-08-24  525  		}
266d12d4 Trond Myklebust 2015-08-24  526  
3064b686 Jeff Layton     2016-04-21  527  		dprintk("%s: iomode %s uid %u gid %u\n", __func__,
3064b686 Jeff Layton     2016-04-21  528  			lgr->range.iomode == IOMODE_READ ? "READ" : "RW",
df462af3 NeilBrown       2018-02-19  529  			from_kuid(&init_user_ns, uid),
df462af3 NeilBrown       2018-02-19  530  			from_kgid(&init_user_ns, gid));
d67ae825 Tom Haynes      2014-12-11  531  	}
d67ae825 Tom Haynes      2014-12-11  532  
c0f5f505 Trond Myklebust 2015-06-26  533  	p = xdr_inline_decode(&stream, 4);
d0379a5d Trond Myklebust 2015-11-16  534  	if (!p)
d0379a5d Trond Myklebust 2015-11-16  535  		goto out_sort_mirrors;
c0f5f505 Trond Myklebust 2015-06-26  536  	fls->flags = be32_to_cpup(p);
c0f5f505 Trond Myklebust 2015-06-26  537  
d0379a5d Trond Myklebust 2015-11-16  538  	p = xdr_inline_decode(&stream, 4);
d0379a5d Trond Myklebust 2015-11-16  539  	if (!p)
d0379a5d Trond Myklebust 2015-11-16  540  		goto out_sort_mirrors;
d0379a5d Trond Myklebust 2015-11-16  541  	for (i=0; i < fls->mirror_array_cnt; i++)
d0379a5d Trond Myklebust 2015-11-16  542  		fls->mirror_array[i]->report_interval = be32_to_cpup(p);
d0379a5d Trond Myklebust 2015-11-16  543  
d0379a5d Trond Myklebust 2015-11-16  544  out_sort_mirrors:
d67ae825 Tom Haynes      2014-12-11  545  	ff_layout_sort_mirrors(fls);
d67ae825 Tom Haynes      2014-12-11  546  	rc = ff_layout_check_layout(lgr);
d67ae825 Tom Haynes      2014-12-11  547  	if (rc)
d67ae825 Tom Haynes      2014-12-11  548  		goto out_err_free;
d67ae825 Tom Haynes      2014-12-11  549  	ret = &fls->generic_hdr;
d67ae825 Tom Haynes      2014-12-11  550  	dprintk("<-- %s (success)\n", __func__);
d67ae825 Tom Haynes      2014-12-11  551  out_free_page:
d67ae825 Tom Haynes      2014-12-11  552  	__free_page(scratch);
d67ae825 Tom Haynes      2014-12-11  553  	return ret;
d67ae825 Tom Haynes      2014-12-11  554  out_err_free:
d67ae825 Tom Haynes      2014-12-11  555  	_ff_layout_free_lseg(fls);
d67ae825 Tom Haynes      2014-12-11  556  	ret = ERR_PTR(rc);
d67ae825 Tom Haynes      2014-12-11  557  	dprintk("<-- %s (%d)\n", __func__, rc);
d67ae825 Tom Haynes      2014-12-11  558  	goto out_free_page;
d67ae825 Tom Haynes      2014-12-11  559  }
d67ae825 Tom Haynes      2014-12-11  560  

:::::: The code at line 517 was first introduced by commit
:::::: 3064b6861d00b7124558cdf79f9387f948361be3 nfs: have flexfiles mirror keep creds for both ro and rw layouts

:::::: TO: Jeff Layton <jlayton@poochiereds.net>
:::::: CC: Anna Schumaker <Anna.Schumaker@Netapp.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
NeilBrown Feb. 20, 2018, 12:17 a.m. UTC | #2
On Mon, Feb 19 2018, kbuild test robot wrote:

> Hi NeilBrown,
>
> Thank you for the patch! Perhaps something to improve:
>
> [auto build test WARNING on nfs/linux-next]
> [also build test WARNING on v4.16-rc2 next-20180219]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url:    https://github.com/0day-ci/linux/commits/NeilBrown/Remove-generic-rpc-credentials-and-associated-changed-V3/20180219-190836
> base:   git://git.linux-nfs.org/projects/trondmy/linux-nfs.git linux-next
> reproduce:
>         # apt-get install sparse
>         make ARCH=x86_64 allmodconfig
>         make C=1 CF=-D__CHECK_ENDIAN__
>
>
> sparse warnings: (new ones prefixed by >>)
>
>>> fs/nfs/flexfilelayout/flexfilelayout.c:517:40: sparse: incorrect type in initializer (different address spaces) @@ expected struct cred const @@ got cred const @@
>    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: expected struct cred const
>    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: got struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred

Hi Mr Robot :-)
 It looks like you have some strange wild-card expansion happening here.
 I think the above should be
>    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: got struct cred const * cred

Even after correcting the that, I cannot see what the different address
spaces are that might be a problem.
Does anyone have any ideas?

Thanks,
NeilBrown
Philip Li Feb. 22, 2018, 1:51 a.m. UTC | #3
On Tue, Feb 20, 2018 at 11:17:03AM +1100, NeilBrown wrote:
> On Mon, Feb 19 2018, kbuild test robot wrote:
> 
> > Hi NeilBrown,
> >
> > Thank you for the patch! Perhaps something to improve:
> >
> > [auto build test WARNING on nfs/linux-next]
> > [also build test WARNING on v4.16-rc2 next-20180219]
> > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> >
> > url:    https://github.com/0day-ci/linux/commits/NeilBrown/Remove-generic-rpc-credentials-and-associated-changed-V3/20180219-190836
> > base:   git://git.linux-nfs.org/projects/trondmy/linux-nfs.git linux-next
> > reproduce:
> >         # apt-get install sparse
> >         make ARCH=x86_64 allmodconfig
> >         make C=1 CF=-D__CHECK_ENDIAN__
> >
> >
> > sparse warnings: (new ones prefixed by >>)
> >
> >>> fs/nfs/flexfilelayout/flexfilelayout.c:517:40: sparse: incorrect type in initializer (different address spaces) @@ expected struct cred const @@ got cred const @@
> >    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: expected struct cred const
> >    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: got struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred
> 
> Hi Mr Robot :-)
>  It looks like you have some strange wild-card expansion happening here.
>  I think the above should be
> >    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: got struct cred const * cred
thanks for pointing this out, we will fix it.

> 
> Even after correcting the that, I cannot see what the different address
> spaces are that might be a problem.
> Does anyone have any ideas?
> 
> Thanks,
> NeilBrown



> _______________________________________________
> kbuild-all mailing list
> kbuild-all@lists.01.org
> https://lists.01.org/mailman/listinfo/kbuild-all

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
kernel test robot Feb. 22, 2018, 2:31 a.m. UTC | #4
On Thu, Feb 22, 2018 at 09:51:23AM +0800, Philip Li wrote:
>On Tue, Feb 20, 2018 at 11:17:03AM +1100, NeilBrown wrote:
>> On Mon, Feb 19 2018, kbuild test robot wrote:
>>
>> > Hi NeilBrown,
>> >
>> > Thank you for the patch! Perhaps something to improve:
>> >
>> > [auto build test WARNING on nfs/linux-next]
>> > [also build test WARNING on v4.16-rc2 next-20180219]
>> > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>> >
>> > url:    https://github.com/0day-ci/linux/commits/NeilBrown/Remove-generic-rpc-credentials-and-associated-changed-V3/20180219-190836
>> > base:   git://git.linux-nfs.org/projects/trondmy/linux-nfs.git linux-next
>> > reproduce:
>> >         # apt-get install sparse
>> >         make ARCH=x86_64 allmodconfig
>> >         make C=1 CF=-D__CHECK_ENDIAN__
>> >
>> >
>> > sparse warnings: (new ones prefixed by >>)
>> >
>> >>> fs/nfs/flexfilelayout/flexfilelayout.c:517:40: sparse: incorrect type in initializer (different address spaces) @@ expected struct cred const @@ got cred const @@
>> >    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: expected struct cred const
>> >    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: got struct cred const Documentation Kbuild Kconfig Makefile certs drivers firmware fs include samples scripts sound tools cred
>>
>> Hi Mr Robot :-)
>>  It looks like you have some strange wild-card expansion happening here.
>>  I think the above should be
>> >    fs/nfs/flexfilelayout/flexfilelayout.c:517:40: got struct cred const * cred
>thanks for pointing this out, we will fix it.

Obviously the robot shell-expands the '*' in error message ...

>>
>> Even after correcting the that, I cannot see what the different address
>> spaces are that might be a problem.
>> Does anyone have any ideas?
>>
>> Thanks,
>> NeilBrown
>
>
>
>> _______________________________________________
>> kbuild-all mailing list
>> kbuild-all@lists.01.org
>> https://lists.01.org/mailman/listinfo/kbuild-all
>
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index a2c0dfc6fdc0..4b24fe01cd70 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -256,7 +256,7 @@  static int nlm_wait_on_grace(wait_queue_head_t *queue)
  * Generic NLM call
  */
 static int
-nlmclnt_call(struct rpc_cred *cred, struct nlm_rqst *req, u32 proc)
+nlmclnt_call(const struct cred *cred, struct nlm_rqst *req, u32 proc)
 {
 	struct nlm_host	*host = req->a_host;
 	struct rpc_clnt	*clnt;
@@ -401,7 +401,7 @@  int nlm_async_reply(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *t
  *      completion in order to be able to correctly track the lock
  *      state.
  */
-static int nlmclnt_async_call(struct rpc_cred *cred, struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
+static int nlmclnt_async_call(const struct cred *cred, struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
 {
 	struct rpc_message msg = {
 		.rpc_argp	= &req->a_args,
@@ -510,7 +510,7 @@  static int do_vfs_lock(struct file_lock *fl)
 static int
 nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
 {
-	struct rpc_cred *cred = nfs_file_cred(fl->fl_file);
+	const struct cred *cred = nfs_file_cred(fl->fl_file);
 	struct nlm_host	*host = req->a_host;
 	struct nlm_res	*resp = &req->a_res;
 	struct nlm_wait *block = NULL;
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 7cb5c38c19e4..a8a05352ae84 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -584,7 +584,7 @@  static int decode_sector_number(__be32 **rp, sector_t *sp)
 
 static struct nfs4_deviceid_node *
 bl_find_get_deviceid(struct nfs_server *server,
-		const struct nfs4_deviceid *id, struct rpc_cred *cred,
+		const struct nfs4_deviceid *id, const struct cred *cred,
 		gfp_t gfp_mask)
 {
 	struct nfs4_deviceid_node *node;
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index d8b47624fee2..9ec2082e42d8 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -26,7 +26,7 @@ 
 static void nfs_free_delegation(struct nfs_delegation *delegation)
 {
 	if (delegation->cred) {
-		put_rpccred(delegation->cred);
+		put_cred(delegation->cred);
 		delegation->cred = NULL;
 	}
 	kfree_rcu(delegation, rcu);
@@ -174,11 +174,11 @@  static int nfs_delegation_claim_opens(struct inode *inode,
  * @res: new delegation state from server
  *
  */
-void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
+void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
 				  struct nfs_openres *res)
 {
 	struct nfs_delegation *delegation;
-	struct rpc_cred *oldcred = NULL;
+	const struct cred *oldcred = NULL;
 
 	rcu_read_lock();
 	delegation = rcu_dereference(NFS_I(inode)->delegation);
@@ -189,12 +189,13 @@  void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
 			delegation->type = res->delegation_type;
 			delegation->pagemod_limit = res->pagemod_limit;
 			oldcred = delegation->cred;
-			delegation->cred = get_rpccred(cred);
+			delegation->cred = get_cred(cred);
 			clear_bit(NFS_DELEGATION_NEED_RECLAIM,
 				  &delegation->flags);
 			spin_unlock(&delegation->lock);
 			rcu_read_unlock();
-			put_rpccred(oldcred);
+			if (oldcred)
+				put_cred(oldcred);
 			trace_nfs4_reclaim_delegation(inode, res->delegation_type);
 			return;
 		}
@@ -333,7 +334,7 @@  nfs_update_inplace_delegation(struct nfs_delegation *delegation,
  *
  * Returns zero on success, or a negative errno value.
  */
-int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
+int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred, struct nfs_openres *res)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_client *clp = server->nfs_client;
@@ -349,7 +350,7 @@  int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
 	delegation->type = res->delegation_type;
 	delegation->pagemod_limit = res->pagemod_limit;
 	delegation->change_attr = inode_peek_iversion_raw(inode);
-	delegation->cred = get_rpccred(cred);
+	delegation->cred = get_cred(cred);
 	delegation->inode = inode;
 	delegation->flags = 1<<NFS_DELEGATION_REFERENCED;
 	spin_lock_init(&delegation->lock);
@@ -954,7 +955,7 @@  void nfs_reap_expired_delegations(struct nfs_client *clp)
 	struct nfs_delegation *delegation;
 	struct nfs_server *server;
 	struct inode *inode;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	nfs4_stateid stateid;
 
 restart:
@@ -976,7 +977,7 @@  void nfs_reap_expired_delegations(struct nfs_client *clp)
 				nfs_sb_deactive(server->super);
 				goto restart;
 			}
-			cred = get_rpccred_rcu(delegation->cred);
+			cred = get_cred_rcu(delegation->cred);
 			nfs4_stateid_copy(&stateid, &delegation->stateid);
 			clear_bit(NFS_DELEGATION_TEST_EXPIRED, &delegation->flags);
 			rcu_read_unlock();
@@ -985,7 +986,8 @@  void nfs_reap_expired_delegations(struct nfs_client *clp)
 				nfs_revoke_delegation(inode, &stateid);
 				nfs_inode_find_state_and_recover(inode, &stateid);
 			}
-			put_rpccred(cred);
+			if (cred)
+				put_cred(cred);
 			if (nfs4_server_rebooted(clp)) {
 				nfs_inode_mark_test_expired_delegation(server,inode);
 				iput(inode);
@@ -1079,7 +1081,7 @@  bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
  * otherwise "false" is returned.
  */
 bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags,
-		nfs4_stateid *dst, struct rpc_cred **cred)
+		nfs4_stateid *dst, const struct cred **cred)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
 	struct nfs_delegation *delegation;
@@ -1093,7 +1095,7 @@  bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags,
 		nfs4_stateid_copy(dst, &delegation->stateid);
 		nfs_mark_delegation_referenced(delegation);
 		if (cred)
-			*cred = get_rpccred(delegation->cred);
+			*cred = get_cred(delegation->cred);
 	}
 	rcu_read_unlock();
 	return ret;
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 185a09f37a89..06f37f823029 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -15,7 +15,7 @@ 
  */
 struct nfs_delegation {
 	struct list_head super_list;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	struct inode *inode;
 	nfs4_stateid stateid;
 	fmode_t type;
@@ -36,8 +36,8 @@  enum {
 	NFS_DELEGATION_TEST_EXPIRED,
 };
 
-int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
-void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
+int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred, struct nfs_openres *res);
+void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred, struct nfs_openres *res);
 int nfs4_inode_return_delegation(struct inode *inode);
 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
 void nfs_inode_return_delegation_noreclaim(struct inode *inode);
@@ -58,10 +58,10 @@  void nfs_mark_test_expired_all_delegations(struct nfs_client *clp);
 void nfs_reap_expired_delegations(struct nfs_client *clp);
 
 /* NFSv4 delegation-related procedures */
-int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync);
+int nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync);
 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid, fmode_t type);
 int nfs4_lock_delegation_recall(struct file_lock *fl, struct nfs4_state *state, const nfs4_stateid *stateid);
-bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, nfs4_stateid *dst, struct rpc_cred **cred);
+bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags, nfs4_stateid *dst, const struct cred **cred);
 bool nfs4_refresh_delegation_stateid(nfs4_stateid *dst, struct inode *inode);
 
 void nfs_mark_delegation_referenced(struct nfs_delegation *delegation);
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 8ef4a9c50b10..00864ee0f170 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -224,16 +224,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;
+	const struct cred	*cred;
 
 	ff_layout_remove_mirror(mirror);
 	kfree(mirror->fh_versions);
 	cred = rcu_access_pointer(mirror->ro_cred);
 	if (cred)
-		put_rpccred(cred);
+		put_cred(cred);
 	cred = rcu_access_pointer(mirror->rw_cred);
 	if (cred)
-		put_rpccred(cred);
+		put_cred(cred);
 	nfs4_ff_layout_put_deviceid(mirror->mirror_ds);
 	kfree(mirror);
 }
@@ -411,9 +411,8 @@  ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
 
 	for (i = 0; i < fls->mirror_array_cnt; i++) {
 		struct nfs4_ff_layout_mirror *mirror;
-		struct auth_cred acred = {};
-		struct rpc_cred	__rcu *cred;
 		struct cred *kcred;
+		const struct cred *cred;
 		kuid_t uid;
 		kgid_t gid;
 		u32 ds_count, fh_count, id;
@@ -504,15 +503,7 @@  ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
 			goto out_err_free;
 		kcred->fsuid = uid;
 		kcred->fsgid = 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;
-		}
+		cred = kcred;
 
 		if (lgr->range.iomode == IOMODE_READ)
 			rcu_assign_pointer(fls->mirror_array[i]->ro_cred, cred);
@@ -1716,7 +1707,7 @@  ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
 	struct pnfs_layout_segment *lseg = hdr->lseg;
 	struct nfs4_pnfs_ds *ds;
 	struct rpc_clnt *ds_clnt;
-	struct rpc_cred *ds_cred;
+	const struct cred *ds_cred;
 	loff_t offset = hdr->args.offset;
 	u32 idx = hdr->pgio_mirror_idx;
 	int vers;
@@ -1762,7 +1753,7 @@  ff_layout_read_pagelist(struct nfs_pgio_header *hdr)
 			  vers == 3 ? &ff_layout_read_call_ops_v3 :
 				      &ff_layout_read_call_ops_v4,
 			  0, RPC_TASK_SOFTCONN);
-	put_rpccred(ds_cred);
+	put_cred(ds_cred);
 	return PNFS_ATTEMPTED;
 
 out_failed:
@@ -1778,7 +1769,7 @@  ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
 	struct pnfs_layout_segment *lseg = hdr->lseg;
 	struct nfs4_pnfs_ds *ds;
 	struct rpc_clnt *ds_clnt;
-	struct rpc_cred *ds_cred;
+	const struct cred *ds_cred;
 	loff_t offset = hdr->args.offset;
 	int vers;
 	struct nfs_fh *fh;
@@ -1823,7 +1814,7 @@  ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync)
 			  vers == 3 ? &ff_layout_write_call_ops_v3 :
 				      &ff_layout_write_call_ops_v4,
 			  sync, RPC_TASK_SOFTCONN);
-	put_rpccred(ds_cred);
+	put_cred(ds_cred);
 	return PNFS_ATTEMPTED;
 
 out_failed:
@@ -1853,7 +1844,7 @@  static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
 	struct pnfs_layout_segment *lseg = data->lseg;
 	struct nfs4_pnfs_ds *ds;
 	struct rpc_clnt *ds_clnt;
-	struct rpc_cred *ds_cred;
+	const struct cred *ds_cred;
 	u32 idx;
 	int vers, ret;
 	struct nfs_fh *fh;
@@ -1893,7 +1884,7 @@  static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how)
 				   vers == 3 ? &ff_layout_commit_call_ops_v3 :
 					       &ff_layout_commit_call_ops_v4,
 				   how, RPC_TASK_SOFTCONN);
-	put_rpccred(ds_cred);
+	put_cred(ds_cred);
 	return ret;
 out_err:
 	pnfs_generic_prepare_to_resend_writes(data);
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.h b/fs/nfs/flexfilelayout/flexfilelayout.h
index 411798346e48..e1521e422269 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.h
+++ b/fs/nfs/flexfilelayout/flexfilelayout.h
@@ -81,8 +81,8 @@  struct nfs4_ff_layout_mirror {
 	u32				fh_versions_cnt;
 	struct nfs_fh			*fh_versions;
 	nfs4_stateid			stateid;
-	struct rpc_cred	__rcu		*ro_cred;
-	struct rpc_cred	__rcu		*rw_cred;
+	const struct cred __rcu		*ro_cred;
+	const struct cred __rcu		*rw_cred;
 	refcount_t			ref;
 	spinlock_t			lock;
 	unsigned long			flags;
@@ -225,8 +225,8 @@  nfs4_ff_find_or_create_ds_client(struct pnfs_layout_segment *lseg,
 				 u32 ds_idx,
 				 struct nfs_client *ds_clp,
 				 struct inode *inode);
-struct rpc_cred *ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg,
-				       u32 ds_idx, struct rpc_cred *mdscred);
+const struct cred *ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg,
+				       u32 ds_idx, const struct cred *mdscred);
 bool ff_layout_avoid_mds_available_ds(struct pnfs_layout_segment *lseg);
 bool ff_layout_avoid_read_on_rw(struct pnfs_layout_segment *lseg);
 
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index d62279d3fc5d..b357dcbd2ed3 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -329,10 +329,10 @@  int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo,
 	return 0;
 }
 
-static struct rpc_cred *
+static const struct cred *
 ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode)
 {
-	struct rpc_cred *cred, __rcu **pcred;
+	const struct cred *cred, __rcu **pcred;
 
 	if (iomode == IOMODE_READ)
 		pcred = &mirror->ro_cred;
@@ -345,7 +345,7 @@  ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode)
 		if (!cred)
 			break;
 
-		cred = get_rpccred_rcu(cred);
+		cred = get_cred_rcu(cred);
 	} while(!cred);
 	rcu_read_unlock();
 	return cred;
@@ -445,19 +445,19 @@  nfs4_ff_layout_prepare_ds(struct pnfs_layout_segment *lseg, u32 ds_idx,
 	return ds;
 }
 
-struct rpc_cred *
+const struct cred *
 ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg, u32 ds_idx,
-		      struct rpc_cred *mdscred)
+		      const struct cred *mdscred)
 {
 	struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx);
-	struct rpc_cred *cred;
+	const struct cred *cred;
 
 	if (mirror) {
 		cred = ff_layout_get_mirror_cred(mirror, lseg->pls_range.iomode);
 		if (!cred)
-			cred = get_rpccred(mdscred);
+			cred = get_cred(mdscred);
 	} else {
-		cred = get_rpccred(mdscred);
+		cred = get_cred(mdscred);
 	}
 	return cred;
 }
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 38de9a06fc33..70e4dd2eb297 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -911,13 +911,11 @@  struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
 						struct file *filp)
 {
 	struct nfs_open_context *ctx;
-	struct rpc_cred *cred = rpc_lookup_cred();
-	if (IS_ERR(cred))
-		return ERR_CAST(cred);
+	const struct cred *cred = get_current_cred();
 
 	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx) {
-		put_rpccred(cred);
+		put_cred(cred);
 		return ERR_PTR(-ENOMEM);
 	}
 	nfs_sb_active(dentry->d_sb);
@@ -960,7 +958,7 @@  static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
 	if (inode != NULL)
 		NFS_PROTO(inode)->close_context(ctx, is_sync);
 	if (ctx->cred != NULL)
-		put_rpccred(ctx->cred);
+		put_cred(ctx->cred);
 	dput(ctx->dentry);
 	nfs_sb_deactive(sb);
 	put_rpccred(ctx->ll_cred);
@@ -1008,7 +1006,7 @@  EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
 /*
  * Given an inode, search for an open context with the desired characteristics
  */
-struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode)
+struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct cred *cred, fmode_t mode)
 {
 	struct nfs_inode *nfsi = NFS_I(inode);
 	struct nfs_open_context *pos, *ctx = NULL;
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 8357ff69962f..0be530a1a059 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -254,7 +254,7 @@  struct nfs_pgio_header *nfs_pgio_header_alloc(const struct nfs_rw_ops *);
 void nfs_pgio_header_free(struct nfs_pgio_header *);
 int nfs_generic_pgio(struct nfs_pageio_descriptor *, struct nfs_pgio_header *);
 int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
-		      struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,
+		      const struct cred *cred, const struct nfs_rpc_ops *rpc_ops,
 		      const struct rpc_call_ops *call_ops, int how, int flags);
 void nfs_free_request(struct nfs_page *req);
 struct nfs_pgio_mirror *
@@ -269,7 +269,7 @@  static inline bool nfs_pgio_has_mirroring(struct nfs_pageio_descriptor *desc)
 static inline bool nfs_match_open_context(const struct nfs_open_context *ctx1,
 		const struct nfs_open_context *ctx2)
 {
-	return ctx1->cred == ctx2->cred && ctx1->state == ctx2->state;
+	return cred_fscmp(ctx1->cred, ctx2->cred) == 0 && ctx1->state == ctx2->state;
 }
 
 /* nfs2xdr.c */
@@ -565,10 +565,10 @@  extern struct nfs_client *nfs4_init_client(struct nfs_client *clp,
 			    const struct nfs_client_initdata *);
 extern int nfs40_walk_client_list(struct nfs_client *clp,
 				struct nfs_client **result,
-				struct rpc_cred *cred);
+				const struct cred *cred);
 extern int nfs41_walk_client_list(struct nfs_client *clp,
 				struct nfs_client **result,
-				struct rpc_cred *cred);
+				const struct cred *cred);
 extern int nfs4_test_session_trunk(struct rpc_clnt *,
 				struct rpc_xprt *,
 				void *);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 2b1291396162..263f8c8d9280 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -191,20 +191,15 @@  static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 		.access		= entry->mask,
 	};
 	struct nfs3_accessres	res;
-	struct auth_cred acred = {
-		.cred		= entry->cred,
-	};
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_ACCESS],
 		.rpc_argp	= &arg,
 		.rpc_resp	= &res,
-		.rpc_cred	= rpc_lookup_generic_cred(&acred, 0, GFP_NOFS),
+		.rpc_cred	= entry->cred,
 	};
 	int status = -ENOMEM;
 
 	dprintk("NFS call  access\n");
-	if (!msg.rpc_cred)
-		goto out;
 	res.fattr = nfs_alloc_fattr();
 	if (res.fattr == NULL)
 		goto out;
@@ -215,8 +210,6 @@  static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 		nfs_access_set_mask(entry, res.access);
 	nfs_free_fattr(res.fattr);
 out:
-	if (msg.rpc_cred)
-		put_rpccred(msg.rpc_cred);
 	dprintk("NFS reply access: %d\n", status);
 	return status;
 }
@@ -623,15 +616,11 @@  nfs3_proc_readdir(struct dentry *dentry, const struct cred *cred,
 		.verf		= verf,
 		.plus		= plus
 	};
-	struct auth_cred acred = {
-		.cred		= cred,
-	};
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs3_procedures[NFS3PROC_READDIR],
 		.rpc_argp	= &arg,
 		.rpc_resp	= &res,
-		.rpc_cred	= rpc_lookup_generic_cred(&acred,
-							  0, GFP_NOFS),
+		.rpc_cred	= cred,
 	};
 	int status = -ENOMEM;
 
@@ -641,8 +630,6 @@  nfs3_proc_readdir(struct dentry *dentry, const struct cred *cred,
 	dprintk("NFS call  readdir%s %d\n",
 			plus? "plus" : "", (unsigned int) cookie);
 
-	if (!msg.rpc_cred)
-		return -ENOMEM;
 	res.dir_attr = nfs_alloc_fattr();
 	if (res.dir_attr == NULL)
 		goto out;
@@ -654,7 +641,6 @@  nfs3_proc_readdir(struct dentry *dentry, const struct cred *cred,
 
 	nfs_free_fattr(res.dir_attr);
 out:
-	put_rpccred(msg.rpc_cred);
 	dprintk("NFS reply readdir%s: %d\n",
 			plus? "plus" : "", status);
 	return status;
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 725b20fc2ebf..c8995291b5a1 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -60,7 +60,7 @@  struct nfs4_minor_version_ops {
 	void	(*free_lock_state)(struct nfs_server *,
 			struct nfs4_lock_state *);
 	int	(*test_and_free_expired)(struct nfs_server *,
-			nfs4_stateid *, struct rpc_cred *);
+			nfs4_stateid *, const struct cred *);
 	struct nfs_seqid *
 		(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t);
 	int	(*session_trunk)(struct rpc_clnt *, struct rpc_xprt *, void *);
@@ -105,7 +105,7 @@  struct nfs4_state_owner {
 	unsigned long        so_expires;
 	struct rb_node	     so_server_node;
 
-	struct rpc_cred	     *so_cred;	 /* Associated cred */
+	const struct cred    *so_cred;	 /* Associated cred */
 
 	spinlock_t	     so_lock;
 	atomic_t	     so_count;
@@ -206,27 +206,27 @@  struct nfs4_state_recovery_ops {
 	int state_flag_bit;
 	int (*recover_open)(struct nfs4_state_owner *, struct nfs4_state *);
 	int (*recover_lock)(struct nfs4_state *, struct file_lock *);
-	int (*establish_clid)(struct nfs_client *, struct rpc_cred *);
-	int (*reclaim_complete)(struct nfs_client *, struct rpc_cred *);
+	int (*establish_clid)(struct nfs_client *, const struct cred *);
+	int (*reclaim_complete)(struct nfs_client *, const struct cred *);
 	int (*detect_trunking)(struct nfs_client *, struct nfs_client **,
-		struct rpc_cred *);
+		const struct cred *);
 };
 
 struct nfs4_add_xprt_data {
 	struct nfs_client	*clp;
-	struct rpc_cred		*cred;
+	const struct cred	*cred;
 };
 
 struct nfs4_state_maintenance_ops {
-	int (*sched_state_renewal)(struct nfs_client *, struct rpc_cred *, unsigned);
-	struct rpc_cred * (*get_state_renewal_cred)(struct nfs_client *);
-	int (*renew_lease)(struct nfs_client *, struct rpc_cred *);
+	int (*sched_state_renewal)(struct nfs_client *, const struct cred *, unsigned);
+	const struct cred * (*get_state_renewal_cred)(struct nfs_client *);
+	int (*renew_lease)(struct nfs_client *, const struct cred *);
 };
 
 struct nfs4_mig_recovery_ops {
 	int (*get_locations)(struct inode *, struct nfs4_fs_locations *,
-		struct page *, struct rpc_cred *);
-	int (*fsid_present)(struct inode *, struct rpc_cred *);
+		struct page *, const struct cred *);
+	int (*fsid_present)(struct inode *, const struct cred *);
 };
 
 extern const struct dentry_operations nfs4_dentry_operations;
@@ -252,21 +252,21 @@  extern int nfs4_call_sync(struct rpc_clnt *, struct nfs_server *,
 			  struct rpc_message *, struct nfs4_sequence_args *,
 			  struct nfs4_sequence_res *, int);
 extern void nfs4_init_sequence(struct nfs4_sequence_args *, struct nfs4_sequence_res *, int);
-extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *);
-extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *);
+extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, const struct cred *, struct nfs4_setclientid_res *);
+extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, const struct cred *);
 extern int nfs4_proc_get_rootfh(struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *, bool);
-extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, struct rpc_cred *cred);
-extern int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred);
+extern int nfs4_proc_bind_conn_to_session(struct nfs_client *, const struct cred *cred);
+extern int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred);
 extern int nfs4_destroy_clientid(struct nfs_client *clp);
-extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *);
-extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *);
+extern int nfs4_init_clientid(struct nfs_client *, const struct cred *);
+extern int nfs41_init_clientid(struct nfs_client *, const struct cred *);
 extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait);
 extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
 extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *,
 				  struct nfs4_fs_locations *, struct page *);
 extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *,
-		struct page *page, struct rpc_cred *);
-extern int nfs4_proc_fsid_present(struct inode *, struct rpc_cred *);
+		struct page *page, const struct cred *);
+extern int nfs4_proc_fsid_present(struct inode *, const struct cred *);
 extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, const struct qstr *,
 			    struct nfs_fh *, struct nfs_fattr *);
 extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
@@ -278,8 +278,8 @@  extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
 
 #if defined(CONFIG_NFS_V4_1)
 extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res *);
-extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *);
-extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *);
+extern int nfs4_proc_create_session(struct nfs_client *, const struct cred *);
+extern int nfs4_proc_destroy_session(struct nfs4_session *, const struct cred *);
 extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
 		struct nfs_fsinfo *fsinfo);
 extern int nfs4_proc_layoutcommit(struct nfs4_layoutcommit_data *data,
@@ -409,16 +409,16 @@  extern void nfs4_set_lease_period(struct nfs_client *clp,
 
 
 /* nfs4state.c */
-struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp);
-struct rpc_cred *nfs4_get_machine_cred(struct nfs_client *clp);
-struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp);
+const struct cred *nfs4_get_clid_cred(struct nfs_client *clp);
+const struct cred *nfs4_get_machine_cred(struct nfs_client *clp);
+const struct cred *nfs4_get_renew_cred(struct nfs_client *clp);
 int nfs4_discover_server_trunking(struct nfs_client *clp,
 			struct nfs_client **);
 int nfs40_discover_server_trunking(struct nfs_client *clp,
-			struct nfs_client **, struct rpc_cred *);
+			struct nfs_client **, const struct cred *);
 #if defined(CONFIG_NFS_V4_1)
 int nfs41_discover_server_trunking(struct nfs_client *clp,
-			struct nfs_client **, struct rpc_cred *);
+			struct nfs_client **, const struct cred *);
 extern void nfs4_schedule_session_recovery(struct nfs4_session *, int);
 extern void nfs41_notify_server(struct nfs_client *);
 #else
@@ -427,7 +427,7 @@  static inline void nfs4_schedule_session_recovery(struct nfs4_session *session,
 }
 #endif /* CONFIG_NFS_V4_1 */
 
-extern struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *, struct rpc_cred *, gfp_t);
+extern struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *, const struct cred *, gfp_t);
 extern void nfs4_put_state_owner(struct nfs4_state_owner *);
 extern void nfs4_purge_state_owners(struct nfs_server *);
 extern struct nfs4_state * nfs4_get_open_state(struct inode *, struct nfs4_state_owner *);
@@ -453,7 +453,7 @@  extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
 extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
 extern int nfs4_select_rw_stateid(struct nfs4_state *, fmode_t,
 		const struct nfs_lock_context *, nfs4_stateid *,
-		struct rpc_cred **);
+		const struct cred **);
 extern bool nfs4_refresh_open_stateid(nfs4_stateid *dst,
 		struct nfs4_state *state);
 extern bool nfs4_copy_open_stateid(nfs4_stateid *dst,
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 04612c24d394..558905774e00 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -530,7 +530,7 @@  static int nfs4_match_client(struct nfs_client  *pos,  struct nfs_client *new,
  */
 int nfs40_walk_client_list(struct nfs_client *new,
 			   struct nfs_client **result,
-			   struct rpc_cred *cred)
+			   const struct cred *cred)
 {
 	struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
 	struct nfs_client *pos, *prev = NULL;
@@ -696,7 +696,7 @@  int nfs4_detect_session_trunking(struct nfs_client *clp,
  */
 int nfs41_walk_client_list(struct nfs_client *new,
 			   struct nfs_client **result,
-			   struct rpc_cred *cred)
+			   const struct cred *cred)
 {
 	struct nfs_net *nn = net_generic(new->cl_net, nfs_net_id);
 	struct nfs_client *pos, *prev = NULL;
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index dc46e4d64e6b..df98c3cc1141 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -92,19 +92,19 @@  static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct nfs_fsinf
 static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
 static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct nfs_fattr *, struct nfs4_label *label);
 static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label);
-static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
+static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
 			    struct nfs_fattr *fattr, struct iattr *sattr,
 			    struct nfs_open_context *ctx, struct nfs4_label *ilabel,
 			    struct nfs4_label *olabel);
 #ifdef CONFIG_NFS_V4_1
 static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
-		struct rpc_cred *cred,
+		const struct cred *cred,
 		struct nfs4_slot *slot,
 		bool is_privileged);
 static int nfs41_test_stateid(struct nfs_server *, nfs4_stateid *,
-		struct rpc_cred *);
+		const struct cred *);
 static int nfs41_free_stateid(struct nfs_server *, const nfs4_stateid *,
-		struct rpc_cred *, bool);
+		const struct cred *, bool);
 #endif
 
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
@@ -333,7 +333,7 @@  static void nfs4_setup_readdir(u64 cookie, __be32 *verifier, struct dentry *dent
 
 static void nfs4_test_and_free_stateid(struct nfs_server *server,
 		nfs4_stateid *stateid,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	const struct nfs4_minor_version_ops *ops = server->nfs_client->cl_mvops;
 
@@ -342,7 +342,7 @@  static void nfs4_test_and_free_stateid(struct nfs_server *server,
 
 static void __nfs4_free_revoked_stateid(struct nfs_server *server,
 		nfs4_stateid *stateid,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	stateid->type = NFS4_REVOKED_STATEID_TYPE;
 	nfs4_test_and_free_stateid(server, stateid, cred);
@@ -350,7 +350,7 @@  static void __nfs4_free_revoked_stateid(struct nfs_server *server,
 
 static void nfs4_free_revoked_stateid(struct nfs_server *server,
 		const nfs4_stateid *stateid,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	nfs4_stateid tmp;
 
@@ -866,7 +866,7 @@  static const struct rpc_call_ops nfs41_call_sync_ops = {
 
 static void
 nfs4_sequence_process_interrupted(struct nfs_client *client,
-		struct nfs4_slot *slot, struct rpc_cred *cred)
+		struct nfs4_slot *slot, const struct cred *cred)
 {
 	struct rpc_task *task;
 
@@ -897,7 +897,7 @@  EXPORT_SYMBOL_GPL(nfs4_sequence_done);
 
 static void
 nfs4_sequence_process_interrupted(struct nfs_client *client,
-		struct nfs4_slot *slot, struct rpc_cred *cred)
+		struct nfs4_slot *slot, const struct cred *cred)
 {
 	WARN_ON_ONCE(1);
 	slot->interrupted = 0;
@@ -1709,7 +1709,7 @@  static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
 		rcu_read_unlock();
 		nfs_release_seqid(opendata->o_arg.seqid);
 		if (!opendata->is_recover) {
-			ret = nfs_may_open(state->inode, state->owner->so_cred->cr_cred, open_mode);
+			ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
 			if (ret != 0)
 				goto out;
 		}
@@ -2393,7 +2393,7 @@  static int _nfs4_recover_proc_open(struct nfs4_opendata *data)
  * Note that in the non-execute case, we want to turn off permission
  * checking if we just created a new file (POSIX open() semantics).
  */
-static int nfs4_opendata_access(struct rpc_cred *cred,
+static int nfs4_opendata_access(const struct cred *cred,
 				struct nfs4_opendata *opendata,
 				struct nfs4_state *state, fmode_t fmode,
 				int openflags)
@@ -2420,7 +2420,7 @@  static int nfs4_opendata_access(struct rpc_cred *cred,
 	} else if ((fmode & FMODE_READ) && !opendata->file_created)
 		mask = NFS4_ACCESS_READ;
 
-	cache.cred = cred->cr_cred;
+	cache.cred = cred;
 	nfs_access_set_mask(&cache, opendata->o_res.access_result);
 	nfs_access_add_cache(state->inode, &cache);
 
@@ -2561,7 +2561,7 @@  static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *st
 
 static int nfs40_test_and_free_expired_stateid(struct nfs_server *server,
 		nfs4_stateid *stateid,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	return -NFS4ERR_BAD_STATEID;
 }
@@ -2569,7 +2569,7 @@  static int nfs40_test_and_free_expired_stateid(struct nfs_server *server,
 #if defined(CONFIG_NFS_V4_1)
 static int nfs41_test_and_free_expired_stateid(struct nfs_server *server,
 		nfs4_stateid *stateid,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	int status;
 
@@ -2603,7 +2603,7 @@  static void nfs41_check_delegation_stateid(struct nfs4_state *state)
 	struct nfs_server *server = NFS_SERVER(state->inode);
 	nfs4_stateid stateid;
 	struct nfs_delegation *delegation;
-	struct rpc_cred *cred;
+	const struct cred *cred = NULL;
 	int status;
 
 	/* Get the delegation credential for use by test/free_stateid */
@@ -2623,14 +2623,16 @@  static void nfs41_check_delegation_stateid(struct nfs4_state *state)
 		return;
 	}
 
-	cred = get_rpccred(delegation->cred);
+	if (delegation->cred)
+		cred = get_cred(delegation->cred);
 	rcu_read_unlock();
 	status = nfs41_test_and_free_expired_stateid(server, &stateid, cred);
 	trace_nfs4_test_delegation_stateid(state, NULL, status);
 	if (status == -NFS4ERR_EXPIRED || status == -NFS4ERR_BAD_STATEID)
 		nfs_finish_clear_delegation_stateid(state, &stateid);
 
-	put_rpccred(cred);
+	if (delegation->cred)
+		put_cred(cred);
 }
 
 /**
@@ -2653,7 +2655,7 @@  static int nfs41_check_expired_locks(struct nfs4_state *state)
 	spin_lock(&state->state_lock);
 	list_for_each_entry(lsp, &state->lock_states, ls_locks) {
 		if (test_bit(NFS_LOCK_INITIALIZED, &lsp->ls_flags)) {
-			struct rpc_cred *cred = lsp->ls_state->owner->so_cred;
+			const struct cred *cred = lsp->ls_state->owner->so_cred;
 
 			refcount_inc(&lsp->ls_count);
 			spin_unlock(&state->state_lock);
@@ -2697,7 +2699,7 @@  static int nfs41_check_open_stateid(struct nfs4_state *state)
 {
 	struct nfs_server *server = NFS_SERVER(state->inode);
 	nfs4_stateid *stateid = &state->open_stateid;
-	struct rpc_cred *cred = state->owner->so_cred;
+	const struct cred *cred = state->owner->so_cred;
 	int status;
 
 	if (test_bit(NFS_OPEN_STATE, &state->flags) == 0) {
@@ -2837,7 +2839,7 @@  static int _nfs4_do_open(struct inode *dir,
 	struct nfs_server       *server = NFS_SERVER(dir);
 	struct nfs4_opendata *opendata;
 	struct dentry *dentry = ctx->dentry;
-	struct rpc_cred *cred = ctx->cred;
+	const struct cred *cred = ctx->cred;
 	struct nfs4_threshold **ctx_th = &ctx->mdsthreshold;
 	fmode_t fmode = ctx->mode & (FMODE_READ|FMODE_WRITE|FMODE_EXEC);
 	enum open_claim_type4 claim = NFS4_OPEN_CLAIM_NULL;
@@ -3003,7 +3005,7 @@  static struct nfs4_state *nfs4_do_open(struct inode *dir,
 static int _nfs4_do_setattr(struct inode *inode,
 			    struct nfs_setattrargs *arg,
 			    struct nfs_setattrres *res,
-			    struct rpc_cred *cred,
+			    const struct cred *cred,
 			    struct nfs_open_context *ctx)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
@@ -3013,7 +3015,7 @@  static int _nfs4_do_setattr(struct inode *inode,
 		.rpc_resp	= res,
 		.rpc_cred	= cred,
 	};
-	struct rpc_cred *delegation_cred = NULL;
+	const struct cred *delegation_cred = NULL;
 	unsigned long timestamp = jiffies;
 	fmode_t fmode;
 	bool truncate;
@@ -3046,14 +3048,15 @@  static int _nfs4_do_setattr(struct inode *inode,
 
 	status = nfs4_call_sync(server->client, server, &msg, &arg->seq_args, &res->seq_res, 1);
 
-	put_rpccred(delegation_cred);
+	if (delegation_cred)
+		put_cred(delegation_cred);
 	if (status == 0 && ctx != NULL)
 		renew_lease(server, timestamp);
 	trace_nfs4_setattr(inode, &arg->stateid, status);
 	return status;
 }
 
-static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
+static int nfs4_do_setattr(struct inode *inode, const struct cred *cred,
 			   struct nfs_fattr *fattr, struct iattr *sattr,
 			   struct nfs_open_context *ctx, struct nfs4_label *ilabel,
 			   struct nfs4_label *olabel)
@@ -3842,7 +3845,7 @@  nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 		  struct iattr *sattr)
 {
 	struct inode *inode = d_inode(dentry);
-	struct rpc_cred *cred = NULL;
+	const struct cred *cred = NULL;
 	struct nfs_open_context *ctx = NULL;
 	struct nfs4_label *label = NULL;
 	int status;
@@ -4054,24 +4057,17 @@  static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
 	struct nfs4_accessres res = {
 		.server = server,
 	};
-	struct auth_cred acred = {
-		.cred = entry->cred,
-	};
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_ACCESS],
 		.rpc_argp = &args,
 		.rpc_resp = &res,
-		.rpc_cred = rpc_lookup_generic_cred(&acred, 0, GFP_NOFS),
+		.rpc_cred = entry->cred,
 	};
 	int status = 0;
 
-	if (!msg.rpc_cred)
-		return -ENOMEM;
 	res.fattr = nfs_alloc_fattr();
-	if (res.fattr == NULL) {
-		put_rpccred(msg.rpc_cred);
+	if (res.fattr == NULL)
 		return -ENOMEM;
-	}
 
 	status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
 	if (!status) {
@@ -4079,7 +4075,6 @@  static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry
 		nfs_refresh_inode(inode, res.fattr);
 	}
 	nfs_free_fattr(res.fattr);
-	put_rpccred(msg.rpc_cred);
 	return status;
 }
 
@@ -4516,23 +4511,17 @@  static int _nfs4_proc_readdir(struct dentry *dentry, const struct cred *cred,
 		.plus = plus,
 	};
 	struct nfs4_readdir_res res;
-	struct auth_cred acred = {
-		.cred		= cred,
-	};
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READDIR],
 		.rpc_argp = &args,
 		.rpc_resp = &res,
-		.rpc_cred = rpc_lookup_generic_cred(&acred,
-						    0, GFP_NOFS),
+		.rpc_cred = cred,
 	};
 	int			status;
 
 	dprintk("%s: dentry = %pd2, cookie = %Lu\n", __func__,
 			dentry,
 			(unsigned long long)cookie);
-	if (!msg.rpc_cred)
-		return -ENOMEM;
 	nfs4_setup_readdir(cookie, NFS_I(dir)->cookieverf, dentry, &args);
 	res.pgbase = args.pgbase;
 	status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0);
@@ -4543,7 +4532,6 @@  static int _nfs4_proc_readdir(struct dentry *dentry, const struct cred *cred,
 
 	nfs_invalidate_atime(dir);
 
-	put_rpccred(msg.rpc_cred);
 	dprintk("%s: returns %d\n", __func__, status);
 	return status;
 }
@@ -5038,7 +5026,7 @@  static const struct rpc_call_ops nfs4_renew_ops = {
 	.rpc_release = nfs4_renew_release,
 };
 
-static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags)
+static int nfs4_proc_async_renew(struct nfs_client *clp, const struct cred *cred, unsigned renew_flags)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -5062,7 +5050,7 @@  static int nfs4_proc_async_renew(struct nfs_client *clp, struct rpc_cred *cred,
 			&nfs4_renew_ops, data);
 }
 
-static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred)
+static int nfs4_proc_renew(struct nfs_client *clp, const struct cred *cred)
 {
 	struct rpc_message msg = {
 		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_RENEW],
@@ -5475,7 +5463,6 @@  nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
 {
 	struct nfs4_label ilabel, *olabel = NULL;
 	struct nfs_fattr fattr;
-	struct rpc_cred *cred;
 	int status;
 
 	if (!nfs_server_capable(inode, NFS_CAP_SECURITY_LABEL))
@@ -5488,10 +5475,6 @@  nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
 	ilabel.label = (char *)buf;
 	ilabel.len = buflen;
 
-	cred = rpc_lookup_cred();
-	if (IS_ERR(cred))
-		return PTR_ERR(cred);
-
 	olabel = nfs4_label_alloc(NFS_SERVER(inode), GFP_KERNEL);
 	if (IS_ERR(olabel)) {
 		status = -PTR_ERR(olabel);
@@ -5504,7 +5487,6 @@  nfs4_set_security_label(struct inode *inode, const void *buf, size_t buflen)
 
 	nfs4_label_free(olabel);
 out:
-	put_rpccred(cred);
 	return status;
 }
 #endif	/* CONFIG_NFS_V4_SECURITY_LABEL */
@@ -5665,13 +5647,13 @@  static const struct rpc_call_ops nfs4_setclientid_ops = {
  * @clp: state data structure
  * @program: RPC program for NFSv4 callback service
  * @port: IP port number for NFS4 callback service
- * @cred: RPC credential to use for this call
+ * @cred: credential to use for this call
  * @res: where to place the result
  *
  * Returns zero, a negative errno, or a negative NFS4ERR status code.
  */
 int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
-		unsigned short port, struct rpc_cred *cred,
+		unsigned short port, const struct cred *cred,
 		struct nfs4_setclientid_res *res)
 {
 	nfs4_verifier sc_verifier;
@@ -5740,13 +5722,13 @@  int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
  * nfs4_proc_setclientid_confirm - Confirm client ID
  * @clp: state data structure
  * @res: result of a previous SETCLIENTID
- * @cred: RPC credential to use for this call
+ * @cred: credential to use for this call
  *
  * Returns zero, a negative errno, or a negative NFS4ERR status code.
  */
 int nfs4_proc_setclientid_confirm(struct nfs_client *clp,
 		struct nfs4_setclientid_res *arg,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID_CONFIRM],
@@ -5901,7 +5883,7 @@  static const struct rpc_call_ops nfs4_delegreturn_ops = {
 	.rpc_release = nfs4_delegreturn_release,
 };
 
-static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
+static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync)
 {
 	struct nfs4_delegreturndata *data;
 	struct nfs_server *server = NFS_SERVER(inode);
@@ -5968,7 +5950,7 @@  static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co
 	return status;
 }
 
-int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
+int nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, const nfs4_stateid *stateid, int issync)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs4_exception exception = { };
@@ -7020,7 +7002,7 @@  int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir,
  */
 static int _nfs40_proc_get_locations(struct inode *inode,
 				     struct nfs4_fs_locations *locations,
-				     struct page *page, struct rpc_cred *cred)
+				     struct page *page, const struct cred *cred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct rpc_clnt *clnt = server->client;
@@ -7078,7 +7060,7 @@  static int _nfs40_proc_get_locations(struct inode *inode,
  */
 static int _nfs41_proc_get_locations(struct inode *inode,
 				     struct nfs4_fs_locations *locations,
-				     struct page *page, struct rpc_cred *cred)
+				     struct page *page, const struct cred *cred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct rpc_clnt *clnt = server->client;
@@ -7138,7 +7120,7 @@  static int _nfs41_proc_get_locations(struct inode *inode,
  */
 int nfs4_proc_get_locations(struct inode *inode,
 			    struct nfs4_fs_locations *locations,
-			    struct page *page, struct rpc_cred *cred)
+			    struct page *page, const struct cred *cred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_client *clp = server->nfs_client;
@@ -7169,7 +7151,7 @@  int nfs4_proc_get_locations(struct inode *inode,
  * is appended to this compound to identify the client ID which is
  * performing recovery.
  */
-static int _nfs40_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
+static int _nfs40_proc_fsid_present(struct inode *inode, const struct cred *cred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
@@ -7216,7 +7198,7 @@  static int _nfs40_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
  * this operation is identified in the SEQUENCE operation in this
  * compound.
  */
-static int _nfs41_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
+static int _nfs41_proc_fsid_present(struct inode *inode, const struct cred *cred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct rpc_clnt *clnt = server->client;
@@ -7264,7 +7246,7 @@  static int _nfs41_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
  *  NFS4ERR code if some error occurred on the server, or a
  *  negative errno if a local failure occurred.
  */
-int nfs4_proc_fsid_present(struct inode *inode, struct rpc_cred *cred)
+int nfs4_proc_fsid_present(struct inode *inode, const struct cred *cred)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_client *clp = server->nfs_client;
@@ -7311,7 +7293,7 @@  static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
 		.rpc_resp = &res,
 	};
 	struct rpc_clnt *clnt = NFS_SERVER(dir)->client;
-	struct rpc_cred *cred = NULL;
+	const struct cred *cred = NULL;
 
 	if (use_integrity) {
 		clnt = NFS_SERVER(dir)->nfs_client->cl_rpcclient;
@@ -7329,7 +7311,7 @@  static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct
 	dprintk("NFS reply  secinfo: %d\n", status);
 
 	if (cred)
-		put_rpccred(cred);
+		put_cred(cred);
 
 	return status;
 }
@@ -7410,7 +7392,7 @@  static
 int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt,
 		struct rpc_xprt *xprt,
 		struct nfs_client *clp,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	int status;
 	struct nfs41_bind_conn_to_session_args args = {
@@ -7472,7 +7454,7 @@  int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt,
 
 struct rpc_bind_conn_calldata {
 	struct nfs_client *clp;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 };
 
 static int
@@ -7485,7 +7467,7 @@  nfs4_proc_bind_conn_to_session_callback(struct rpc_clnt *clnt,
 	return nfs4_proc_bind_one_conn_to_session(clnt, xprt, p->clp, p->cred);
 }
 
-int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_bind_conn_to_session(struct nfs_client *clp, const struct cred *cred)
 {
 	struct rpc_bind_conn_calldata data = {
 		.clp = clp,
@@ -7651,7 +7633,7 @@  static const struct rpc_call_ops nfs4_exchange_id_call_ops = {
  * Wrapper for EXCHANGE_ID operation.
  */
 static struct rpc_task *
-nfs4_run_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
+nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred,
 			u32 sp4_how, struct rpc_xprt *xprt)
 {
 	struct rpc_message msg = {
@@ -7747,7 +7729,7 @@  nfs4_run_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
  *
  * Wrapper for EXCHANGE_ID operation.
  */
-static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
+static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred,
 			u32 sp4_how)
 {
 	struct rpc_task *task;
@@ -7814,7 +7796,7 @@  static int _nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred,
  *
  * Will attempt to negotiate SP4_MACH_CRED if krb5i / krb5p auth is used.
  */
-int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cred)
 {
 	rpc_authflavor_t authflavor = clp->cl_rpcclient->cl_auth->au_flavor;
 	int status;
@@ -7876,7 +7858,7 @@  int nfs4_test_session_trunk(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
 EXPORT_SYMBOL_GPL(nfs4_test_session_trunk);
 
 static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_CLIENTID],
@@ -7894,7 +7876,7 @@  static int _nfs4_proc_destroy_clientid(struct nfs_client *clp,
 }
 
 static int nfs4_proc_destroy_clientid(struct nfs_client *clp,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	unsigned int loop;
 	int ret;
@@ -7915,7 +7897,7 @@  static int nfs4_proc_destroy_clientid(struct nfs_client *clp,
 
 int nfs4_destroy_clientid(struct nfs_client *clp)
 {
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	int ret = 0;
 
 	if (clp->cl_mvops->minor_version < 1)
@@ -7927,7 +7909,7 @@  int nfs4_destroy_clientid(struct nfs_client *clp)
 	cred = nfs4_get_clid_cred(clp);
 	ret = nfs4_proc_destroy_clientid(clp, cred);
 	if (cred)
-		put_rpccred(cred);
+		put_cred(cred);
 	switch (ret) {
 	case 0:
 	case -NFS4ERR_STALE_CLIENTID:
@@ -8144,7 +8126,7 @@  static void nfs4_update_session(struct nfs4_session *session,
 }
 
 static int _nfs4_proc_create_session(struct nfs_client *clp,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct nfs4_session *session = clp->cl_session;
 	struct nfs41_create_session_args args = {
@@ -8196,7 +8178,7 @@  static int _nfs4_proc_create_session(struct nfs_client *clp,
  * It is the responsibility of the caller to verify the session is
  * expired before calling this routine.
  */
-int nfs4_proc_create_session(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_proc_create_session(struct nfs_client *clp, const struct cred *cred)
 {
 	int status;
 	unsigned *ptr;
@@ -8227,7 +8209,7 @@  int nfs4_proc_create_session(struct nfs_client *clp, struct rpc_cred *cred)
  * The caller must serialize access to this routine.
  */
 int nfs4_proc_destroy_session(struct nfs4_session *session,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct rpc_message msg = {
 		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_DESTROY_SESSION],
@@ -8329,7 +8311,7 @@  static const struct rpc_call_ops nfs41_sequence_ops = {
 };
 
 static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
-		struct rpc_cred *cred,
+		const struct cred *cred,
 		struct nfs4_slot *slot,
 		bool is_privileged)
 {
@@ -8374,7 +8356,7 @@  static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp,
 	return ret;
 }
 
-static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred, unsigned renew_flags)
+static int nfs41_proc_async_sequence(struct nfs_client *clp, const struct cred *cred, unsigned renew_flags)
 {
 	struct rpc_task *task;
 	int ret = 0;
@@ -8390,7 +8372,7 @@  static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cr
 	return ret;
 }
 
-static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
+static int nfs4_proc_sequence(struct nfs_client *clp, const struct cred *cred)
 {
 	struct rpc_task *task;
 	int ret;
@@ -8484,7 +8466,7 @@  static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {
  * Issue a global reclaim complete.
  */
 static int nfs41_proc_reclaim_complete(struct nfs_client *clp,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct nfs4_reclaim_complete_data *calldata;
 	struct rpc_task *task;
@@ -8886,7 +8868,7 @@  int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync)
 static int
 _nfs4_proc_getdeviceinfo(struct nfs_server *server,
 		struct pnfs_device *pdev,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct nfs4_getdeviceinfo_args args = {
 		.pdev = pdev,
@@ -8918,7 +8900,7 @@  _nfs4_proc_getdeviceinfo(struct nfs_server *server,
 
 int nfs4_proc_getdeviceinfo(struct nfs_server *server,
 		struct pnfs_device *pdev,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct nfs4_exception exception = { };
 	int err;
@@ -8975,7 +8957,7 @@  static void nfs4_layoutcommit_release(void *calldata)
 	pnfs_cleanup_layoutcommit(data);
 	nfs_post_op_update_inode_force_wcc(data->args.inode,
 					   data->res.fattr);
-	put_rpccred(data->cred);
+	put_cred(data->cred);
 	nfs_iput_and_deactive(data->inode);
 	kfree(data);
 }
@@ -9051,7 +9033,7 @@  _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
 		.rpc_resp = &res,
 	};
 	struct rpc_clnt *clnt = server->client;
-	struct rpc_cred *cred = NULL;
+	const struct cred *cred = NULL;
 	int status;
 
 	if (use_integrity) {
@@ -9066,7 +9048,7 @@  _nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
 	dprintk("<-- %s status=%d\n", __func__, status);
 
 	if (cred)
-		put_rpccred(cred);
+		put_cred(cred);
 
 	return status;
 }
@@ -9179,7 +9161,7 @@  nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
 
 static int _nfs41_test_stateid(struct nfs_server *server,
 		nfs4_stateid *stateid,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	int status;
 	struct nfs41_test_stateid_args args = {
@@ -9241,7 +9223,7 @@  static void nfs4_handle_delay_or_session_error(struct nfs_server *server,
  */
 static int nfs41_test_stateid(struct nfs_server *server,
 		nfs4_stateid *stateid,
-		struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct nfs4_exception exception = { };
 	int err;
@@ -9293,7 +9275,7 @@  static const struct rpc_call_ops nfs41_free_stateid_ops = {
 
 static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
 		const nfs4_stateid *stateid,
-		struct rpc_cred *cred,
+		const struct cred *cred,
 		bool privileged)
 {
 	struct rpc_message msg = {
@@ -9341,7 +9323,7 @@  static struct rpc_task *_nfs41_free_stateid(struct nfs_server *server,
  */
 static int nfs41_free_stateid(struct nfs_server *server,
 		const nfs4_stateid *stateid,
-		struct rpc_cred *cred,
+		const struct cred *cred,
 		bool is_recovery)
 {
 	struct rpc_task *task;
@@ -9356,7 +9338,7 @@  static int nfs41_free_stateid(struct nfs_server *server,
 static void
 nfs41_free_lock_state(struct nfs_server *server, struct nfs4_lock_state *lsp)
 {
-	struct rpc_cred *cred = lsp->ls_state->owner->so_cred;
+	const struct cred *cred = lsp->ls_state->owner->so_cred;
 
 	nfs41_free_stateid(server, &lsp->ls_stateid, cred, false);
 	nfs4_free_lock_state(server, lsp);
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 8880cd958210..6ea431b067dd 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -57,7 +57,7 @@  nfs4_renew_state(struct work_struct *work)
 	const struct nfs4_state_maintenance_ops *ops;
 	struct nfs_client *clp =
 		container_of(work, struct nfs_client, cl_renewd.work);
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	long lease;
 	unsigned long last, now;
 	unsigned renew_flags = 0;
@@ -90,7 +90,7 @@  nfs4_renew_state(struct work_struct *work)
 
 			/* Queue an asynchronous RENEW. */
 			ret = ops->sched_state_renewal(clp, cred, renew_flags);
-			put_rpccred(cred);
+			put_cred(cred);
 			switch (ret) {
 			default:
 				goto out_exp;
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c
index 769b85655c4b..fa01f9a367e7 100644
--- a/fs/nfs/nfs4session.c
+++ b/fs/nfs/nfs4session.c
@@ -573,12 +573,12 @@  static void nfs4_destroy_session_slot_tables(struct nfs4_session *session)
 void nfs4_destroy_session(struct nfs4_session *session)
 {
 	struct rpc_xprt *xprt;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 
 	cred = nfs4_get_clid_cred(session->clp);
 	nfs4_proc_destroy_session(session, cred);
 	if (cred)
-		put_rpccred(cred);
+		put_cred(cred);
 
 	rcu_read_lock();
 	xprt = rcu_dereference(session->clp->cl_rpcclient->cl_xprt);
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index a89c0d79c030..9fd7812c1130 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -79,7 +79,7 @@  const nfs4_stateid invalid_stateid = {
 
 static DEFINE_MUTEX(nfs_clid_init_mutex);
 
-int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs4_init_clientid(struct nfs_client *clp, const struct cred *cred)
 {
 	struct nfs4_setclientid_res clid = {
 		.clientid = clp->cl_clientid,
@@ -126,7 +126,7 @@  int nfs4_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
  */
 int nfs40_discover_server_trunking(struct nfs_client *clp,
 				   struct nfs_client **result,
-				   struct rpc_cred *cred)
+				   const struct cred *cred)
 {
 	struct nfs4_setclientid_res clid = {
 		.clientid = clp->cl_clientid,
@@ -156,9 +156,9 @@  int nfs40_discover_server_trunking(struct nfs_client *clp,
 	return status;
 }
 
-struct rpc_cred *nfs4_get_machine_cred(struct nfs_client *clp)
+const struct cred *nfs4_get_machine_cred(struct nfs_client *clp)
 {
-	return get_rpccred(rpc_machine_cred());
+	return get_cred(rpc_machine_cred());
 }
 
 static void nfs4_root_machine_cred(struct nfs_client *clp)
@@ -169,10 +169,10 @@  static void nfs4_root_machine_cred(struct nfs_client *clp)
 	clp->cl_rpcclient->cl_principal = NULL;
 }
 
-static struct rpc_cred *
+static const struct cred *
 nfs4_get_renew_cred_server_locked(struct nfs_server *server)
 {
-	struct rpc_cred *cred = NULL;
+	const struct cred *cred = NULL;
 	struct nfs4_state_owner *sp;
 	struct rb_node *pos;
 
@@ -182,7 +182,7 @@  nfs4_get_renew_cred_server_locked(struct nfs_server *server)
 		sp = rb_entry(pos, struct nfs4_state_owner, so_server_node);
 		if (list_empty(&sp->so_states))
 			continue;
-		cred = get_rpccred(sp->so_cred);
+		cred = get_cred(sp->so_cred);
 		break;
 	}
 	return cred;
@@ -195,9 +195,9 @@  nfs4_get_renew_cred_server_locked(struct nfs_server *server)
  * Returns an rpc_cred with reference count bumped, or NULL.
  * Caller must hold clp->cl_lock.
  */
-struct rpc_cred *nfs4_get_renew_cred(struct nfs_client *clp)
+const struct cred *nfs4_get_renew_cred(struct nfs_client *clp)
 {
-	struct rpc_cred *cred = NULL;
+	const struct cred *cred = NULL;
 	struct nfs_server *server;
 
 	/* Use machine credentials if available */
@@ -304,7 +304,7 @@  static void nfs41_finish_session_reset(struct nfs_client *clp)
 	nfs41_setup_state_renewal(clp);
 }
 
-int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
+int nfs41_init_clientid(struct nfs_client *clp, const struct cred *cred)
 {
 	int status;
 
@@ -339,7 +339,7 @@  int nfs41_init_clientid(struct nfs_client *clp, struct rpc_cred *cred)
  */
 int nfs41_discover_server_trunking(struct nfs_client *clp,
 				   struct nfs_client **result,
-				   struct rpc_cred *cred)
+				   const struct cred *cred)
 {
 	int status;
 
@@ -377,30 +377,32 @@  int nfs41_discover_server_trunking(struct nfs_client *clp,
  * nfs4_get_clid_cred - Acquire credential for a setclientid operation
  * @clp: client state handle
  *
- * Returns an rpc_cred with reference count bumped, or NULL.
+ * Returns a cred with reference count bumped, or NULL.
  */
-struct rpc_cred *nfs4_get_clid_cred(struct nfs_client *clp)
+const struct cred *nfs4_get_clid_cred(struct nfs_client *clp)
 {
-	struct rpc_cred *cred;
+	const struct cred *cred;
 
 	cred = nfs4_get_machine_cred(clp);
 	return cred;
 }
 
 static struct nfs4_state_owner *
-nfs4_find_state_owner_locked(struct nfs_server *server, struct rpc_cred *cred)
+nfs4_find_state_owner_locked(struct nfs_server *server, const struct cred *cred)
 {
 	struct rb_node **p = &server->state_owners.rb_node,
 		       *parent = NULL;
 	struct nfs4_state_owner *sp;
+	int cmp;
 
 	while (*p != NULL) {
 		parent = *p;
 		sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
+		cmp = cred_fscmp(cred, sp->so_cred);
 
-		if (cred < sp->so_cred)
+		if (cmp < 0)
 			p = &parent->rb_left;
-		else if (cred > sp->so_cred)
+		else if (cmp > 0)
 			p = &parent->rb_right;
 		else {
 			if (!list_empty(&sp->so_lru))
@@ -420,14 +422,16 @@  nfs4_insert_state_owner_locked(struct nfs4_state_owner *new)
 		       *parent = NULL;
 	struct nfs4_state_owner *sp;
 	int err;
+	int cmp;
 
 	while (*p != NULL) {
 		parent = *p;
 		sp = rb_entry(parent, struct nfs4_state_owner, so_server_node);
+		cmp = cred_fscmp(new->so_cred, sp->so_cred);
 
-		if (new->so_cred < sp->so_cred)
+		if (cmp < 0)
 			p = &parent->rb_left;
-		else if (new->so_cred > sp->so_cred)
+		else if (cmp > 0)
 			p = &parent->rb_right;
 		else {
 			if (!list_empty(&sp->so_lru))
@@ -478,7 +482,7 @@  nfs4_destroy_seqid_counter(struct nfs_seqid_counter *sc)
  */
 static struct nfs4_state_owner *
 nfs4_alloc_state_owner(struct nfs_server *server,
-		struct rpc_cred *cred,
+		const struct cred *cred,
 		gfp_t gfp_flags)
 {
 	struct nfs4_state_owner *sp;
@@ -487,7 +491,7 @@  nfs4_alloc_state_owner(struct nfs_server *server,
 	if (!sp)
 		return NULL;
 	sp->so_server = server;
-	sp->so_cred = get_rpccred(cred);
+	sp->so_cred = get_cred(cred);
 	spin_lock_init(&sp->so_lock);
 	INIT_LIST_HEAD(&sp->so_states);
 	nfs4_init_seqid_counter(&sp->so_seqid);
@@ -516,7 +520,7 @@  nfs4_reset_state_owner(struct nfs4_state_owner *sp)
 static void nfs4_free_state_owner(struct nfs4_state_owner *sp)
 {
 	nfs4_destroy_seqid_counter(&sp->so_seqid);
-	put_rpccred(sp->so_cred);
+	put_cred(sp->so_cred);
 	kfree(sp);
 }
 
@@ -553,7 +557,7 @@  static void nfs4_gc_state_owners(struct nfs_server *server)
  * Returns a pointer to an instantiated nfs4_state_owner struct, or NULL.
  */
 struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server,
-					      struct rpc_cred *cred,
+					      const struct cred *cred,
 					      gfp_t gfp_flags)
 {
 	struct nfs_client *clp = server->nfs_client;
@@ -1026,7 +1030,7 @@  bool nfs4_copy_open_stateid(nfs4_stateid *dst, struct nfs4_state *state)
  */
 int nfs4_select_rw_stateid(struct nfs4_state *state,
 		fmode_t fmode, const struct nfs_lock_context *l_ctx,
-		nfs4_stateid *dst, struct rpc_cred **cred)
+		nfs4_stateid *dst, const struct cred **cred)
 {
 	int ret;
 
@@ -1686,7 +1690,7 @@  static void nfs4_state_start_reclaim_reboot(struct nfs_client *clp)
 
 static int nfs4_reclaim_complete(struct nfs_client *clp,
 				 const struct nfs4_state_recovery_ops *ops,
-				 struct rpc_cred *cred)
+				 const struct cred *cred)
 {
 	/* Notify the server we're done reclaiming our state */
 	if (ops->reclaim_complete)
@@ -1737,7 +1741,7 @@  static int nfs4_state_clear_reclaim_reboot(struct nfs_client *clp)
 static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
 {
 	const struct nfs4_state_recovery_ops *ops;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	int err;
 
 	if (!nfs4_state_clear_reclaim_reboot(clp))
@@ -1745,7 +1749,7 @@  static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
 	ops = clp->cl_mvops->reboot_recovery_ops;
 	cred = nfs4_get_clid_cred(clp);
 	err = nfs4_reclaim_complete(clp, ops, cred);
-	put_rpccred(cred);
+	put_cred(cred);
 	if (err == -NFS4ERR_CONN_NOT_BOUND_TO_SESSION)
 		set_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state);
 }
@@ -1841,7 +1845,7 @@  static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov
 
 static int nfs4_check_lease(struct nfs_client *clp)
 {
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	const struct nfs4_state_maintenance_ops *ops =
 		clp->cl_mvops->state_renewal_ops;
 	int status;
@@ -1857,7 +1861,7 @@  static int nfs4_check_lease(struct nfs_client *clp)
 			goto out;
 	}
 	status = ops->renew_lease(clp, cred);
-	put_rpccred(cred);
+	put_cred(cred);
 	if (status == -ETIMEDOUT) {
 		set_bit(NFS4CLNT_CHECK_LEASE, &clp->cl_state);
 		return 0;
@@ -1917,7 +1921,7 @@  static int nfs4_handle_reclaim_lease_error(struct nfs_client *clp, int status)
 
 static int nfs4_establish_lease(struct nfs_client *clp)
 {
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	const struct nfs4_state_recovery_ops *ops =
 		clp->cl_mvops->reboot_recovery_ops;
 	int status;
@@ -1927,7 +1931,7 @@  static int nfs4_establish_lease(struct nfs_client *clp)
 	if (cred == NULL)
 		return -ENOENT;
 	status = ops->establish_clid(clp, cred);
-	put_rpccred(cred);
+	put_cred(cred);
 	if (status != 0)
 		return status;
 	pnfs_destroy_all_layouts(clp);
@@ -1974,7 +1978,7 @@  static int nfs4_purge_lease(struct nfs_client *clp)
  *
  * Returns zero or a negative NFS4ERR status code.
  */
-static int nfs4_try_migration(struct nfs_server *server, struct rpc_cred *cred)
+static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred)
 {
 	struct nfs_client *clp = server->nfs_client;
 	struct nfs4_fs_locations *locations = NULL;
@@ -2042,7 +2046,7 @@  static int nfs4_handle_migration(struct nfs_client *clp)
 	const struct nfs4_state_maintenance_ops *ops =
 				clp->cl_mvops->state_renewal_ops;
 	struct nfs_server *server;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 
 	dprintk("%s: migration reported on \"%s\"\n", __func__,
 			clp->cl_hostname);
@@ -2068,13 +2072,13 @@  static int nfs4_handle_migration(struct nfs_client *clp)
 		rcu_read_unlock();
 		status = nfs4_try_migration(server, cred);
 		if (status < 0) {
-			put_rpccred(cred);
+			put_cred(cred);
 			return status;
 		}
 		goto restart;
 	}
 	rcu_read_unlock();
-	put_rpccred(cred);
+	put_cred(cred);
 	return 0;
 }
 
@@ -2088,7 +2092,7 @@  static int nfs4_handle_lease_moved(struct nfs_client *clp)
 	const struct nfs4_state_maintenance_ops *ops =
 				clp->cl_mvops->state_renewal_ops;
 	struct nfs_server *server;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 
 	dprintk("%s: lease moved reported on \"%s\"\n", __func__,
 			clp->cl_hostname);
@@ -2121,7 +2125,7 @@  static int nfs4_handle_lease_moved(struct nfs_client *clp)
 	rcu_read_unlock();
 
 out:
-	put_rpccred(cred);
+	put_cred(cred);
 	return 0;
 }
 
@@ -2144,7 +2148,7 @@  int nfs4_discover_server_trunking(struct nfs_client *clp,
 	const struct nfs4_state_recovery_ops *ops =
 				clp->cl_mvops->reboot_recovery_ops;
 	struct rpc_clnt *clnt;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	int i, status;
 
 	dprintk("NFS: %s: testing '%s'\n", __func__, clp->cl_hostname);
@@ -2160,7 +2164,7 @@  int nfs4_discover_server_trunking(struct nfs_client *clp,
 		goto out_unlock;
 
 	status = ops->detect_trunking(clp, result, cred);
-	put_rpccred(cred);
+	put_cred(cred);
 	switch (status) {
 	case 0:
 	case -EINTR:
@@ -2348,7 +2352,7 @@  void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags,
 
 static int nfs4_reset_session(struct nfs_client *clp)
 {
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	int status;
 
 	if (!nfs4_has_session(clp))
@@ -2385,13 +2389,13 @@  static int nfs4_reset_session(struct nfs_client *clp)
 			__func__, clp->cl_hostname);
 out:
 	if (cred)
-		put_rpccred(cred);
+		put_cred(cred);
 	return status;
 }
 
 static int nfs4_bind_conn_to_session(struct nfs_client *clp)
 {
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	int ret;
 
 	if (!nfs4_has_session(clp))
@@ -2400,7 +2404,7 @@  static int nfs4_bind_conn_to_session(struct nfs_client *clp)
 	cred = nfs4_get_clid_cred(clp);
 	ret = nfs4_proc_bind_conn_to_session(clp, cred);
 	if (cred)
-		put_rpccred(cred);
+		put_cred(cred);
 	clear_bit(NFS4CLNT_BIND_CONN_TO_SESSION, &clp->cl_state);
 	switch (ret) {
 	case 0:
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 18a7626ac638..59d20f1583c8 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -587,7 +587,7 @@  static void nfs_pgio_prepare(struct rpc_task *task, void *calldata)
 }
 
 int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
-		      struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,
+		      const struct cred *cred, const struct nfs_rpc_ops *rpc_ops,
 		      const struct rpc_call_ops *call_ops, int how, int flags)
 {
 	struct rpc_task *task;
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index c13e826614b5..f1ec3e72badf 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -274,7 +274,7 @@  pnfs_free_layout_hdr(struct pnfs_layout_hdr *lo)
 		list_del_init(&lo->plh_layouts);
 		spin_unlock(&clp->cl_lock);
 	}
-	put_rpccred(lo->plh_lc_cred);
+	put_cred(lo->plh_lc_cred);
 	return ld->free_layout_hdr(lo);
 }
 
@@ -1223,7 +1223,7 @@  pnfs_commit_and_return_layout(struct inode *inode)
 bool pnfs_roc(struct inode *ino,
 		struct nfs4_layoutreturn_args *args,
 		struct nfs4_layoutreturn_res *res,
-		const struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	struct nfs_inode *nfsi = NFS_I(ino);
 	struct nfs_open_context *ctx;
@@ -1475,7 +1475,7 @@  alloc_init_layout_hdr(struct inode *ino,
 	INIT_LIST_HEAD(&lo->plh_return_segs);
 	INIT_LIST_HEAD(&lo->plh_bulk_destroy);
 	lo->plh_inode = ino;
-	lo->plh_lc_cred = get_rpccred(ctx->cred);
+	lo->plh_lc_cred = get_cred(ctx->cred);
 	lo->plh_flags |= 1 << NFS_LAYOUT_INVALID_STID;
 	return lo;
 }
@@ -2607,7 +2607,7 @@  pnfs_layoutcommit_inode(struct inode *inode, bool sync)
 	spin_unlock(&inode->i_lock);
 
 	data->args.inode = inode;
-	data->cred = get_rpccred(nfsi->layout->plh_lc_cred);
+	data->cred = get_cred(nfsi->layout->plh_lc_cred);
 	nfs_fattr_init(&data->fattr);
 	data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
 	data->res.fattr = &data->fattr;
@@ -2620,7 +2620,7 @@  pnfs_layoutcommit_inode(struct inode *inode, bool sync)
 	if (ld->prepare_layoutcommit) {
 		status = ld->prepare_layoutcommit(&data->args);
 		if (status) {
-			put_rpccred(data->cred);
+			put_cred(data->cred);
 			spin_lock(&inode->i_lock);
 			set_bit(NFS_INO_LAYOUTCOMMIT, &nfsi->flags);
 			if (end_pos > nfsi->layout->plh_lwb)
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index daf6cbf5c15f..2265b632b1e3 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -196,7 +196,7 @@  struct pnfs_layout_hdr {
 	u32			plh_return_seq;
 	enum pnfs_iomode	plh_return_iomode;
 	loff_t			plh_lwb; /* last write byte for layoutcommit */
-	struct rpc_cred		*plh_lc_cred; /* layoutcommit cred */
+	const struct cred	*plh_lc_cred; /* layoutcommit cred */
 	struct inode		*plh_inode;
 };
 
@@ -225,7 +225,7 @@  extern void pnfs_unregister_layoutdriver(struct pnfs_layoutdriver_type *);
 /* nfs4proc.c */
 extern int nfs4_proc_getdeviceinfo(struct nfs_server *server,
 				   struct pnfs_device *dev,
-				   struct rpc_cred *cred);
+				   const struct cred *cred);
 extern struct pnfs_layout_segment* nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout, gfp_t gfp_flags);
 extern int nfs4_proc_layoutreturn(struct nfs4_layoutreturn *lrp, bool sync);
 
@@ -272,7 +272,7 @@  int pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
 bool pnfs_roc(struct inode *ino,
 		struct nfs4_layoutreturn_args *args,
 		struct nfs4_layoutreturn_res *res,
-		const struct rpc_cred *cred);
+		const struct cred *cred);
 void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
 		struct nfs4_layoutreturn_res *res,
 		int ret);
@@ -335,7 +335,7 @@  struct nfs4_deviceid_node {
 
 struct nfs4_deviceid_node *
 nfs4_find_get_deviceid(struct nfs_server *server,
-		const struct nfs4_deviceid *id, struct rpc_cred *cred,
+		const struct nfs4_deviceid *id, const struct cred *cred,
 		gfp_t gfp_mask);
 void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
 void nfs4_init_deviceid_node(struct nfs4_deviceid_node *, struct nfs_server *,
@@ -681,7 +681,7 @@  static inline bool
 pnfs_roc(struct inode *ino,
 		struct nfs4_layoutreturn_args *args,
 		struct nfs4_layoutreturn_res *res,
-		const struct rpc_cred *cred)
+		const struct cred *cred)
 {
 	return false;
 }
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c
index e8a07b3f9aaa..7fb59487ee90 100644
--- a/fs/nfs/pnfs_dev.c
+++ b/fs/nfs/pnfs_dev.c
@@ -94,7 +94,7 @@  _lookup_deviceid(const struct pnfs_layoutdriver_type *ld,
 static struct nfs4_deviceid_node *
 nfs4_get_device_info(struct nfs_server *server,
 		const struct nfs4_deviceid *dev_id,
-		struct rpc_cred *cred, gfp_t gfp_flags)
+		const struct cred *cred, gfp_t gfp_flags)
 {
 	struct nfs4_deviceid_node *d = NULL;
 	struct pnfs_device *pdev = NULL;
@@ -184,7 +184,7 @@  __nfs4_find_get_deviceid(struct nfs_server *server,
 
 struct nfs4_deviceid_node *
 nfs4_find_get_deviceid(struct nfs_server *server,
-		const struct nfs4_deviceid *id, struct rpc_cred *cred,
+		const struct nfs4_deviceid *id, const struct cred *cred,
 		gfp_t gfp_mask)
 {
 	long hash = nfs4_deviceid_hash(id);
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index 03aaa60c7768..753ca6f33fb7 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -688,7 +688,7 @@  static int _nfs4_pnfs_v4_ds_connect(struct nfs_server *mds_srv,
 					  rpc_clnt_setup_test_and_add_xprt,
 					  &rpcdata);
 			if (xprtdata.cred)
-				put_rpccred(xprtdata.cred);
+				put_cred(xprtdata.cred);
 		} else {
 			clp = nfs4_set_ds_client(mds_srv,
 						(struct sockaddr *)&da->da_addr,
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 70df66a72d15..402225e8f378 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -495,25 +495,18 @@  nfs_proc_readdir(struct dentry *dentry, const struct cred *cred,
 		.count		= count,
 		.pages		= pages,
 	};
-	struct auth_cred acred = {
-		.cred		= cred,
-	};
 	struct rpc_message	msg = {
 		.rpc_proc	= &nfs_procedures[NFSPROC_READDIR],
 		.rpc_argp	= &arg,
-		.rpc_cred	= rpc_lookup_generic_cred(&acred,
-							  0, GFP_NOFS),
+		.rpc_cred	= cred,
 	};
 	int			status;
 
 	dprintk("NFS call  readdir %d\n", (unsigned int)cookie);
-	if (!msg.rpc_cred)
-		return -ENOMEM;
 	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
 
 	nfs_invalidate_atime(dir);
 
-	put_rpccred(msg.rpc_cred);
 	dprintk("NFS reply readdir: %d\n", status);
 	return status;
 }
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 630b4a3c1a93..0964d669df8e 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -31,7 +31,7 @@ 
 static void
 nfs_free_unlinkdata(struct nfs_unlinkdata *data)
 {
-	put_rpccred(data->cred);
+	put_cred(data->cred);
 	kfree(data->args.name.name);
 	kfree(data);
 }
@@ -177,11 +177,7 @@  nfs_async_unlink(struct dentry *dentry, const struct qstr *name)
 		goto out_free;
 	data->args.name.len = name->len;
 
-	data->cred = rpc_lookup_cred();
-	if (IS_ERR(data->cred)) {
-		status = PTR_ERR(data->cred);
-		goto out_free_name;
-	}
+	data->cred = get_current_cred();
 	data->res.dir_attr = &data->dir_attr;
 	init_waitqueue_head(&data->wq);
 
@@ -202,8 +198,7 @@  nfs_async_unlink(struct dentry *dentry, const struct qstr *name)
 	return 0;
 out_unlock:
 	spin_unlock(&dentry->d_lock);
-	put_rpccred(data->cred);
-out_free_name:
+	put_cred(data->cred);
 	kfree(data->args.name.name);
 out_free:
 	kfree(data);
@@ -307,7 +302,7 @@  static void nfs_async_rename_release(void *calldata)
 	iput(data->old_dir);
 	iput(data->new_dir);
 	nfs_sb_deactive(sb);
-	put_rpccred(data->cred);
+	put_cred(data->cred);
 	kfree(data);
 }
 
@@ -352,7 +347,7 @@  nfs_async_rename(struct inode *old_dir, struct inode *new_dir,
 		return ERR_PTR(-ENOMEM);
 	task_setup_data.callback_data = data;
 
-	data->cred = rpc_lookup_cred();
+	data->cred = get_current_cred();
 	if (IS_ERR(data->cred)) {
 		struct rpc_task *task = ERR_CAST(data->cred);
 		kfree(data);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 37161574e36b..63425f79bd4f 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1248,7 +1248,7 @@  bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx, struct inode *inode)
 	struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;
 	struct rpc_cred *cred = ctx->ll_cred;
 	struct auth_cred acred = {
-		.cred = ctx->cred->cr_cred,
+		.cred = ctx->cred,
 	};
 
 	if (cred && !cred->cr_ops->crmatch(&acred, cred, 0)) {
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index 4d741d2db406..48601d1b36d3 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -746,16 +746,13 @@  static int max_cb_time(struct net *net)
 	return max(nn->nfsd4_lease/10, (time_t)1) * HZ;
 }
 
-static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
+static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc_clnt *client, struct nfsd4_session *ses)
 {
 	if (clp->cl_minorversion == 0) {
 		client->cl_principal = "nfs";
-		return get_rpccred(rpc_machine_cred());
+		return get_cred(rpc_machine_cred());
 	} else {
-		struct rpc_auth *auth = client->cl_auth;
-		struct auth_cred acred = {};
 		struct cred *kcred;
-		struct rpc_cred *ret;
 
 		kcred = prepare_kernel_cred(NULL);
 		if (!kcred)
@@ -763,10 +760,7 @@  static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc
 
 		kcred->uid = ses->se_cb_sec.uid;
 		kcred->gid = ses->se_cb_sec.gid;
-		acred.cred = kcred;
-		ret = auth->au_ops->lookup_cred(client->cl_auth, &acred, 0);
-		put_cred(kcred);
-		return ret;
+		return kcred;
 	}
 }
 
@@ -789,7 +783,7 @@  static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
 		.flags		= (RPC_CLNT_CREATE_NOPING | RPC_CLNT_CREATE_QUIET),
 	};
 	struct rpc_clnt *client;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 
 	if (clp->cl_minorversion == 0) {
 		if (!clp->cl_cred.cr_principal &&
@@ -1118,7 +1112,7 @@  static void nfsd4_process_cb_update(struct nfsd4_callback *cb)
 	if (clp->cl_cb_client) {
 		rpc_shutdown_client(clp->cl_cb_client);
 		clp->cl_cb_client = NULL;
-		put_rpccred(clp->cl_cb_cred);
+		put_cred(clp->cl_cb_cred);
 		clp->cl_cb_cred = NULL;
 	}
 	if (clp->cl_cb_conn.cb_xprt) {
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 0b15dac7e609..61938e75c9e2 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -327,7 +327,7 @@  struct nfs4_client {
 #define NFSD4_CLIENT_CB_FLAG_MASK	(1 << NFSD4_CLIENT_CB_UPDATE | \
 					 1 << NFSD4_CLIENT_CB_KILL)
 	unsigned long		cl_flags;
-	struct rpc_cred		*cl_cb_cred;
+	const struct cred	*cl_cb_cred;
 	struct rpc_clnt		*cl_cb_client;
 	u32			cl_cb_ident;
 #define NFSD4_CB_UP		0
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 702b6fe5d642..3cb005c66c34 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -69,7 +69,7 @@  struct nfs_open_context {
 	struct nfs_lock_context lock_context;
 	fl_owner_t flock_owner;
 	struct dentry *dentry;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	struct rpc_cred *ll_cred;	/* low-level cred - use to check for expiry */
 	struct nfs4_state *state;
 	fmode_t mode;
@@ -367,7 +367,7 @@  extern void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
 				struct nfs4_label *label);
 extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
 extern void put_nfs_open_context(struct nfs_open_context *ctx);
-extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode);
+extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct cred *cred, fmode_t mode);
 extern struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode, struct file *filp);
 extern void nfs_inode_attach_open_context(struct nfs_open_context *ctx);
 extern void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx);
@@ -438,7 +438,7 @@  static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
 	return filp->private_data;
 }
 
-static inline struct rpc_cred *nfs_file_cred(struct file *file)
+static inline const struct cred *nfs_file_cred(struct file *file)
 {
 	if (file != NULL) {
 		struct nfs_open_context *ctx =
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index b33a7f3577e1..28cf7d194a2e 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -269,7 +269,7 @@  struct nfs4_layoutget_res {
 struct nfs4_layoutget {
 	struct nfs4_layoutget_args args;
 	struct nfs4_layoutget_res res;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	gfp_t gfp_flags;
 };
 
@@ -308,7 +308,7 @@  struct nfs4_layoutcommit_data {
 	struct rpc_task task;
 	struct nfs_fattr fattr;
 	struct list_head lseg_list;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	struct inode *inode;
 	struct nfs4_layoutcommit_args args;
 	struct nfs4_layoutcommit_res res;
@@ -333,7 +333,7 @@  struct nfs4_layoutreturn_res {
 struct nfs4_layoutreturn {
 	struct nfs4_layoutreturn_args args;
 	struct nfs4_layoutreturn_res res;
-	struct rpc_cred *cred;
+	const struct cred *cred;
 	struct nfs_client *clp;
 	struct inode *inode;
 	int rpc_status;
@@ -1439,7 +1439,7 @@  enum {
 struct nfs_io_completion;
 struct nfs_pgio_header {
 	struct inode		*inode;
-	struct rpc_cred		*cred;
+	const struct cred		*cred;
 	struct list_head	pages;
 	struct nfs_page		*req;
 	struct nfs_writeverf	verf;		/* Used for writes */
@@ -1500,7 +1500,7 @@  struct nfs_commit_info {
 struct nfs_commit_data {
 	struct rpc_task		task;
 	struct inode		*inode;
-	struct rpc_cred		*cred;
+	const struct cred		*cred;
 	struct nfs_fattr	fattr;
 	struct nfs_writeverf	verf;
 	struct list_head	pages;		/* Coalesced requests we wish to flush */
@@ -1531,7 +1531,7 @@  struct nfs_unlinkdata {
 	struct nfs_removeres res;
 	struct dentry *dentry;
 	wait_queue_head_t wq;
-	struct rpc_cred	*cred;
+	const struct cred *cred;
 	struct nfs_fattr dir_attr;
 	long timeout;
 };
@@ -1539,7 +1539,7 @@  struct nfs_unlinkdata {
 struct nfs_renamedata {
 	struct nfs_renameargs	args;
 	struct nfs_renameres	res;
-	struct rpc_cred		*cred;
+	const struct cred	*cred;
 	struct inode		*old_dir;
 	struct dentry		*old_dentry;
 	struct nfs_fattr	old_fattr;
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
index 0513db589739..ff289e8b24c0 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -67,7 +67,7 @@  struct rpc_cred {
 #define RPCAUTH_CRED_HASHED	2
 #define RPCAUTH_CRED_NEGATIVE	3
 
-struct rpc_cred *rpc_machine_cred(void);
+const struct cred *rpc_machine_cred(void);
 
 /*
  * Client authentication handle
@@ -193,23 +193,5 @@  struct rpc_cred *	get_rpccred(struct rpc_cred *cred)
 	return cred;
 }
 
-/**
- * get_rpccred_rcu - get a reference to a cred using rcu-protected pointer
- * @cred: cred of which to take a reference
- *
- * In some cases, we may have a pointer to a credential to which we
- * want to take a reference, but don't already have one. Because these
- * objects are freed using RCU, we can access the cr_count while its
- * on its way to destruction and only take a reference if it's not already
- * zero.
- */
-static inline struct rpc_cred *
-get_rpccred_rcu(struct rpc_cred *cred)
-{
-	if (atomic_inc_not_zero(&cred->cr_count))
-		return cred;
-	return NULL;
-}
-
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_AUTH_H */
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index be278d92ff4f..57769cf8727a 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -26,7 +26,7 @@  struct rpc_message {
 	const struct rpc_procinfo *rpc_proc;	/* Procedure information */
 	void *			rpc_argp;	/* Arguments */
 	void *			rpc_resp;	/* Result */
-	struct rpc_cred *	rpc_cred;	/* Credentials */
+	const struct cred *	rpc_cred;	/* Credentials */
 };
 
 struct rpc_call_ops;
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index eabe721d6a99..9bc320ef5232 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -40,15 +40,15 @@  static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
 static LIST_HEAD(cred_unused);
 static unsigned long number_cred_unused;
 
-static struct rpc_cred machine_cred = {
-	.cr_count = ATOMIC_INIT(1),
+static struct cred machine_cred = {
+	.usage = ATOMIC_INIT(1),
 };
 
 /*
  * Return the machine_cred pointer to be used whenever
  * the a generic machine credential is needed.
  */
-struct rpc_cred *rpc_machine_cred(void)
+const struct cred *rpc_machine_cred(void)
 {
 	return &machine_cred;
 }
@@ -695,11 +695,15 @@  rpcauth_bind_new_cred(struct rpc_task *task, int lookupflags)
 }
 
 static int
-rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
+rpcauth_bindcred(struct rpc_task *task, const struct cred *cred, int flags)
 {
 	struct rpc_rqst *req = task->tk_rqstp;
 	struct rpc_cred *new = NULL;
 	int lookupflags = 0;
+	struct rpc_auth *auth = task->tk_client->cl_auth;
+	struct auth_cred acred = {
+		.cred = cred,
+	};
 
 	if (flags & RPC_TASK_ASYNC)
 		lookupflags |= RPCAUTH_LOOKUP_NEW;
@@ -708,7 +712,7 @@  rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
 		new = task->tk_op_cred->cr_ops->crbind(task, task->tk_op_cred,
 						       lookupflags);
 	else if (cred != NULL && cred != &machine_cred)
-		new = cred->cr_ops->crbind(task, cred, lookupflags);
+		new = auth->au_ops->lookup_cred(auth, &acred, lookupflags);
 	else if (cred == &machine_cred)
 		new = rpcauth_bind_machine_cred(task, lookupflags);
 
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index be66fec601b0..69a4f581e067 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -1018,7 +1018,7 @@  rpc_task_set_rpc_message(struct rpc_task *task, const struct rpc_message *msg)
 		task->tk_msg.rpc_argp = msg->rpc_argp;
 		task->tk_msg.rpc_resp = msg->rpc_resp;
 		if (msg->rpc_cred != NULL)
-			task->tk_msg.rpc_cred = get_rpccred(msg->rpc_cred);
+			task->tk_msg.rpc_cred = get_cred(msg->rpc_cred);
 	}
 }
 
@@ -2524,7 +2524,7 @@  struct rpc_task *rpc_call_null_helper(struct rpc_clnt *clnt,
 		.rpc_op_cred = cred,
 		.callback_ops = (ops != NULL) ? ops : &rpc_default_ops,
 		.callback_data = data,
-		.flags = flags,
+		.flags = flags | RPC_TASK_NULLCREDS,
 	};
 
 	return rpc_run_task(&task_setup_data);
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index d0091e5ad220..97bf97767766 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -1026,7 +1026,7 @@  static void rpc_release_resources_task(struct rpc_task *task)
 {
 	xprt_release(task);
 	if (task->tk_msg.rpc_cred) {
-		put_rpccred(task->tk_msg.rpc_cred);
+		put_cred(task->tk_msg.rpc_cred);
 		task->tk_msg.rpc_cred = NULL;
 	}
 	rpc_task_release_client(task);