Thanks, Trond! I applied this patch on 4.19rc4 and ran my test, and this seemed to have solved the problem! On Fri, Sep 28, 2018 at 1:03 PM Trond Myklebust <trondmy@xxxxxxxxx> wrote: > > 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@xxxxxxxxx> > Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> > --- > fs/nfs/nfs4proc.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index 4da59bd53f98..db84b4adbc49 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -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); > -- > 2.17.1 >