Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a52458b4 authored by NeilBrown's avatar NeilBrown Committed by Anna Schumaker
Browse files

NFS/NFSD/SUNRPC: replace generic creds with 'struct cred'.



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: default avatarNeilBrown <neilb@suse.com>
Acked-by: default avatarJ. Bruce Fields <bfields@redhat.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 684f39b4
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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;
+13 −15
Original line number Diff line number Diff line
@@ -26,10 +26,8 @@

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);
}

@@ -178,13 +176,13 @@ static int nfs_delegation_claim_opens(struct inode *inode,
 * @pagemod_limit: write delegation "space_limit"
 *
 */
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
				  fmode_t type,
				  const nfs4_stateid *stateid,
				  unsigned long pagemod_limit)
{
	struct nfs_delegation *delegation;
	struct rpc_cred *oldcred = NULL;
	const struct cred *oldcred = NULL;

	rcu_read_lock();
	delegation = rcu_dereference(NFS_I(inode)->delegation);
@@ -195,12 +193,12 @@ void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
			delegation->type = type;
			delegation->pagemod_limit = 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);
			put_cred(oldcred);
			trace_nfs4_reclaim_delegation(inode, type);
			return;
		}
@@ -341,7 +339,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,
int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
				  fmode_t type,
				  const nfs4_stateid *stateid,
				  unsigned long pagemod_limit)
@@ -360,7 +358,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred,
	delegation->type = type;
	delegation->pagemod_limit = 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);
@@ -1047,7 +1045,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:
@@ -1069,7 +1067,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();
@@ -1078,7 +1076,7 @@ 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);
			put_cred(cred);
			if (nfs4_server_rebooted(clp)) {
				nfs_inode_mark_test_expired_delegation(server,inode);
				iput(inode);
@@ -1173,7 +1171,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;
@@ -1187,7 +1185,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;
+5 −5
Original line number Diff line number Diff line
@@ -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,9 +36,9 @@ enum {
	NFS_DELEGATION_TEST_EXPIRED,
};

int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred,
int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
		fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit);
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
void nfs_inode_reclaim_delegation(struct inode *inode, const struct cred *cred,
		fmode_t type, const nfs4_stateid *stateid, unsigned long pagemod_limit);
int nfs4_inode_return_delegation(struct inode *inode);
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
@@ -60,10 +60,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);
+11 −22
Original line number Diff line number Diff line
@@ -224,16 +224,14 @@ 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 +409,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 +501,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);
@@ -1714,7 +1703,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;
@@ -1765,7 +1754,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:
@@ -1781,7 +1770,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;
@@ -1830,7 +1819,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:
@@ -1860,7 +1849,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;
@@ -1900,7 +1889,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);
Loading