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: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
Trond Myklebust 2007-07-08 21:04:15 -04:00
parent 6ee4126890
commit 1ac7e2fd35

View File

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