aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2011-12-09 19:05:58 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-12-09 19:05:58 -0500
commit652f89f64fabcdae9143ee2b4253cfa838fb0279 (patch)
tree3ab618ec5a8f74c86d610e95ed04afa7b3b0b849 /fs/nfs/nfs4proc.c
parent4b44b40e04a758e2242ff4a3f7c15982801ec8bc (diff)
NFSv4: Do not accept delegated opens when a delegation recall is in effect
...and report the servers that try to return a delegation when the client is using the CLAIM_DELEG_CUR open mode. That behaviour is explicitly forbidden in RFC3530. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index be2bbac13817..d9f4d78c3413 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -39,6 +39,8 @@
39#include <linux/delay.h> 39#include <linux/delay.h>
40#include <linux/errno.h> 40#include <linux/errno.h>
41#include <linux/string.h> 41#include <linux/string.h>
42#include <linux/ratelimit.h>
43#include <linux/printk.h>
42#include <linux/slab.h> 44#include <linux/slab.h>
43#include <linux/sunrpc/clnt.h> 45#include <linux/sunrpc/clnt.h>
44#include <linux/sunrpc/gss_api.h> 46#include <linux/sunrpc/gss_api.h>
@@ -894,6 +896,8 @@ out:
894 896
895static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode) 897static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode)
896{ 898{
899 if (delegation == NULL)
900 return 0;
897 if ((delegation->type & fmode) != fmode) 901 if ((delegation->type & fmode) != fmode)
898 return 0; 902 return 0;
899 if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags)) 903 if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags))
@@ -1036,8 +1040,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
1036 } 1040 }
1037 rcu_read_lock(); 1041 rcu_read_lock();
1038 delegation = rcu_dereference(nfsi->delegation); 1042 delegation = rcu_dereference(nfsi->delegation);
1039 if (delegation == NULL || 1043 if (!can_open_delegated(delegation, fmode)) {
1040 !can_open_delegated(delegation, fmode)) {
1041 rcu_read_unlock(); 1044 rcu_read_unlock();
1042 break; 1045 break;
1043 } 1046 }
@@ -1091,7 +1094,12 @@ static struct nfs4_state *nfs4_opendata_to_nfs4_state(struct nfs4_opendata *data
1091 if (delegation) 1094 if (delegation)
1092 delegation_flags = delegation->flags; 1095 delegation_flags = delegation->flags;
1093 rcu_read_unlock(); 1096 rcu_read_unlock();
1094 if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0) 1097 if (data->o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) {
1098 pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
1099 "returning a delegation for "
1100 "OPEN(CLAIM_DELEGATE_CUR)\n",
1101 NFS_CLIENT(inode)->cl_server);
1102 } else if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
1095 nfs_inode_set_delegation(state->inode, 1103 nfs_inode_set_delegation(state->inode,
1096 data->owner->so_cred, 1104 data->owner->so_cred,
1097 &data->o_res); 1105 &data->o_res);
@@ -1423,11 +1431,9 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1423 goto out_no_action; 1431 goto out_no_action;
1424 rcu_read_lock(); 1432 rcu_read_lock();
1425 delegation = rcu_dereference(NFS_I(data->state->inode)->delegation); 1433 delegation = rcu_dereference(NFS_I(data->state->inode)->delegation);
1426 if (delegation != NULL && 1434 if (data->o_arg.claim != NFS4_OPEN_CLAIM_DELEGATE_CUR &&
1427 test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0) { 1435 can_open_delegated(delegation, data->o_arg.fmode))
1428 rcu_read_unlock(); 1436 goto unlock_no_action;
1429 goto out_no_action;
1430 }
1431 rcu_read_unlock(); 1437 rcu_read_unlock();
1432 } 1438 }
1433 /* Update sequence id. */ 1439 /* Update sequence id. */
@@ -1444,6 +1450,8 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
1444 return; 1450 return;
1445 rpc_call_start(task); 1451 rpc_call_start(task);
1446 return; 1452 return;
1453unlock_no_action:
1454 rcu_read_unlock();
1447out_no_action: 1455out_no_action:
1448 task->tk_action = NULL; 1456 task->tk_action = NULL;
1449 1457