|
@@ -1682,11 +1682,29 @@ nfs4_opendata_get_inode(struct nfs4_opendata *data)
|
|
}
|
|
}
|
|
|
|
|
|
static struct nfs4_state *
|
|
static struct nfs4_state *
|
|
-_nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
|
|
|
|
|
|
+nfs4_opendata_find_nfs4_state(struct nfs4_opendata *data)
|
|
{
|
|
{
|
|
|
|
+ struct nfs4_state *state;
|
|
struct inode *inode;
|
|
struct inode *inode;
|
|
- struct nfs4_state *state = NULL;
|
|
|
|
- int ret;
|
|
|
|
|
|
+
|
|
|
|
+ inode = nfs4_opendata_get_inode(data);
|
|
|
|
+ if (IS_ERR(inode))
|
|
|
|
+ return ERR_CAST(inode);
|
|
|
|
+ if (data->state != NULL && data->state->inode == inode) {
|
|
|
|
+ state = data->state;
|
|
|
|
+ atomic_inc(&state->count);
|
|
|
|
+ } else
|
|
|
|
+ state = nfs4_get_open_state(inode, data->owner);
|
|
|
|
+ iput(inode);
|
|
|
|
+ if (state == NULL)
|
|
|
|
+ state = ERR_PTR(-ENOMEM);
|
|
|
|
+ return state;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static struct nfs4_state *
|
|
|
|
+_nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
|
|
|
|
+{
|
|
|
|
+ struct nfs4_state *state;
|
|
|
|
|
|
if (!data->rpc_done) {
|
|
if (!data->rpc_done) {
|
|
state = nfs4_try_open_cached(data);
|
|
state = nfs4_try_open_cached(data);
|
|
@@ -1694,26 +1712,17 @@ _nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data)
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
- inode = nfs4_opendata_get_inode(data);
|
|
|
|
- ret = PTR_ERR(inode);
|
|
|
|
- if (IS_ERR(inode))
|
|
|
|
- goto err;
|
|
|
|
- ret = -ENOMEM;
|
|
|
|
- state = nfs4_get_open_state(inode, data->owner);
|
|
|
|
- if (state == NULL)
|
|
|
|
- goto err_put_inode;
|
|
|
|
|
|
+ state = nfs4_opendata_find_nfs4_state(data);
|
|
|
|
+ if (IS_ERR(state))
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
if (data->o_res.delegation_type != 0)
|
|
if (data->o_res.delegation_type != 0)
|
|
nfs4_opendata_check_deleg(data, state);
|
|
nfs4_opendata_check_deleg(data, state);
|
|
update_open_stateid(state, &data->o_res.stateid, NULL,
|
|
update_open_stateid(state, &data->o_res.stateid, NULL,
|
|
data->o_arg.fmode);
|
|
data->o_arg.fmode);
|
|
- iput(inode);
|
|
|
|
out:
|
|
out:
|
|
nfs_release_seqid(data->o_arg.seqid);
|
|
nfs_release_seqid(data->o_arg.seqid);
|
|
return state;
|
|
return state;
|
|
-err_put_inode:
|
|
|
|
- iput(inode);
|
|
|
|
-err:
|
|
|
|
- return ERR_PTR(ret);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static struct nfs4_state *
|
|
static struct nfs4_state *
|