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

Commit 1ac7e2fd authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4: Clean up the callers of nfs4_open_recover_helper()



Rely on nfs4_try_open_cached() when appropriate.

Also fix an RCU violation in _nfs4_do_open_reclaim()

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 6ee41268
Loading
Loading
Loading
Loading
+20 −22
Original line number Diff line number Diff line
@@ -602,6 +602,19 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
		if (newstate != state)
			return -ESTALE;
	}
	/*
	 * We may have performed cached opens for all three recoveries.
	 * Check if we need to update the current stateid.
	 */
	if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0 &&
	    memcmp(state->stateid.data, state->open_stateid.data, sizeof(state->stateid.data)) != 0) {
		spin_lock(&state->owner->so_lock);
		spin_lock(&state->inode->i_lock);
		if (test_bit(NFS_DELEGATED_STATE, &state->flags) == 0)
			memcpy(state->stateid.data, state->open_stateid.data, sizeof(state->stateid.data));
		spin_unlock(&state->inode->i_lock);
		spin_unlock(&state->owner->so_lock);
	}
	return 0;
}

@@ -611,26 +624,22 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state *
 */
static int _nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
{
	struct nfs_delegation *delegation = NFS_I(state->inode)->delegation;
	struct nfs_delegation *delegation;
	struct nfs4_opendata *opendata;
	int delegation_type = 0;
	int status;

	if (delegation != NULL) {
		if (!(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) {
			memcpy(&state->stateid, &delegation->stateid,
					sizeof(state->stateid));
			set_bit(NFS_DELEGATED_STATE, &state->flags);
			return 0;
		}
		delegation_type = delegation->type;
	}
	opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
	if (opendata == NULL)
		return -ENOMEM;
	opendata->o_arg.claim = NFS4_OPEN_CLAIM_PREVIOUS;
	opendata->o_arg.fh = NFS_FH(state->inode);
	nfs_copy_fh(&opendata->o_res.fh, opendata->o_arg.fh);
	rcu_read_lock();
	delegation = rcu_dereference(NFS_I(state->inode)->delegation);
	if (delegation != NULL && (delegation->flags & NFS_DELEGATION_NEED_RECLAIM) != 0)
		delegation_type = delegation->flags;
	rcu_read_unlock();
	opendata->o_arg.u.delegation_type = delegation_type;
	status = nfs4_open_recover(opendata, state);
	nfs4_opendata_put(opendata);
@@ -980,21 +989,10 @@ static int nfs4_recover_expired_lease(struct nfs_server *server)
 */
static int _nfs4_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
{
	struct inode *inode = state->inode;
	struct nfs_delegation *delegation = NFS_I(inode)->delegation;
	struct nfs4_opendata *opendata;
	int openflags = state->state & (FMODE_READ|FMODE_WRITE);
	int ret;

	if (delegation != NULL && !(delegation->flags & NFS_DELEGATION_NEED_RECLAIM)) {
		ret = _nfs4_do_access(inode, ctx->cred, openflags);
		if (ret < 0)
			return ret;
		memcpy(&state->stateid, &delegation->stateid, sizeof(state->stateid));
		set_bit(NFS_DELEGATED_STATE, &state->flags);
		return 0;
	}
	opendata = nfs4_opendata_alloc(&ctx->path, state->owner, openflags, NULL);
	opendata = nfs4_opendata_alloc(&ctx->path, state->owner, 0, NULL);
	if (opendata == NULL)
		return -ENOMEM;
	ret = nfs4_open_recover(opendata, state);