diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-02 19:13:04 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-10-09 17:20:16 -0400 |
commit | a12802cab8520f86c9a80bbf87d10ee6171687d1 (patch) | |
tree | 95e65c0541f0488b9fa6d31441cd584b2fbaf480 /fs | |
parent | b050aa791fad6b060d6ff59305f01289e18b058c (diff) |
NFS: Be strict about dentry revalidation when doing exclusive create
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-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 393c4813691..c2207e3f263 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 | |||
669 | } | 669 | } |
670 | 670 | ||
671 | /* | 671 | /* |
672 | * Use intent information to check whether or not we're going to do | ||
673 | * an O_EXCL create using this path component. | ||
674 | */ | ||
675 | static int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) | ||
676 | { | ||
677 | if (NFS_PROTO(dir)->version == 2) | ||
678 | return 0; | ||
679 | if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0) | ||
680 | return 0; | ||
681 | return (nd->intent.open.flags & O_EXCL) != 0; | ||
682 | } | ||
683 | |||
684 | /* | ||
672 | * Inode and filehandle revalidation for lookups. | 685 | * Inode and filehandle revalidation for lookups. |
673 | * | 686 | * |
674 | * We force revalidation in the cases where the VFS sets LOOKUP_REVAL, | 687 | * 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) | |||
754 | } | 767 | } |
755 | 768 | ||
756 | /* Force a full look up iff the parent directory has changed */ | 769 | /* Force a full look up iff the parent directory has changed */ |
757 | if (nfs_check_verifier(dir, dentry)) { | 770 | if (!nfs_is_exclusive_create(dir, nd) && nfs_check_verifier(dir, dentry)) { |
758 | if (nfs_lookup_verify_inode(inode, nd)) | 771 | if (nfs_lookup_verify_inode(inode, nd)) |
759 | goto out_zap_parent; | 772 | goto out_zap_parent; |
760 | goto out_valid; | 773 | goto out_valid; |
@@ -848,20 +861,6 @@ struct dentry_operations nfs_dentry_operations = { | |||
848 | .d_iput = nfs_dentry_iput, | 861 | .d_iput = nfs_dentry_iput, |
849 | }; | 862 | }; |
850 | 863 | ||
851 | /* | ||
852 | * Use intent information to check whether or not we're going to do | ||
853 | * an O_EXCL create using this path component. | ||
854 | */ | ||
855 | static inline | ||
856 | int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) | ||
857 | { | ||
858 | if (NFS_PROTO(dir)->version == 2) | ||
859 | return 0; | ||
860 | if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0) | ||
861 | return 0; | ||
862 | return (nd->intent.open.flags & O_EXCL) != 0; | ||
863 | } | ||
864 | |||
865 | static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) | 864 | static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) |
866 | { | 865 | { |
867 | struct dentry *res; | 866 | struct dentry *res; |