NFSv4: Fix races between open and dentry revalidation
We want to make sure that we revalidate the dentry if and only if we've done an OPEN by filename. In order to avoid races with remote changes to the directory on the server, we want to save the verifier before calling OPEN. The exception is if the server returned a delegation with our OPEN, as we then know that the filename can't have changed on the server. Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Reviewed-by: Benjamin Coddington <bcodding@gmail.com> Tested-by: Benjamin Coddington <bcodding@gmail.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
This commit is contained in:
parent
a1147b8281
commit
cf5b4059ba
|
@ -87,7 +87,6 @@ nfs4_file_open(struct inode *inode, struct file *filp)
|
|||
if (inode != d_inode(dentry))
|
||||
goto out_drop;
|
||||
|
||||
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
||||
nfs_file_set_open_context(filp, ctx);
|
||||
nfs_fscache_open_file(inode, filp);
|
||||
err = 0;
|
||||
|
|
|
@ -2974,10 +2974,13 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
|
|||
struct dentry *dentry;
|
||||
struct nfs4_state *state;
|
||||
fmode_t acc_mode = _nfs4_ctx_to_accessmode(ctx);
|
||||
struct inode *dir = d_inode(opendata->dir);
|
||||
unsigned long dir_verifier;
|
||||
unsigned int seq;
|
||||
int ret;
|
||||
|
||||
seq = raw_seqcount_begin(&sp->so_reclaim_seqcount);
|
||||
dir_verifier = nfs_save_change_attribute(dir);
|
||||
|
||||
ret = _nfs4_proc_open(opendata, ctx);
|
||||
if (ret != 0)
|
||||
|
@ -3005,8 +3008,19 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata,
|
|||
dput(ctx->dentry);
|
||||
ctx->dentry = dentry = alias;
|
||||
}
|
||||
nfs_set_verifier(dentry,
|
||||
nfs_save_change_attribute(d_inode(opendata->dir)));
|
||||
}
|
||||
|
||||
switch(opendata->o_arg.claim) {
|
||||
default:
|
||||
break;
|
||||
case NFS4_OPEN_CLAIM_NULL:
|
||||
case NFS4_OPEN_CLAIM_DELEGATE_CUR:
|
||||
case NFS4_OPEN_CLAIM_DELEGATE_PREV:
|
||||
if (!opendata->rpc_done)
|
||||
break;
|
||||
if (opendata->o_res.delegation_type != 0)
|
||||
dir_verifier = nfs_save_change_attribute(dir);
|
||||
nfs_set_verifier(dentry, dir_verifier);
|
||||
}
|
||||
|
||||
/* Parse layoutget results before we check for access */
|
||||
|
|
Loading…
Reference in New Issue