|
@@ -1349,12 +1349,20 @@ static bool nfs4_mode_match_open_stateid(struct nfs4_state *state,
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode)
|
|
|
+static int can_open_cached(struct nfs4_state *state, fmode_t mode,
|
|
|
+ int open_mode, enum open_claim_type4 claim)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
|
|
|
if (open_mode & (O_EXCL|O_TRUNC))
|
|
|
goto out;
|
|
|
+ switch (claim) {
|
|
|
+ case NFS4_OPEN_CLAIM_NULL:
|
|
|
+ case NFS4_OPEN_CLAIM_FH:
|
|
|
+ goto out;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
switch (mode & (FMODE_READ|FMODE_WRITE)) {
|
|
|
case FMODE_READ:
|
|
|
ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0
|
|
@@ -1747,7 +1755,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
|
|
|
|
|
|
for (;;) {
|
|
|
spin_lock(&state->owner->so_lock);
|
|
|
- if (can_open_cached(state, fmode, open_mode)) {
|
|
|
+ if (can_open_cached(state, fmode, open_mode, claim)) {
|
|
|
update_open_stateflags(state, fmode);
|
|
|
spin_unlock(&state->owner->so_lock);
|
|
|
goto out_return_state;
|
|
@@ -2294,7 +2302,8 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
|
|
|
if (data->state != NULL) {
|
|
|
struct nfs_delegation *delegation;
|
|
|
|
|
|
- if (can_open_cached(data->state, data->o_arg.fmode, data->o_arg.open_flags))
|
|
|
+ if (can_open_cached(data->state, data->o_arg.fmode,
|
|
|
+ data->o_arg.open_flags, claim))
|
|
|
goto out_no_action;
|
|
|
rcu_read_lock();
|
|
|
delegation = rcu_dereference(NFS_I(data->state->inode)->delegation);
|