Commit a12802ca authored by Trond Myklebust's avatar Trond Myklebust

NFS: Be strict about dentry revalidation when doing exclusive create

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent b050aa79
...@@ -668,6 +668,19 @@ static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigne ...@@ -668,6 +668,19 @@ static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigne
return nd->flags & mask; return nd->flags & mask;
} }
/*
* Use intent information to check whether or not we're going to do
* an O_EXCL create using this path component.
*/
static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
{
if (NFS_PROTO(dir)->version == 2)
return 0;
if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
return 0;
return (nd->intent.open.flags & O_EXCL) != 0;
}
/* /*
* Inode and filehandle revalidation for lookups. * Inode and filehandle revalidation for lookups.
* *
...@@ -754,7 +767,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd) ...@@ -754,7 +767,7 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
} }
/* Force a full look up iff the parent directory has changed */ /* Force a full look up iff the parent directory has changed */
if (nfs_check_verifier(dir, dentry)) { if (!nfs_is_exclusive_create(dir, nd) && nfs_check_verifier(dir, dentry)) {
if (nfs_lookup_verify_inode(inode, nd)) if (nfs_lookup_verify_inode(inode, nd))
goto out_zap_parent; goto out_zap_parent;
goto out_valid; goto out_valid;
...@@ -848,20 +861,6 @@ struct dentry_operations nfs_dentry_operations = { ...@@ -848,20 +861,6 @@ struct dentry_operations nfs_dentry_operations = {
.d_iput = nfs_dentry_iput, .d_iput = nfs_dentry_iput,
}; };
/*
* Use intent information to check whether or not we're going to do
* an O_EXCL create using this path component.
*/
static inline
int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd)
{
if (NFS_PROTO(dir)->version == 2)
return 0;
if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0)
return 0;
return (nd->intent.open.flags & O_EXCL) != 0;
}
static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd)
{ {
struct dentry *res; struct dentry *res;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment