aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-23 14:52:44 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-23 14:52:44 -0400
commitbdeca1b76cd56cd10a029f0ad2fd9ab6dd7e313d (patch)
tree3fcbc68bfb122aaf959e8c53e4d5fe0ec752369d /fs/nfs
parentcd4c9be2c61d4d974d348743fddb8183b8185abc (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.c14
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);