@@ -769,6 +769,7 @@ struct nfs4_opendata {
struct iattr attrs;
unsigned long timestamp;
unsigned int rpc_done : 1;
+ unsigned int is_recover : 1;
int rpc_status;
int cancelled;
};
@@ -1101,9 +1102,11 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
/* Save the delegation */
nfs4_stateid_copy(&stateid, &delegation->stateid);
rcu_read_unlock();
- ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
- if (ret != 0)
- goto out;
+ if (!opendata->is_recover) {
+ ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode);
+ if (ret != 0)
+ goto out;
+ }
ret = -EAGAIN;
/* Try to update the stateid using the delegation */
@@ -1670,8 +1673,11 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover)
data->rpc_done = 0;
data->rpc_status = 0;
data->cancelled = 0;
- if (isrecover)
+ data->is_recover = 0;
+ if (isrecover) {
nfs4_set_sequence_privileged(&o_arg->seq_args);
+ data->is_recover = 1;
+ }
task = rpc_run_task(&task_setup_data);
if (IS_ERR(task))
return PTR_ERR(task);
If we already checked the user access permissions on the original open, then don't bother checking again on recovery. Doing so can cause a deadlock with NFSv4.1, since the may_open() operation is not privileged. Furthermore, we can't report an access permission failure here anyway. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com> --- fs/nfs/nfs4proc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)