Unverified Commit de5817b4 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!14866 NFS: Fix up nfs_ctx_key_to_expire()

parents c7c32544 e5086cdc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -998,7 +998,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry,
		ctx->cred = get_cred(filp->f_cred);
	else
		ctx->cred = get_current_cred();
	ctx->ll_cred = NULL;
	rcu_assign_pointer(ctx->ll_cred, NULL);
	ctx->state = NULL;
	ctx->mode = f_mode;
	ctx->flags = 0;
@@ -1037,7 +1037,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
	put_cred(ctx->cred);
	dput(ctx->dentry);
	nfs_sb_deactive(sb);
	put_rpccred(ctx->ll_cred);
	put_rpccred(rcu_dereference_protected(ctx->ll_cred, 1));
	kfree(ctx->mdsthreshold);
	kfree_rcu(ctx, rcu_head);
}
+28 −13
Original line number Diff line number Diff line
@@ -1221,7 +1221,7 @@ nfs_key_timeout_notify(struct file *filp, struct inode *inode)
	struct nfs_open_context *ctx = nfs_file_open_context(filp);

	if (nfs_ctx_key_to_expire(ctx, inode) &&
	    !ctx->ll_cred)
	    !rcu_access_pointer(ctx->ll_cred))
		/* Already expired! */
		return -EACCES;
	return 0;
@@ -1233,23 +1233,38 @@ 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 rpc_cred *cred, *new, *old = NULL;
	struct auth_cred acred = {
		.cred = ctx->cred,
	};
	bool ret = false;

	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))
	rcu_read_lock();
	cred = rcu_dereference(ctx->ll_cred);
	if (cred && !(cred->cr_ops->crkey_timeout &&
		      cred->cr_ops->crkey_timeout(cred)))
		goto out;
	rcu_read_unlock();

	new = auth->au_ops->lookup_cred(auth, &acred, 0);
	if (new == cred) {
		put_rpccred(new);
		return true;
	ctx->ll_cred = cred;
	return !!(cred->cr_ops->crkey_timeout &&
		  cred->cr_ops->crkey_timeout(cred));
	}
	if (IS_ERR_OR_NULL(new)) {
		new = NULL;
		ret = true;
	} else if (new->cr_ops->crkey_timeout &&
		   new->cr_ops->crkey_timeout(new))
		ret = true;

	rcu_read_lock();
	old = rcu_dereference_protected(xchg(&ctx->ll_cred,
					     RCU_INITIALIZER(new)), 1);
out:
	rcu_read_unlock();
	put_rpccred(old);
	return ret;
}

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