diff options
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r-- | fs/9p/vfs_inode.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 9e3ea6ce695..e3c03db3c78 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -825,6 +825,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
825 | struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | 825 | struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, |
826 | struct nameidata *nameidata) | 826 | struct nameidata *nameidata) |
827 | { | 827 | { |
828 | struct dentry *res; | ||
828 | struct super_block *sb; | 829 | struct super_block *sb; |
829 | struct v9fs_session_info *v9ses; | 830 | struct v9fs_session_info *v9ses; |
830 | struct p9_fid *dfid, *fid; | 831 | struct p9_fid *dfid, *fid; |
@@ -856,22 +857,35 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
856 | 857 | ||
857 | return ERR_PTR(result); | 858 | return ERR_PTR(result); |
858 | } | 859 | } |
859 | 860 | /* | |
860 | inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); | 861 | * Make sure we don't use a wrong inode due to parallel |
862 | * unlink. For cached mode create calls request for new | ||
863 | * inode. But with cache disabled, lookup should do this. | ||
864 | */ | ||
865 | if (v9ses->cache) | ||
866 | inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); | ||
867 | else | ||
868 | inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); | ||
861 | if (IS_ERR(inode)) { | 869 | if (IS_ERR(inode)) { |
862 | result = PTR_ERR(inode); | 870 | result = PTR_ERR(inode); |
863 | inode = NULL; | 871 | inode = NULL; |
864 | goto error; | 872 | goto error; |
865 | } | 873 | } |
866 | |||
867 | result = v9fs_fid_add(dentry, fid); | 874 | result = v9fs_fid_add(dentry, fid); |
868 | if (result < 0) | 875 | if (result < 0) |
869 | goto error_iput; | 876 | goto error_iput; |
870 | |||
871 | inst_out: | 877 | inst_out: |
872 | d_add(dentry, inode); | 878 | /* |
873 | return NULL; | 879 | * If we had a rename on the server and a parallel lookup |
874 | 880 | * for the new name, then make sure we instantiate with | |
881 | * the new name. ie look up for a/b, while on server somebody | ||
882 | * moved b under k and client parallely did a lookup for | ||
883 | * k/b. | ||
884 | */ | ||
885 | res = d_materialise_unique(dentry, inode); | ||
886 | if (!IS_ERR(res)) | ||
887 | return res; | ||
888 | result = PTR_ERR(res); | ||
875 | error_iput: | 889 | error_iput: |
876 | iput(inode); | 890 | iput(inode); |
877 | error: | 891 | error: |