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

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

NFS: move credential expiry tracking out of SUNRPC into NFS.



NFS needs to know when a credential is about to expire so that
it can modify write-back behaviour to finish the write inside the
expiry time.
It currently uses functions in SUNRPC code which make use of a
fairly complex callback scheme and flags in the generic credientials.

As I am working to discard the generic credentials, this has to change.

This patch moves the logic into NFS, in part by finding and caching
the low-level credential in the open_context.  We then make direct
cred-api calls on that.

This makes the code much simpler and removes a dependency on generic
rpc credentials.

Signed-off-by: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 1de7eea9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -962,6 +962,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
	nfs_sb_active(dentry->d_sb);
	ctx->dentry = dget(dentry);
	ctx->cred = cred;
	ctx->ll_cred = NULL;
	ctx->state = NULL;
	ctx->mode = f_mode;
	ctx->flags = 0;
@@ -1001,6 +1002,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
		put_rpccred(ctx->cred);
	dput(ctx->dentry);
	nfs_sb_deactive(sb);
	put_rpccred(ctx->ll_cred);
	kfree(ctx->mdsthreshold);
	kfree_rcu(ctx, rcu_head);
}
+21 −3
Original line number Diff line number Diff line
@@ -1233,9 +1233,12 @@ int
nfs_key_timeout_notify(struct file *filp, struct inode *inode)
{
	struct nfs_open_context *ctx = nfs_file_open_context(filp);
	struct rpc_auth *auth = NFS_SERVER(inode)->client->cl_auth;

	return rpcauth_key_timeout_notify(auth, ctx->cred);
	if (nfs_ctx_key_to_expire(ctx, inode) &&
	    !ctx->ll_cred)
		/* Already expired! */
		return -EACCES;
	return 0;
}

/*
@@ -1244,8 +1247,23 @@ nfs_key_timeout_notify(struct file *filp, struct inode *inode)
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,
	};

	return rpcauth_cred_key_to_expire(auth, ctx->cred);
	if (cred && !cred->cr_ops->crmatch(&acred, cred, 0)) {
		put_rpccred(cred);
		ctx->ll_cred = NULL;
		cred = NULL;
	}
	if (!cred)
		cred = auth->au_ops->lookup_cred(auth, &acred, 0);
	if (!cred || IS_ERR(cred))
		return true;
	ctx->ll_cred = cred;
	return !!(cred->cr_ops->crkey_timeout &&
		  cred->cr_ops->crkey_timeout(cred));
}

/*
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ struct nfs_open_context {
	fl_owner_t flock_owner;
	struct dentry *dentry;
	struct rpc_cred *cred;
	struct rpc_cred *ll_cred;	/* low-level cred - use to check for expiry */
	struct nfs4_state *state;
	fmode_t mode;

+0 −12
Original line number Diff line number Diff line
@@ -37,17 +37,9 @@

struct rpcsec_gss_info;

/* auth_cred ac_flags bits */
enum {
	RPC_CRED_KEY_EXPIRE_SOON = 1, /* underlying cred key will expire soon */
	RPC_CRED_NOTIFY_TIMEOUT = 2,   /* nofity generic cred when underlying
					key will expire soon */
};

struct auth_cred {
	const struct cred *cred;
	const char *principal;	/* If present, this is a machine credential */
	unsigned long ac_flags;
};

/*
@@ -154,7 +146,6 @@ struct rpc_credops {
	int			(*crunwrap_resp)(struct rpc_task *, kxdrdproc_t,
						void *, __be32 *, void *);
	int			(*crkey_timeout)(struct rpc_cred *);
	bool			(*crkey_to_expire)(struct rpc_cred *);
	char *			(*crstringify_acceptor)(struct rpc_cred *);
	bool			(*crneed_reencode)(struct rpc_task *);
};
@@ -198,9 +189,6 @@ int rpcauth_uptodatecred(struct rpc_task *);
int			rpcauth_init_credcache(struct rpc_auth *);
void			rpcauth_destroy_credcache(struct rpc_auth *);
void			rpcauth_clear_credcache(struct rpc_cred_cache *);
int			rpcauth_key_timeout_notify(struct rpc_auth *,
						struct rpc_cred *);
bool			rpcauth_cred_key_to_expire(struct rpc_auth *, struct rpc_cred *);
char *			rpcauth_stringify_acceptor(struct rpc_cred *);

static inline
+0 −23
Original line number Diff line number Diff line
@@ -360,29 +360,6 @@ rpcauth_init_credcache(struct rpc_auth *auth)
}
EXPORT_SYMBOL_GPL(rpcauth_init_credcache);

/*
 * Setup a credential key lifetime timeout notification
 */
int
rpcauth_key_timeout_notify(struct rpc_auth *auth, struct rpc_cred *cred)
{
	if (!cred->cr_auth->au_ops->key_timeout)
		return 0;
	return cred->cr_auth->au_ops->key_timeout(auth, cred);
}
EXPORT_SYMBOL_GPL(rpcauth_key_timeout_notify);

bool
rpcauth_cred_key_to_expire(struct rpc_auth *auth, struct rpc_cred *cred)
{
	if (auth->au_flags & RPCAUTH_AUTH_NO_CRKEY_TIMEOUT)
		return false;
	if (!cred->cr_ops->crkey_to_expire)
		return false;
	return cred->cr_ops->crkey_to_expire(cred);
}
EXPORT_SYMBOL_GPL(rpcauth_cred_key_to_expire);

char *
rpcauth_stringify_acceptor(struct rpc_cred *cred)
{
Loading