diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-02 23:13:04 (GMT) |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-09 21:20:16 (GMT) |
commit | a12802cab8520f86c9a80bbf87d10ee6171687d1 (patch) | |
tree | 95e65c0541f0488b9fa6d31441cd584b2fbaf480 | |
parent | b050aa791fad6b060d6ff59305f01289e18b058c (diff) | |
download | linux-a12802cab8520f86c9a80bbf87d10ee6171687d1.tar.xz |
NFS: Be strict about dentry revalidation when doing exclusive create
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/dir.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 393c481..c2207e3 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -669,6 +669,19 @@ static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigne } /* + * 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. * * We force revalidation in the cases where the VFS sets LOOKUP_REVAL, @@ -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 */ - 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)) goto out_zap_parent; goto out_valid; @@ -848,20 +861,6 @@ struct dentry_operations nfs_dentry_operations = { .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) { struct dentry *res; |