diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-04-23 14:52:44 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-04-23 14:52:44 -0400 |
commit | bdeca1b76cd56cd10a029f0ad2fd9ab6dd7e313d (patch) | |
tree | 3fcbc68bfb122aaf959e8c53e4d5fe0ec752369d /fs/nfs | |
parent | cd4c9be2c61d4d974d348743fddb8183b8185abc (diff) |
NFSv4: Don't recheck permissions on open in case of recovery cached open
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>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ea50807b65d9..e18b3b46c001 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -769,6 +769,7 @@ struct nfs4_opendata { | |||
769 | struct iattr attrs; | 769 | struct iattr attrs; |
770 | unsigned long timestamp; | 770 | unsigned long timestamp; |
771 | unsigned int rpc_done : 1; | 771 | unsigned int rpc_done : 1; |
772 | unsigned int is_recover : 1; | ||
772 | int rpc_status; | 773 | int rpc_status; |
773 | int cancelled; | 774 | int cancelled; |
774 | }; | 775 | }; |
@@ -1101,9 +1102,11 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) | |||
1101 | /* Save the delegation */ | 1102 | /* Save the delegation */ |
1102 | nfs4_stateid_copy(&stateid, &delegation->stateid); | 1103 | nfs4_stateid_copy(&stateid, &delegation->stateid); |
1103 | rcu_read_unlock(); | 1104 | rcu_read_unlock(); |
1104 | ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); | 1105 | if (!opendata->is_recover) { |
1105 | if (ret != 0) | 1106 | ret = nfs_may_open(state->inode, state->owner->so_cred, open_mode); |
1106 | goto out; | 1107 | if (ret != 0) |
1108 | goto out; | ||
1109 | } | ||
1107 | ret = -EAGAIN; | 1110 | ret = -EAGAIN; |
1108 | 1111 | ||
1109 | /* Try to update the stateid using the delegation */ | 1112 | /* Try to update the stateid using the delegation */ |
@@ -1670,8 +1673,11 @@ static int nfs4_run_open_task(struct nfs4_opendata *data, int isrecover) | |||
1670 | data->rpc_done = 0; | 1673 | data->rpc_done = 0; |
1671 | data->rpc_status = 0; | 1674 | data->rpc_status = 0; |
1672 | data->cancelled = 0; | 1675 | data->cancelled = 0; |
1673 | if (isrecover) | 1676 | data->is_recover = 0; |
1677 | if (isrecover) { | ||
1674 | nfs4_set_sequence_privileged(&o_arg->seq_args); | 1678 | nfs4_set_sequence_privileged(&o_arg->seq_args); |
1679 | data->is_recover = 1; | ||
1680 | } | ||
1675 | task = rpc_run_task(&task_setup_data); | 1681 | task = rpc_run_task(&task_setup_data); |
1676 | if (IS_ERR(task)) | 1682 | if (IS_ERR(task)) |
1677 | return PTR_ERR(task); | 1683 | return PTR_ERR(task); |