Skip to content

Commit be189f7

Browse files
author
Trond Myklebust
committed
NFS: Fix dentry revalidation on NFSv4 lookup
We need to ensure that inode and dentry revalidation occurs correctly on reopen of a file that is already open. Currently, we can end up not revalidating either in the case of NFSv4.0, due to the 'cached open' path. Let's fix that by ensuring that we only do cached open for the special cases of open recovery and delegation return. Reported-by: Stan Hu <stanhu@gmail.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent 571ed1f commit be189f7

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

fs/nfs/nfs4proc.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1349,12 +1349,20 @@ static bool nfs4_mode_match_open_stateid(struct nfs4_state *state,
13491349
return false;
13501350
}
13511351

1352-
static int can_open_cached(struct nfs4_state *state, fmode_t mode, int open_mode)
1352+
static int can_open_cached(struct nfs4_state *state, fmode_t mode,
1353+
int open_mode, enum open_claim_type4 claim)
13531354
{
13541355
int ret = 0;
13551356

13561357
if (open_mode & (O_EXCL|O_TRUNC))
13571358
goto out;
1359+
switch (claim) {
1360+
case NFS4_OPEN_CLAIM_NULL:
1361+
case NFS4_OPEN_CLAIM_FH:
1362+
goto out;
1363+
default:
1364+
break;
1365+
}
13581366
switch (mode & (FMODE_READ|FMODE_WRITE)) {
13591367
case FMODE_READ:
13601368
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)
17471755

17481756
for (;;) {
17491757
spin_lock(&state->owner->so_lock);
1750-
if (can_open_cached(state, fmode, open_mode)) {
1758+
if (can_open_cached(state, fmode, open_mode, claim)) {
17511759
update_open_stateflags(state, fmode);
17521760
spin_unlock(&state->owner->so_lock);
17531761
goto out_return_state;
@@ -2294,7 +2302,8 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
22942302
if (data->state != NULL) {
22952303
struct nfs_delegation *delegation;
22962304

2297-
if (can_open_cached(data->state, data->o_arg.fmode, data->o_arg.open_flags))
2305+
if (can_open_cached(data->state, data->o_arg.fmode,
2306+
data->o_arg.open_flags, claim))
22982307
goto out_no_action;
22992308
rcu_read_lock();
23002309
delegation = rcu_dereference(NFS_I(data->state->inode)->delegation);

0 commit comments

Comments
 (0)